Closure driven tests: an alternative style to table driven tests in go

Jack Lindamood
Sep 17 · 2 min read

Table driven tests are a popular model for testing in Go and a clear improvement to traditional testing of one function per case. However, there’s an alternative style that can often be clearer than table driven tests that relies on function closures.

I’ll reference the example code on Dave Cheney’s post Prefer table driven tests for my examples.

The original way

The code we want to test is a function that splits strings.

The original way to test code like this was to create different test functions for each case. Here are two tests: one for a wrong separator and another for no separator.

Table driven test example

As a table driven test, we create a struct object to hold the common parts of the test case. This has many advantages: the biggest of which is that we can add more test cases easily.

The common parts of traditional table driven tests are

  • a structure to represent the test case
  • a loop around an array or map of the structure
  • testing logic inside the main body of the loop

Closure driven test example

We can make a closure of our main testing body and rewrite the above code.

The common parts of closure driven tests are

  • Defined test case parameters as function parameters rather than struct parameters
  • A function that returns func (t *testing.T), often inline with the test
  • Inline executions of cases rather than a loop

The most important part is that we can use the return value of splitEquals directly as the second parameter to t.Run.

Comparing closure driven tests to table driven tests

A few advantages stick out for closure driven tests.

  • TestSplit2 has fewer lines of code, but is still easy to read
  • It’s obvious how to add other splitNotEquals or splitContains closures in a way that doesn’t require another for loop
  • Traditional Go tests name the thing they are testing TestSplit and the test input simple, but give no name to the logic used for testing. Closure driven tests add the name splitEquals to your code.
  • We avoid the unnatural compact one linestruct{} style of table driven tests

Which you use is more of a personal choice, but I’ve found closure driven tests easier to extend and develop iteratively and am using them for most my current code.

Jack Lindamood

Written by

Software Engineer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade