So I wrote a custom checker in less than 20 lines of code. Arguably, I could've written a Within() helper function in 3. So you win some, you lose some.

There are ways to write concise tests without pulling in an xUnit assertion frameworks. If you've ever seen Cucumber data tables, you will appreciate table driven tests, a simple way of testing many variations with relatively compact code.

Alternatives

Gocheck isn't the only third-party option out there. Andrea Fazzi's PrettyTest has a colourful test runner, and it is compatible with gocheck assertions.

Go has anonymous functions, so it was only a matter of time before someone built a Jasmine-style BDD library. There are several options, including Mao/Zen, Goblin, GoConvey and Ginkgo/GΩmega. Unfortunately I haven't had a chance to try these yet, so I can't vouch for them.

No doubt there are other tools that have slipped past my radar. Lately I've been reaching for the standard testing package, mostly to avoid yet-another-dependency in reusable libraries. Go 1.2's ability to download test dependencies with go get -t may change that for me.

Mocking

Mocking, stubbing, fakes, test doubles... it can be a bit confusing.

A summer ago, I was learning OpenGL, and wanted a way to stub out the graphics context in tests. I looked at gomock, but I wasn't a huge fan of the code generation required, and I didn't actually need expectations.

So I looked for a light weight alternative. The solution was to use interfaces in the production code, which allowed me to write a test double that satisfied said interface. That worked pretty well, and is the approach I continue to use today.

Then there are specialized "mocking" tools. For testing HTTP client libraries, the standard library ships with httptest. Will Norris explains how it works in Testing in go-github.

Coverage

Test coverage allows you to see which methods and conditional branches your test suite doesn't reach.

Andrew Gerrand and Rob Pike are developing a new coverage tool for Go 1.2. To try it out, you'll need the Go 1.2 release candidate or install Go from source. After you go get it, a lovely report in your browser is as simple as:

Travis CI

Travis CI has been around longer than most, and has some nice features. Though it only integrates with GitHub, Travis will let you know if pull requests are safe to merge. It also allows testing against older versions of Go or Go tip.

AppVeyor

AppVeyor is a CI service for .NET developers. I approached them over Twitter with an interest in testing Go libraries on Windows. They added the option to use a PowerShell script for the build phase, installed Go on their servers, and have since officially announced Go language support.

Here is the source code for a sample application with the necessary build script.

wercker

wercker looks to be the most flexible offering, though I found the whole thing a bit overwhelming. It allows the community to build custom boxes for any language or environment required, and includes support for Go.

Cross-Platform Testing

Before contributing to fsnotify, I wanted a way to test my changes across the adapters for kqueue (BSD), inotify (Linux) and ReadDirectoryChanges (Windows). My development machine is running OS X, which currently uses the kqueue adapter (though support for FSEvents is in the works). How would I test the others?

Vagrant

Vagrant is a tool to script the creation of VirtualBox VMs (as well as VMWare and other providers).

When you run vagrant up with the Vagrantfile I wrote, it will download Linux and BSD boxes if necessary, install the DVCS tools and Go binaries, and configure GOPATH and other environment variables.

The way I have this setup, my src/ folder is shared, so I can continue to use my editor and tools on OS X, while being able to issue commands to Linux and BSD VMs:

vagrant ssh linux -c 'cd nathany/looper; go test ./...'

Each VM has its own bin/ folder so go install won't stomp on the binaries created by your host OS or the other VM.

If you would like to try it out, there are more details in the Vagrant Gopher repository. I welcome contributions, but be warned, you'll be dealing with Bash script embedded in Ruby. Lotsa fun!

Windows

I'm not aware of a way to work with the Windows command line through Vagrant, so I had to set all this up manually.

You can download Windows Virtual Machines from Microsoft for free, but I went with a proper Windows 7 Professional license to avoid the constant "Genuine Windows" nagging.

Using VMWare Fusion, I shared my project folder which contains src, bin, and pkg. It becomes Z:\project on Windows.

Fortunately, this doesn't cause conflicts, because binaries on Windows have an .exe extension and Go puts static libraries under pkg\windows_amd64.

With the Go binaries installed, I can use PowerShell to run my tests.

Autotest

Many people like running tests directly in their editor or IDE. I prefer to have a separate Terminal window for running tests.

This past February I wrote an autotest tool at a hackathon. Looper uses fsnotify to watch your file system. When you hit save it runs the tests for that package (folder).

Looper still has a long ways to go, but even at the start it had some nice features:

Recursive watching, when you add a subfolder it will start watching it.

It has a prompt that uses readline to manage history.

ANSI colours indicate pass/fail.

I'm already thinking about automatically running tests across multiple VMs using Vagrant, and maybe adding one-off commands for shortcuts, like generating a coverage report. My goal isn't to replace Bash though, so there is much to consider.

The Looper README maintains a list of alternative tools for all your autotest and file watching needs.

PASS

Well, I hope you found this article helpful. If it was a FAIL, please let me know how I can improve it.