Skip to content

Commit ba8ff87

Browse files
nemithmpvl
authored andcommitted
testing: add argument to list tests, benchmarks, and examples
Some large testing/build systems require some form of test discovery before running tests. This usually allows for analytics, history, and stats on a per tests basis. Typically these systems are meant used in multi-language environments and the original source code is not known or available. This adds a -test.list option which takes a regular expression as an argument. Any tests, benchmarks, or examples that match that regular expression will be printed, one per line, to stdout and then the program will exit. Since subtests are named/discovered at run time this will only show top-level tests names and is a known limitation. Fixes #17209 Change-Id: I7e607f5f4f084d623a1cae88a1f70e7d92b7f13e Reviewed-on: https://go-review.googlesource.com/41195 Reviewed-by: Marcel van Lohuizen <[email protected]> Run-TryBot: Marcel van Lohuizen <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 6e2c4bc commit ba8ff87

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

src/cmd/go/internal/test/test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ const testFlag2 = `
184184
benchmarks should be executed. The default is the current value
185185
of GOMAXPROCS.
186186
187+
-list regexp
188+
List tests, benchmarks, or examples matching the regular expression.
189+
No tests, benchmarks or examples will be run. This will only
190+
list top-level tests. No subtest or subbenchmarks will be shown.
191+
187192
-parallel n
188193
Allow parallel execution of test functions that call t.Parallel.
189194
The value of this flag is the maximum number of tests to run
@@ -400,6 +405,7 @@ var (
400405
testTimeout string // -timeout flag
401406
testArgs []string
402407
testBench bool
408+
testList bool
403409
testStreamOutput bool // show output as it is generated
404410
testShowPass bool // show passing output
405411

@@ -447,7 +453,7 @@ func runTest(cmd *base.Command, args []string) {
447453
// show passing test output (after buffering) with -v flag.
448454
// must buffer because tests are running in parallel, and
449455
// otherwise the output will get mixed.
450-
testShowPass = testV
456+
testShowPass = testV || testList
451457

452458
// stream test output (no buffering) when no package has
453459
// been given on the command line (implicit current directory)

src/cmd/go/internal/test/testflag.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ var testFlagDefn = []*cmdflag.Defn{
4242
{Name: "coverprofile", PassToTest: true},
4343
{Name: "cpu", PassToTest: true},
4444
{Name: "cpuprofile", PassToTest: true},
45+
{Name: "list", PassToTest: true},
4546
{Name: "memprofile", PassToTest: true},
4647
{Name: "memprofilerate", PassToTest: true},
4748
{Name: "blockprofile", PassToTest: true},
@@ -145,6 +146,8 @@ func testFlags(args []string) (packageNames, passToTest []string) {
145146
case "bench":
146147
// record that we saw the flag; don't care about the value
147148
testBench = true
149+
case "list":
150+
testList = true
148151
case "timeout":
149152
testTimeout = value
150153
case "blockprofile", "cpuprofile", "memprofile", "mutexprofile":

src/testing/testing.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ var (
252252
chatty = flag.Bool("test.v", false, "verbose: print additional output")
253253
count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
254254
coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
255+
matchList = flag.String("test.list", "", "list tests, examples, and benchmarch maching `regexp` then exit")
255256
match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
256257
memProfile = flag.String("test.memprofile", "", "write a memory profile to `file`")
257258
memProfileRate = flag.Int("test.memprofilerate", 0, "set memory profiling `rate` (see runtime.MemProfileRate)")
@@ -907,6 +908,11 @@ func (m *M) Run() int {
907908
flag.Parse()
908909
}
909910

911+
if len(*matchList) != 0 {
912+
listTests(m.deps.MatchString, m.tests, m.benchmarks, m.examples)
913+
return 0
914+
}
915+
910916
parseCpuList()
911917

912918
m.before()
@@ -946,6 +952,29 @@ func (t *T) report() {
946952
}
947953
}
948954

955+
func listTests(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
956+
if _, err := matchString(*matchList, "non-empty"); err != nil {
957+
fmt.Fprintf(os.Stderr, "testing: invalid regexp in -test.list (%q): %s\n", *matchList, err)
958+
os.Exit(1)
959+
}
960+
961+
for _, test := range tests {
962+
if ok, _ := matchString(*matchList, test.Name); ok {
963+
fmt.Println(test.Name)
964+
}
965+
}
966+
for _, bench := range benchmarks {
967+
if ok, _ := matchString(*matchList, bench.Name); ok {
968+
fmt.Println(bench.Name)
969+
}
970+
}
971+
for _, example := range examples {
972+
if ok, _ := matchString(*matchList, example.Name); ok && example.Output != "" {
973+
fmt.Println(example.Name)
974+
}
975+
}
976+
}
977+
949978
// An internal function but exported because it is cross-package; part of the implementation
950979
// of the "go test" command.
951980
func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {

0 commit comments

Comments
 (0)