]> Cypherpunks repositories - gostls13.git/commitdiff
testing: add Skip/Skipf
authorDave Cheney <dave@cheney.net>
Tue, 22 Jan 2013 23:22:33 +0000 (10:22 +1100)
committerDave Cheney <dave@cheney.net>
Tue, 22 Jan 2013 23:22:33 +0000 (10:22 +1100)
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

src/pkg/testing/testing.go

index 1768e205f0ded41ee19513471f8becafd695204b..c1917f8fe03c492250a1b507d48643b8e3fcb519 100644 (file)
 // [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 {