In the go programing language there is a testing pattern called table tests. I want to quickly go over what is this pattern, why I think it’s great and how we can use it in python.

What are Table tests

In go a simple test would look like this:

func TestAdd(t *testing.T) {
    got := add(5, 6)

    if got != 11 {
        t.Errorf("Expected 11, Got %v", got)
    }
}

A table test of the same kind will look like this:

func TestAdd(t *testing.T) {
    type test struct {
        x         int
        y         int
        expected  int
    }

    cases := []test{
        {5, 6, 11},
    }

    for _, tc := range cases {
        got := add(tc.x, tc.y)

        if got != tc.expected {
            t.Errorf("add(%v, %v) = %v, Expected %v", tc.x, tc.y, got, tc.expected)
        }
    }
}

Thats the gist of it.

Why they are great

To some people, testing is all about testing the edge cases.

A software QA engineer walks into a bar.

  • He orders a beer.
  • Orders 0 beers.
  • Orders 99999999999 beers.
  • Orders a lizard. Orders -1 beers.
  • Orders a ueicbksjdhd.

First real customer walks in and asks where the bathroom is. The bar bursts into flames, killing everyone.

To me the biggest value of a test is not in adding all the edge cases, but in testing the base case. Firstly because there can be a bug there ( you’d be surprised at how often! ), but most importantly because ater the 1st test the other test cases are just a ctr-C crt-V away!

This, to me is where table tests shine! They separate the testing assertions from the test cases definitions. This both makes adding new cases super easy and keeps the assertion logic very clean and easy to understand.

How to do it in python

If you haven’t guessed it by now, the answer to this is to use a python dict instead of the struct.

def test_add():
    cases = [
       {"x": 5, "y": 6, "expected": 11},
    ]

    for tc in cases:
        got = add(tc["x"], tc["y"])

        assert got == tc["expected"], f"{tc['x']} + {tc['y']}"

I’ve seen people suggest using data classes or named tuples, if that makes you happy and write more test, go right ahead. I like the dict approach because it doesn’t introduce any new concepts so it shouldn’t intimidate even the very beginners from writing and reading tests.

Anyway, thats it, nice short post for today.