wercker status GoDoc

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 (


// 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 (

// Defined only once within a package.
func TestAll(t *testing.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