@@ -37,17 +37,16 @@ type Runner struct {
3737 FailFast bool // Stop on first test failure.
3838 SkipTests []string // Test names to exclude.
3939 SelectTests []string // Test names to include.
40- SelectedTestPackages []string // Explicitly selected packages to run.
4140 CollectRawOutput bool // Set to true to collect test output for later inspection.
4241 OmitOutputsOnSuccess bool // Set to true to omit test outputs on success.
4342 rawOutputs map [string ]* bytes.Buffer
4443}
4544
46- // RunTests executes the tests for each provided package and aggregates all results.
45+ // RunTestPackages executes the tests for each provided package and aggregates all results.
4746// It returns all test results and any error encountered during testing.
48- func (r * Runner ) RunTests ( ) (* reports.TestReport , error ) {
47+ func (r * Runner ) RunTestPackages ( packages [] string ) (* reports.TestReport , error ) {
4948 var jsonFilePaths []string
50- for _ , p := range r . SelectedTestPackages {
49+ for _ , p := range packages {
5150 for i := 0 ; i < r .RunCount ; i ++ {
5251 if r .CollectRawOutput { // Collect raw output for debugging
5352 if r .rawOutputs == nil {
@@ -59,7 +58,7 @@ func (r *Runner) RunTests() (*reports.TestReport, error) {
5958 separator := strings .Repeat ("-" , 80 )
6059 r .rawOutputs [p ].WriteString (fmt .Sprintf ("Run %d\n %s\n " , i + 1 , separator ))
6160 }
62- jsonFilePath , passed , err := r .runTests (p )
61+ jsonFilePath , passed , err := r .runTestPackage (p )
6362 if err != nil {
6463 return nil , fmt .Errorf ("failed to run tests in package %s: %w" , p , err )
6564 }
@@ -84,6 +83,38 @@ func (r *Runner) RunTests() (*reports.TestReport, error) {
8483 }, nil
8584}
8685
86+ // RunTestCmd runs an arbitrary command testCmd (like ["go", "run", "my_test.go", ...])
87+ // that produces the same JSON lines that 'go test -json' would produce on stdout.
88+ // It captures those lines in a temp file, then parses them for pass/fail/panic/race data.
89+ func (r * Runner ) RunTestCmd (testCmd []string ) (* reports.TestReport , error ) {
90+ var jsonFilePaths []string
91+
92+ // Run the command r.RunCount times
93+ for i := 0 ; i < r .RunCount ; i ++ {
94+ jsonFilePath , passed , err := r .runCmd (testCmd , i )
95+ if err != nil {
96+ return nil , fmt .Errorf ("failed to run test command: %w" , err )
97+ }
98+ jsonFilePaths = append (jsonFilePaths , jsonFilePath )
99+ if ! passed && r .FailFast {
100+ break
101+ }
102+ }
103+
104+ results , err := r .parseTestResults (jsonFilePaths )
105+ if err != nil {
106+ return nil , fmt .Errorf ("failed to parse test results: %w" , err )
107+ }
108+
109+ // Build a TestReport, same shape as RunTests()
110+ return & reports.TestReport {
111+ GoProject : r .prettyProjectPath ,
112+ TestRunCount : r .RunCount ,
113+ RaceDetection : r .UseRace ,
114+ Results : results ,
115+ }, nil
116+ }
117+
87118// RawOutputs retrieves the raw output from the test runs, if CollectRawOutput enabled.
88119// packageName : raw output
89120func (r * Runner ) RawOutputs () map [string ]* bytes.Buffer {
@@ -94,8 +125,8 @@ type exitCoder interface {
94125 ExitCode () int
95126}
96127
97- // runTests runs the tests for a given package and returns the path to the output file.
98- func (r * Runner ) runTests (packageName string ) (string , bool , error ) {
128+ // runTestPackage runs the tests for a given package and returns the path to the output file.
129+ func (r * Runner ) runTestPackage (packageName string ) (string , bool , error ) {
99130 args := []string {"test" , packageName , "-json" , "-count=1" }
100131 if r .UseRace {
101132 args = append (args , "-race" )
@@ -160,38 +191,6 @@ func (r *Runner) runTests(packageName string) (string, bool, error) {
160191 return tmpFile .Name (), true , nil // Test succeeded
161192}
162193
163- // RunTestsByCmd runs an arbitrary command testCmd (like ["go", "run", "my_test.go", ...])
164- // that produces the same JSON lines that 'go test -json' would produce on stdout.
165- // It captures those lines in a temp file, then parses them for pass/fail/panic/race data.
166- func (r * Runner ) RunTestsByCmd (testCmd []string ) (* reports.TestReport , error ) {
167- var jsonFilePaths []string
168-
169- // Run the command r.RunCount times
170- for i := 0 ; i < r .RunCount ; i ++ {
171- jsonFilePath , passed , err := r .runCmd (testCmd , i )
172- if err != nil {
173- return nil , fmt .Errorf ("failed to run test command: %w" , err )
174- }
175- jsonFilePaths = append (jsonFilePaths , jsonFilePath )
176- if ! passed && r .FailFast {
177- break
178- }
179- }
180-
181- results , err := r .parseTestResults (jsonFilePaths )
182- if err != nil {
183- return nil , fmt .Errorf ("failed to parse test results: %w" , err )
184- }
185-
186- // Build a TestReport, same shape as RunTests()
187- return & reports.TestReport {
188- GoProject : r .prettyProjectPath ,
189- TestRunCount : r .RunCount ,
190- RaceDetection : r .UseRace ,
191- Results : results ,
192- }, nil
193- }
194-
195194// runCmd is a helper that runs the user-supplied command once, captures its JSON output,
196195// and returns (tempFilePath, passed, error).
197196func (r * Runner ) runCmd (testCmd []string , runIndex int ) (string , bool , error ) {
@@ -222,10 +221,8 @@ func (r *Runner) runCmd(testCmd []string, runIndex int) (string, bool, error) {
222221 } else {
223222 cmd .Stdout = tmpFile
224223 }
225- // Handle stderr however you like; here we just dump it to console
226224 cmd .Stderr = os .Stderr
227225
228- // Run it
229226 err = cmd .Run ()
230227
231228 // Determine pass/fail from exit code
0 commit comments