testeach
provides a simple mechanism for shared test setup/teardown for Go tests.
For each case, all that case's parents are re-run, such that their setup, teardown and assertions automatically apply to the case.
Variable scoping follows natural language rules, avoiding issues common in BDD frameworks with Before() functions.
Cases are registered using callbacks rather than reflection, avoiding the possibility of tests mistakenly being missed due to typos.
See v3/example_test.go for more examples.
package my_test
import (
"testing"
testeach "github.com/devnev/testeach/v3"
)
func TestMyType(t *testing.T) {
// Suite setup goes here (equivalent to SetupSuite/TeardownSuite functions in suite frameworks)
harness := createHarness(t)
// In Go 1.14+, harness may use t.Cleanup, making this defer unnecessary.
defer harness.Destroy()
s := testeach.NewSuite(&t)
s.Case("with state", func() {
// Test setup goes here (equivalent to SetupTest/TeardownTest functions in suite frameworks)
stuff := setupState(t)
defer func() {
teardown(stuff)
}()
// Individual test cases. The names must be static and are used as the sub-test name to `t.Run`.
s.Case("it does the thing", func() {
// assert a thing
})
s.Case("it does something else", func() {
// assert something else
})
s.Case("with a particular setup", func() {
// Can have test calls within callbacks. All setup and teardown is re-run for every sub-test.
s.Case("it does another thing", func() {
// more asserts
})
})
})
}
See v2/example_test.go for more examples.
package my_test
import (
"testing"
. "github.com/devnev/testeach/v2"
)
func TestMyType(t *testing.T) {
// Suite setup goes here (equivalent to SetupSuite/TeardownSuite functions in suite frameworks)
harness := createHarness(t)
// In Go 1.14+, harness may use t.Cleanup, making this defer unnecessary.
defer harness.Destroy()
Case(&t, "with state", func() {
// Test setup goes here (equivalent to SetupTest/TeardownTest functions in suite frameworks)
stuff := setupState(t)
defer func() {
teardown(stuff)
}()
// Individual test cases. The names must be static and are used as the sub-test name to `t.Run`.
Case(&t, "it does the thing", func() {
// assert a thing
})
Case(&t, "it does something else", func() {
// assert something else
})
Case(&t, "with a particular setup", func() {
// Can have test calls within callbacks. All setup and teardown is re-run for every sub-test.
Case(&t, "it does another thing", func() {
// more asserts
})
})
})
}
See example_test.go for more examples.
package my_test
import (
"testing"
. "github.com/devnev/testeach"
)
func TestMyType(t *testing.T) {
// Suite setup goes here (equivalent to SetupSuite/TeardownSuite functions in suite frameworks)
harness := createHarness(t)
// In Go 1.14+, harness may use t.Cleanup, making this defer unnecessary.
defer harness.Destroy()
Start(t, func(t *testing.T) {
// Test setup goes here (equivalent to SetupTest/TeardownTest functions in suite frameworks)
stuff := setupState(t)
defer func() {
teardown(stuff)
}()
// Individual test cases. The names must be static and are used as the sub-test name to `t.Run`.
Case(t, "it does the thing", func() {
// assert a thing
})
Case(t, "it does something else", func() {
// assert something else
})
Case(t, "with a particular setup", func() {
// Can have test calls within callbacks. All setup and teardown is re-run for every sub-test.
Case(t, "it does another thing", func() {
// more asserts
})
})
})
}