I'm using the testify package a lot when writing tests using Go. I find they make my test code much clearer, more concise and easier to read.

However, when you use it in your tests, you need to be very careful when choosing between assert and require. They look the same but are different in the way they behave. Which one you choose depends on the behaviour you are looking for.

If you use assert, your test will look like:

package yours

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestSomething(t *testing.T) {
    assert.Equal(t, 123, 123, "they should be equal")
    assert.NotEqual(t, 123, 456, "they should not be equal")
    assert.Nil(t, object)
    if assert.NotNil(t, object) {
        assert.Equal(t, "Something", object.Value)
    }
}

With assert, you will get a log entry for each assertation.

Changing it to use require looks similar until you run the actual tests:

package yours

import (
    "testing"

    "github.com/stretchr/testify/require"
)

func TestSomething(t *testing.T) {
    require.Equal(t, 123, 123, "they should be equal")
    require.NotEqual(t, 123, 456, "they should not be equal")
    require.Nil(t, object)
    if require.NotNil(t, object) {
        require.Equal(t, "Something", object.Value)
    }
}

With require, as soon as you run the tests, the first requirement which fails interrupts and fails the complete test. So, if the first requirement fails, the rest of the test will be skipped.

An alternative to testify is the is package from Mat Ryer. The biggest difference is that this library only supports the same flow as the assert package. The advantage is that the output is much more concise and the API is a lot more straightforward. I guess I'll have to give it a go when writing tests again…

Related Posts

  • Using environment variables in Go tests
  • Testing exceptions in pytest
  • Parsing a key pair from a PEM file in Go
  • Pointer vs value receivers
  • Handling Unix timestamps in JSON