I always loved the fact that Go ships with a build in test
runner that allows you to go test
your application without any additional
tools required. Although the simplicity of Go tests is high, the API doesn't
allow you to create any suites with tear ups and tear downs. Stuff I usually
use for integration tests. So I started using Gocheck
today and I must say that I am in love! It has one of the best Go API's I've
seen so far (ok, it shares the first place with the Gorilla Web Toolkit).
Here are some examples of the features I enjoy!
Test suites
Bundle your tests and add state to them.
// Setup the test suite
var _ = Suite(&ApiIntegrationTestSuite{
ProcessFilename: "httpcallback.io",
})
// The state for the test suite
type ApiIntegrationTestSuite struct {
ProcessFilename string
process *os.Process
}
Test suites with set up and tear down
// Runs before the test suite starts
func (s *ApiIntegrationTestSuite) SetUpSuite(c *C) {
var procAttr os.ProcAttr
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
procArgs := []string{"-config config.toml -port 8000"}
process, err := os.StartProcess(s.ProcessFilename, procArgs, &procAttr)
if err != nil {
c.Errorf("Unable to start %s: %s", s.ProcessFilename, err.Error())
c.Fail()
}
// Allow process to warm up
time.Sleep(2 * time.Second)
s.process = process
c.Logf("Started %s, pid %v", s.ProcessFilename, process.Pid)
}
// Runs after the test suite finished, even when failed
func (s *ApiIntegrationTestSuite) TearDownSuite(c *C) {
if err := s.process.Kill(); err != nil {
c.Logf("Unable to kill %s: %s", s.ProcessFilename, err.Error())
}
}
Tests come with set up and tear down
// Runs before the test starts
func (s *ApiIntegrationTestSuite) SetUpTest(c *C) {
s.ResetDataContext()
}
// Runs after the test finished, even when failed
func (s *ApiIntegrationTestSuite) TearDownTest(c *C) {
s.Flush()
}
Assert API
No more if err != nil
's in your Go test code, but a decent
assert API.
func (s *ApiIntegrationTestSuite) TestPing(c *C) {
response, err := http.Get("http://api.localhost:8000/ping")
c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK)
doc, err := GetBodyAsDocument(c, response)
c.Assert(err, IsNil)
c.Assert(doc["message"], Equals, "pong")
}
Skipping tests
var aws = flag.Bool("aws", false, "Include aws tests")
func (s *ApiIntegrationTestSuite) TestAwsProvisioning(c *C) {
if *aws {
c.Skip("-aws not provided")
}
}
Support benchmark tests
func (s *ApiIntegrationTestSuite) BenchmarkPing(c *C) {
// c.N contains the number of times to repeat
// the benchmark test. This number is dynamicly
// set by the Go test runner.
for i := 0; i < c.N; i++ {
response, err := http.Get("http://api.localhost:8000/ping")
if err != nil {
c.Fatalf("Error while getting response: %v", err.Error())
} else {
response.Body.Close()
}
}
}
Learn more
Read the gocheck introduction page to learn more about the framework and its benefits.