GSpec is an expressive, reliable, concurrent and extensible Go test framework that makes it productive to organize and verify the mind model of software.
- Expressive: a complete runnable specification can be organized via both BDD and table driven styles.
- Reliable: the implementation has minimal footprint and is tested with 100% coverage.
- Concurrent: test cases can be executed concurrently or sequentially.
- Extensible: customizable BDD cue words, expectations and test reporters.
- Compatible: “go test” is sufficient but not mandatory to run GSpec tests.
Quick start
Get GSpec
go get -u -f h12.io/gspec
go test h12.io/gspec/...
Write tests with GSpec
According to the convention of Go, write GSpec tests in file xxx_test.go to test code in xxx.go.
import (
"fmt"
"h12.io/gspec"
)
// Only one suite.Add is needed for each xxx_test.go file.
var _ = gspec.Add(func(s gspec.S) {
// BDD cue word is customizible.
describe, given, when, it := s.Alias("describe"), s.Alias("given"), s.Alias("when"), s.Alias("it")
// expectation cue word is customizible too.
expect := gspec.Alias(s.FailNow)
// A BDD example.
describe("an integer i", func() {
// setup
i := 2
defer func() {
// teardown (if any)
}()
given("another integer j", func() {
j := 3
when("j is added to i", func() {
i += j
it("should become the sum of original i and j", func() {
expect(i).Equal(5) // a passing case
})
})
when("j is minused from i", func() {
i -= j
it("should become the difference of j minus i", func() {
expect(i).Equal(4) // a failing case
})
})
when("j is multiplied to i", nil) // a pending case
})
})
// A table-driven example.
testcase := s.Alias("testcase")
describe("integer summation", func() {
for _, c := range []struct{ i, j, sum int }{
{1, 2, 3}, // a passing case
{1, 1, 0}, // a failing case
} {
testcase(fmt.Sprintf(`%d + %d = %d`, c.i, c.j, c.sum), func() {
expect(c.i + c.j).Equal(c.sum)
})
}
})
})
Write the following go test function for only once in any test file within the package (e.g. all_test.go).
import (
"testing"
"h12.io/gspec"
)
// Defined only once within a package.
func TestAll(t *testing.T) {
gspec.Test(t)
}
Run tests with “go test”
Run all the tests concurrently (sequencially by default) and display errors.
go test -concurrent
Run all the tests and view the complete specification.
go test -v
Run only a failing test case (even it is an entry in the driven table):
go test -focus 1/1