@@ -23,21 +23,20 @@ type TestReport struct {
2323
2424// TestResult represents the result of a single test being run through flakeguard.
2525type TestResult struct {
26- TestName string
27- TestPackage string
28- Panicked bool // Indicates a test-level panic
29- Skipped bool // Indicates if the test was skipped
30- PackagePanicked bool // Indicates a package-level panic
31- PassRatio float64 // Pass ratio in decimal format like 0.5
32- Runs int // Count of how many times the test was run
33- Failures int // Count of how many times the test failed
34- Successes int // Count of how many times the test passed
35- Panics int // Count of how many times the test panicked
36- Races int // Count of how many times the test encountered a data race
37- Skips int // Count of how many times the test was skipped
38- Outputs []string `json:"outputs,omitempty"` // Stores outputs for a test
39- Durations []time.Duration // Stores elapsed time for each run of the test
40- PackageOutputs []string `json:"package_outputs,omitempty"` // Stores package-level outputs
26+ TestName string
27+ TestPackage string
28+ PackagePanic bool // Indicates a package-level panic
29+ Panic bool // Indicates a test-level panic
30+ Race bool // Indicates if the test caused a data race
31+ Skipped bool // Indicates if the test was skipped
32+ PassRatio float64 // Pass ratio in decimal format like 0.5
33+ Runs int // Count of how many times the test was run
34+ Failures int // Count of how many times the test failed
35+ Successes int // Count of how many times the test passed
36+ Skips int // Count of how many times the test was skipped
37+ Outputs []string `json:"outputs,omitempty"` // Stores outputs for a test
38+ Durations []time.Duration // Stores elapsed time for each run of the test
39+ PackageOutputs []string `json:"package_outputs,omitempty"` // Stores package-level outputs
4140}
4241
4342// FilterFailedTests returns a slice of TestResult where the pass ratio is below the specified threshold.
@@ -131,8 +130,8 @@ func AggregateTestResults(folderPath string) (*TestReport, error) {
131130 existingResult .PackageOutputs = append (existingResult .PackageOutputs , result .PackageOutputs ... )
132131 existingResult .Successes += result .Successes
133132 existingResult .Failures += result .Failures
134- existingResult .Panics += result .Panics
135- existingResult .Races += result .Races
133+ existingResult .Panic = existingResult . Panic || result .Panic
134+ existingResult .Race = existingResult . Race || result .Race
136135 existingResult .Skips += result .Skips
137136 existingResult .PassRatio = 1.0
138137 if existingResult .Runs > 0 {
@@ -178,9 +177,23 @@ func AggregateTestResults(folderPath string) (*TestReport, error) {
178177}
179178
180179// PrintTests prints tests in a pretty format
181- func PrintTests (w io.Writer , tests []TestResult , maxPassRatio float64 ) (allRuns , passes , fails , panics , skips , races , flakes int ) {
180+ func PrintTests (
181+ w io.Writer ,
182+ tests []TestResult ,
183+ maxPassRatio float64 ,
184+ ) (runs , passes , fails , skips , panickedTests , racedTests , flakyTests int ) {
182185 headers := []string {
183- "**Test Name**" , "**Test Package**" , "**Package Panicked**" , "**Pass Ratio**" , "**Runs**" , "**Successes**" , "**Failures**" , "**Panics**" , "**Races**" , "**Skips**" , "**Avg Duration**" ,
186+ "**Test**" ,
187+ "**Pass Ratio**" ,
188+ "**Runs**" ,
189+ "**Test Panicked?**" ,
190+ "**Test Race?**" ,
191+ "**Successes**" ,
192+ "**Failures**" ,
193+ "**Skips**" ,
194+ "**Package**" ,
195+ "**Package Panicked?**" ,
196+ "**Avg Duration**" ,
184197 }
185198
186199 // Build test rows and summary data
@@ -189,40 +202,46 @@ func PrintTests(w io.Writer, tests []TestResult, maxPassRatio float64) (allRuns,
189202 if test .PassRatio < maxPassRatio {
190203 rows = append (rows , []string {
191204 test .TestName ,
192- test .TestPackage ,
193- fmt .Sprintf ("%t" , test .PackagePanicked ),
194205 fmt .Sprintf ("%.2f%%" , test .PassRatio * 100 ),
195206 fmt .Sprintf ("%d" , test .Runs ),
207+ fmt .Sprintf ("%t" , test .Panic ),
208+ fmt .Sprintf ("%t" , test .Race ),
196209 fmt .Sprintf ("%d" , test .Successes ),
197210 fmt .Sprintf ("%d" , test .Failures ),
198- fmt .Sprintf ("%d" , test .Panics ),
199- fmt .Sprintf ("%d" , test .Races ),
200211 fmt .Sprintf ("%d" , test .Skips ),
212+ test .TestPackage ,
213+ fmt .Sprintf ("%t" , test .PackagePanic ),
201214 avgDuration (test .Durations ).String (),
202215 })
203216 }
204217
205- allRuns += test .Runs
218+ runs += test .Runs
206219 passes += test .Successes
207220 fails += test .Failures
208221 skips += test .Skips
209- races += test .Races
210- panics += test .Panics
211- if test .PassRatio < maxPassRatio {
212- flakes ++
222+ if test .Panic {
223+ panickedTests ++
224+ flakyTests ++
225+ } else if test .Race {
226+ racedTests ++
227+ flakyTests ++
228+ } else if test .PassRatio < maxPassRatio {
229+ flakyTests ++
213230 }
214231 }
215232
216233 // Print out summary data
217234 summaryData := [][]string {
218235 {"**Category**" , "**Total**" },
219- {"**Runs**" , fmt .Sprint (allRuns )},
236+ {"**Tests**" , fmt .Sprint (len (tests ))},
237+ {"**Panicked Tests**" , fmt .Sprint (panickedTests )},
238+ {"**Raced Tests**" , fmt .Sprint (racedTests )},
239+ {"**Flaky Tests**" , fmt .Sprint (flakyTests )},
240+ {"**Pass Ratio**" , fmt .Sprintf ("%.2f%%" , float64 (passes )/ float64 (runs )* 100 )},
241+ {"**Runs**" , fmt .Sprint (runs )},
220242 {"**Passes**" , fmt .Sprint (passes )},
221243 {"**Failures**" , fmt .Sprint (fails )},
222- {"**Panics**" , fmt .Sprint (panics )},
223244 {"**Skips**" , fmt .Sprint (skips )},
224- {"**Races**" , fmt .Sprint (races )},
225- {"**Flaky Tests**" , fmt .Sprint (flakes )},
226245 }
227246 colWidths := make ([]int , len (rows [0 ]))
228247
@@ -276,11 +295,12 @@ func PrintTests(w io.Writer, tests []TestResult, maxPassRatio float64) (allRuns,
276295 fmt .Fprintln (w , "|" + buffer .String ())
277296 }
278297
279- // Print table
280- printRow (headers )
281- printSeparator ()
282- for _ , row := range rows {
283- printRow (row )
298+ if len (rows ) == 0 {
299+ printRow (headers )
300+ printSeparator ()
301+ for _ , row := range rows {
302+ printRow (row )
303+ }
284304 }
285305 return
286306}
@@ -332,7 +352,7 @@ func MarkdownSummary(w io.Writer, testReport *TestReport, maxPassRatio float64)
332352 return
333353 }
334354
335- allRuns , passes , _ , _ , _ , _ , flakes := PrintTests (testsData , tests , maxPassRatio )
355+ allRuns , passes , _ , _ , _ , _ , _ := PrintTests (testsData , tests , maxPassRatio )
336356 if allRuns > 0 {
337357 avgPassRatio = float64 (passes ) / float64 (allRuns )
338358 }
@@ -341,11 +361,7 @@ func MarkdownSummary(w io.Writer, testReport *TestReport, maxPassRatio float64)
341361 } else {
342362 fmt .Fprint (w , "## No Flakes Found :white_check_mark:\n \n " )
343363 }
344- fmt .Fprintf (w , "Ran `%d` tests `%d` times, and found `%d` flaky tests with an overall `%.2f%%` pass ratio\n \n " , len (tests ), testReport .TestRunCount , flakes , avgPassRatio * 100 )
345- if avgPassRatio < maxPassRatio {
346- fmt .Fprint (w , "### Flakes\n \n " )
347- fmt .Fprint (w , testsData .String ())
348- }
364+ fmt .Fprint (w , testsData .String ())
349365}
350366
351367// Helper function to save filtered results and logs to specified paths
@@ -356,7 +372,8 @@ func SaveFilteredResultsAndLogs(outputResultsPath, outputLogsPath string, report
356372 }
357373 jsonFileName := strings .TrimSuffix (outputResultsPath , filepath .Ext (outputResultsPath )) + ".json"
358374 mdFileName := strings .TrimSuffix (outputResultsPath , filepath .Ext (outputResultsPath )) + ".md"
359- if err := saveReportNoLogs (jsonFileName , report ); err != nil {
375+ // no pointer to avoid destroying the original report
376+ if err := saveReportNoLogs (jsonFileName , * report ); err != nil {
360377 return fmt .Errorf ("error writing filtered results to file: %w" , err )
361378 }
362379 summaryFile , err := os .Create (mdFileName )
@@ -374,7 +391,8 @@ func SaveFilteredResultsAndLogs(outputResultsPath, outputLogsPath string, report
374391 if err := os .MkdirAll (filepath .Dir (outputLogsPath ), 0755 ); err != nil { //nolint:gosec
375392 return fmt .Errorf ("error creating output directory: %w" , err )
376393 }
377- if err := saveReport (outputLogsPath , report ); err != nil {
394+ // no pointer to avoid destroying the original report
395+ if err := saveReport (outputLogsPath , * report ); err != nil {
378396 return fmt .Errorf ("error writing filtered logs to file: %w" , err )
379397 }
380398 fmt .Printf ("Test logs saved to %s\n " , outputLogsPath )
@@ -385,7 +403,7 @@ func SaveFilteredResultsAndLogs(outputResultsPath, outputLogsPath string, report
385403// saveReportNoLogs saves the test results to JSON without logs
386404// as outputs can take up a lot of space and are not always needed.
387405// Outputs can be saved separately using saveTestOutputs
388- func saveReportNoLogs (filePath string , report * TestReport ) error {
406+ func saveReportNoLogs (filePath string , report TestReport ) error {
389407 var filteredResults []TestResult
390408 for _ , r := range report .Results {
391409 filteredResult := r
@@ -403,7 +421,7 @@ func saveReportNoLogs(filePath string, report *TestReport) error {
403421}
404422
405423// saveReport saves the test results to JSON
406- func saveReport (filePath string , report * TestReport ) error {
424+ func saveReport (filePath string , report TestReport ) error {
407425 data , err := json .MarshalIndent (report , "" , " " )
408426 if err != nil {
409427 return fmt .Errorf ("error marshaling outputs: %v" , err )
0 commit comments