From: Dave Cheney Date: Tue, 22 Jan 2013 23:22:33 +0000 (+1100) Subject: testing: add Skip/Skipf X-Git-Tag: go1.1rc2~1314 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f7ea900a7bfe88cdfc42448d10a4f9bfa83cc36f;p=gostls13.git testing: add Skip/Skipf This proposal adds two methods to *testing.T, Skip(string) and Skipf(format, args...). The intent is to replace the existing log and return idiom which currently has 97 cases in the standard library. A simple example of Skip would be: func TestSomethingLong(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") // not reached } ... time consuming work } Additionally tests can be skipped anywhere a *testing.T is present. An example adapted from the go.crypto/ssh/test package would be: // setup performs some before test action and returns a func() // which should be defered by the caller for cleanup. func setup(t *testing.T) func() { ... cmd := exec.Command("sshd", "-f", configfile, "-i") if err := cmd.Run(); err != nil { t.Skipf("could not execute mock ssh server: %v", err) } ... return func() { // stop subprocess and cleanup } } func TestDialMockServer(t *testing.T) { cleanup := setup(t) defer cleanup() ... } In verbose mode tests that are skipped are now reported as a SKIP, rather than PASS. Link to discussion: https://groups.google.com/d/topic/golang-nuts/BqorNARzt4U/discussion R=adg, rsc, r, n13m3y3r CC=golang-dev, minux.ma https://golang.org/cl/6501094 --- diff --git a/src/pkg/testing/testing.go b/src/pkg/testing/testing.go index 1768e205f0..c1917f8fe0 100644 --- a/src/pkg/testing/testing.go +++ b/src/pkg/testing/testing.go @@ -10,6 +10,14 @@ // [a-z]) and serves to identify the test routine. // These TestXxx routines should be declared within the package they are testing. // +// Tests may be skipped if not applicable like this: +// func TestTimeConsuming(t *testing.T) { +// if testing.Short() { +// t.Skip("skipping test in short mode.") +// } +// ... +// } +// // Functions of the form // func BenchmarkXxx(*testing.B) // are considered benchmarks, and are executed by the "go test" command when @@ -185,6 +193,7 @@ type T struct { common name string // Name of test. startParallel chan bool // Parallel tests will wait on this. + skipped bool // Test has been skipped. } // Fail marks the function as having failed but continues execution. @@ -194,7 +203,7 @@ func (c *common) Fail() { c.failed = true } -// Failed returns whether the function has failed. +// Failed reports whether the function has failed. func (c *common) Failed() bool { c.mu.RLock() defer c.mu.RUnlock() @@ -328,10 +337,46 @@ func (t *T) report() { if t.Failed() { fmt.Printf(format, "FAIL", t.name, tstr, t.output) } else if *chatty { - fmt.Printf(format, "PASS", t.name, tstr, t.output) + if t.Skipped() { + fmt.Printf(format, "SKIP", t.name, tstr, t.output) + } else { + fmt.Printf(format, "PASS", t.name, tstr, t.output) + } } } +// Skip is equivalent to Log() followed by SkipNow(). +func (t *T) Skip(args ...interface{}) { + t.log(fmt.Sprintln(args...)) + t.SkipNow() +} + +// Skipf is equivalent to Logf() followed by SkipNow(). +func (t *T) Skipf(format string, args ...interface{}) { + t.log(fmt.Sprintf(format, args...)) + t.SkipNow() +} + +// SkipNow marks the function as having been skipped and stops its execution. +// Execution will continue at the next test or benchmark. See also, t.FailNow. +func (t *T) SkipNow() { + t.skip() + runtime.Goexit() +} + +func (t *T) skip() { + t.mu.Lock() + defer t.mu.Unlock() + t.skipped = true +} + +// Skipped reports whether the function was skipped. +func (t *T) Skipped() bool { + t.mu.RLock() + defer t.mu.RUnlock() + return t.skipped +} + func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) { ok = true if len(tests) == 0 && !haveExamples {