Commit f7ea900a authored by Dave Cheney's avatar Dave Cheney

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
parent 6e3f3af4
......@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment