Re-run SetUpTest and TearDownTest while callibrating timing.
diff --git a/benchmark.go b/benchmark.go
index 58fc41a..dcd426f 100644
--- a/benchmark.go
+++ b/benchmark.go
@@ -6,8 +6,6 @@
import (
"fmt"
- "reflect"
- "runtime"
"time"
)
@@ -136,41 +134,3 @@
}
return 10 * base
}
-
-// benchmarkN runs a single benchmark for the specified number of iterations.
-func benchmarkN(c *C, n int) {
- // Try to get a comparable environment for each run
- // by clearing garbage from previous runs.
- runtime.GC()
- c.N = n
- c.ResetTimer()
- c.StartTimer()
- c.method.Call([]reflect.Value{reflect.ValueOf(c)})
- c.StopTimer()
-}
-
-// benchmark runs the benchmark function. It gradually increases the number
-// of benchmark iterations until the benchmark runs for a second in order
-// to get a reasonable measurement.
-func benchmark(c *C) {
- // Run the benchmark for a single iteration in case it's expensive.
- n := 1
- benchmarkN(c, n)
- // Run the benchmark for at least the specified amount of time.
- for c.status == succeededSt && c.duration < c.benchTime && n < 1e9 {
- last := n
- // Predict iterations/sec.
- if c.nsPerOp() == 0 {
- n = 1e9
- } else {
- n = int(c.benchTime.Nanoseconds() / c.nsPerOp())
- }
- // Run more iterations than we think we'll need for a second (1.5x).
- // Don't grow too fast in case we had timing errors previously.
- // Be sure to run at least one more than last time.
- n = max(min(n+n/2, 100*last), last+1)
- // Round up to something easy to read.
- n = roundUp(n)
- benchmarkN(c, n)
- }
-}
diff --git a/benchmark_test.go b/benchmark_test.go
index 6d2b009..7e96ae7 100644
--- a/benchmark_test.go
+++ b/benchmark_test.go
@@ -36,8 +36,6 @@
c.Assert(output.value, Matches, expected)
}
-// Quite unfortunate that these two tests alone account for most of the
-
func (s *BenchmarkS) TestBenchmark(c *C) {
helper := FixtureHelper{sleep: 100000}
output := String{}
@@ -48,6 +46,14 @@
Filter: "Benchmark1",
}
Run(&helper, &runConf)
+ c.Check(helper.calls[0], Equals, "SetUpSuite")
+ c.Check(helper.calls[1], Equals, "SetUpTest")
+ c.Check(helper.calls[2], Equals, "Benchmark1")
+ c.Check(helper.calls[3], Equals, "TearDownTest")
+ c.Check(helper.calls[4], Equals, "SetUpTest")
+ c.Check(helper.calls[5], Equals, "Benchmark1")
+ c.Check(helper.calls[6], Equals, "TearDownTest")
+ // ... and more.
expected := "PASS: gocheck_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n"
c.Assert(output.value, Matches, expected)
diff --git a/fixture_test.go b/fixture_test.go
index cd66118..63f392e 100644
--- a/fixture_test.go
+++ b/fixture_test.go
@@ -31,7 +31,7 @@
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 8)
+ c.Check(len(helper.calls), Equals, 8)
}
// -----------------------------------------------------------------------
@@ -49,7 +49,7 @@
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 8)
+ c.Check(len(helper.calls), Equals, 8)
expected := "^\n-+\n" +
"PANIC: gocheck_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" +
@@ -72,7 +72,7 @@
c.Check(helper.calls[1], Equals, "SetUpTest")
c.Check(helper.calls[2], Equals, "TearDownTest")
c.Check(helper.calls[3], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 4)
+ c.Check(len(helper.calls), Equals, 4)
expected := "^\n-+\n" +
"PANIC: gocheck_test\\.go:[0-9]+: " +
@@ -102,7 +102,7 @@
c.Check(helper.calls[2], Equals, "Test1")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 5)
+ c.Check(len(helper.calls), Equals, 5)
expected := "^\n-+\n" +
"PANIC: gocheck_test\\.go:[0-9]+: " +
@@ -129,7 +129,7 @@
Run(&helper, &RunConf{Output: &output})
c.Check(helper.calls[0], Equals, "SetUpSuite")
c.Check(helper.calls[1], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 2)
+ c.Check(len(helper.calls), Equals, 2)
expected := "^\n-+\n" +
"PANIC: gocheck_test\\.go:[0-9]+: " +
@@ -157,7 +157,7 @@
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 8)
+ c.Check(len(helper.calls), Equals, 8)
expected := "^\n-+\n" +
"PANIC: gocheck_test\\.go:[0-9]+: " +
@@ -187,7 +187,7 @@
c.Check(helper.calls[4], Equals, "Test2")
c.Check(helper.calls[5], Equals, "TearDownTest")
c.Check(helper.calls[6], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 7)
+ c.Check(len(helper.calls), Equals, 7)
expected := "^\n-+\n" +
"PANIC: fixture_test\\.go:[0-9]+: " +
@@ -202,7 +202,7 @@
helper := WrongSetUpTestArgHelper{}
output := String{}
Run(&helper, &RunConf{Output: &output})
- c.Check(helper.n, Equals, 0)
+ c.Check(len(helper.calls), Equals, 0)
expected :=
"^\n-+\n" +
@@ -218,7 +218,7 @@
helper := WrongSetUpSuiteArgHelper{}
output := String{}
Run(&helper, &RunConf{Output: &output})
- c.Check(helper.n, Equals, 0)
+ c.Check(len(helper.calls), Equals, 0)
expected :=
"^\n-+\n" +
@@ -244,7 +244,7 @@
c.Check(helper.calls[4], Equals, "Test2")
c.Check(helper.calls[5], Equals, "TearDownTest")
c.Check(helper.calls[6], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 7)
+ c.Check(len(helper.calls), Equals, 7)
expected := "^\n-+\n" +
"PANIC: fixture_test\\.go:[0-9]+: " +
@@ -259,7 +259,7 @@
helper := WrongSetUpTestArgCountHelper{}
output := String{}
Run(&helper, &RunConf{Output: &output})
- c.Check(helper.n, Equals, 0)
+ c.Check(len(helper.calls), Equals, 0)
expected :=
"^\n-+\n" +
@@ -275,7 +275,7 @@
helper := WrongSetUpSuiteArgCountHelper{}
output := String{}
Run(&helper, &RunConf{Output: &output})
- c.Check(helper.n, Equals, 0)
+ c.Check(len(helper.calls), Equals, 0)
expected :=
"^\n-+\n" +
@@ -460,7 +460,7 @@
c.Assert(output.value, Equals, "")
c.Assert(helper.calls[0], Equals, "SetUpSuite")
c.Assert(helper.calls[1], Equals, "TearDownSuite")
- c.Assert(helper.n, Equals, 2)
+ c.Assert(len(helper.calls), Equals, 2)
c.Assert(result.Skipped, Equals, 2)
}
@@ -474,6 +474,6 @@
c.Assert(helper.calls[3], Equals, "Test2")
c.Assert(helper.calls[4], Equals, "TearDownTest")
c.Assert(helper.calls[5], Equals, "TearDownSuite")
- c.Assert(helper.n, Equals, 6)
+ c.Assert(len(helper.calls), Equals, 6)
c.Assert(result.Skipped, Equals, 1)
}
diff --git a/gocheck.go b/gocheck.go
index a037c95..50af42e 100644
--- a/gocheck.go
+++ b/gocheck.go
@@ -691,12 +691,14 @@
// in case the fixture method panics. This makes it easier to track the
// fixture panic together with other call panics within forkTest().
func (runner *suiteRunner) runFixtureWithPanic(method *methodType, logb *logger, skipped *bool) *C {
- if *skipped {
+ if skipped != nil && *skipped {
return nil
}
c := runner.runFixture(method, logb)
if c != nil && c.status != succeededSt {
- *skipped = c.status == skippedSt
+ if skipped != nil {
+ *skipped = c.status == skippedSt
+ }
panic(&fixturePanic{c.status, method})
}
return c
@@ -713,27 +715,53 @@
return runner.forkCall(method, testKd, nil, func(c *C) {
var skipped bool
defer runner.runFixtureWithPanic(runner.tearDownTest, nil, &skipped)
- runner.runFixtureWithPanic(runner.setUpTest, c.logb, &skipped)
- mt := c.method.Type()
- if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
- // Rather than a plain panic, provide a more helpful message when
- // the argument type is incorrect.
- c.status = panickedSt
- c.logArgPanic(c.method, "*gocheck.C")
- return
- }
- if strings.HasPrefix(c.method.Info.Name, "Test") {
+ defer c.StopTimer()
+ benchN := 1
+ for {
+ runner.runFixtureWithPanic(runner.setUpTest, c.logb, &skipped)
+ mt := c.method.Type()
+ if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
+ // Rather than a plain panic, provide a more helpful message when
+ // the argument type is incorrect.
+ c.status = panickedSt
+ c.logArgPanic(c.method, "*gocheck.C")
+ return
+ }
+ if strings.HasPrefix(c.method.Info.Name, "Test") {
+ c.ResetTimer()
+ c.StartTimer()
+ c.method.Call([]reflect.Value{reflect.ValueOf(c)})
+ return
+ }
+ if !strings.HasPrefix(c.method.Info.Name, "Benchmark") {
+ panic("unexpected method prefix: " + c.method.Info.Name)
+ }
+
+ runtime.GC()
+ c.N = benchN
c.ResetTimer()
c.StartTimer()
- defer c.StopTimer()
c.method.Call([]reflect.Value{reflect.ValueOf(c)})
- return
+ c.StopTimer()
+ if c.status != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
+ return
+ }
+ perOpN := int(1e9)
+ if c.nsPerOp() != 0 {
+ perOpN = int(c.benchTime.Nanoseconds() / c.nsPerOp())
+ }
+
+ // Logic taken from the stock testing package:
+ // - Run more iterations than we think we'll need for a second (1.5x).
+ // - Don't grow too fast in case we had timing errors previously.
+ // - Be sure to run at least one more than last time.
+ benchN = max(min(perOpN+perOpN/2, 100*benchN), benchN+1)
+ benchN = roundUp(benchN)
+
+ skipped = true // Don't run the deferred one if this panics.
+ runner.runFixtureWithPanic(runner.tearDownTest, nil, nil)
+ skipped = false
}
- if strings.HasPrefix(c.method.Info.Name, "Benchmark") {
- benchmark(c)
- return
- }
- panic("unexpected method prefix: " + c.method.Info.Name)
})
}
diff --git a/gocheck_test.go b/gocheck_test.go
index aad261a..7575df4 100644
--- a/gocheck_test.go
+++ b/gocheck_test.go
@@ -94,8 +94,7 @@
// Helper suite for testing ordering and behavior of fixture.
type FixtureHelper struct {
- calls [64]string
- n int
+ calls []string
panicOn string
skip bool
skipOnN int
@@ -105,16 +104,14 @@
}
func (s *FixtureHelper) trace(name string, c *gocheck.C) {
- n := s.n
- s.calls[n] = name
- s.n += 1
+ s.calls = append(s.calls, name)
if name == s.panicOn {
panic(name)
}
if s.sleep > 0 && s.sleepOn == name {
time.Sleep(s.sleep)
}
- if s.skip && s.skipOnN == n {
+ if s.skip && s.skipOnN == len(s.calls)-1 {
c.Skip("skipOnN == n")
}
}
diff --git a/run_test.go b/run_test.go
index 3700ac7..6793e4c 100644
--- a/run_test.go
+++ b/run_test.go
@@ -206,7 +206,7 @@
c.Check(helper.calls[2], Equals, "Test1")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 5)
+ c.Check(len(helper.calls), Equals, 5)
}
func (s *RunS) TestFilterTestNameWithAll(c *C) {
@@ -222,7 +222,7 @@
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 8)
+ c.Check(len(helper.calls), Equals, 8)
}
func (s *RunS) TestFilterSuiteName(c *C) {
@@ -238,7 +238,7 @@
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 8)
+ c.Check(len(helper.calls), Equals, 8)
}
func (s *RunS) TestFilterSuiteNameAndTestName(c *C) {
@@ -251,7 +251,7 @@
c.Check(helper.calls[2], Equals, "Test2")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "TearDownSuite")
- c.Check(helper.n, Equals, 5)
+ c.Check(len(helper.calls), Equals, 5)
}
func (s *RunS) TestFilterAllOut(c *C) {
@@ -259,7 +259,7 @@
output := String{}
runConf := RunConf{Output: &output, Filter: "NotFound"}
Run(&helper, &runConf)
- c.Check(helper.n, Equals, 0)
+ c.Check(len(helper.calls), Equals, 0)
}
func (s *RunS) TestRequirePartialMatch(c *C) {
@@ -267,7 +267,7 @@
output := String{}
runConf := RunConf{Output: &output, Filter: "est"}
Run(&helper, &runConf)
- c.Check(helper.n, Equals, 8)
+ c.Check(len(helper.calls), Equals, 8)
}
func (s *RunS) TestFilterError(c *C) {
@@ -277,7 +277,7 @@
result := Run(&helper, &runConf)
c.Check(result.String(), Equals,
"ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`")
- c.Check(helper.n, Equals, 0)
+ c.Check(len(helper.calls), Equals, 0)
}
// -----------------------------------------------------------------------