Beginner's Guide to Logging in Tests in Golang

⏰ 2 Minutes 📅 Dec 29, 2023

Welcome Gophers! In this tutorial, we’re going to be looking at how you can add log messages to your Go unit tests.

This is critical as your suite of tests around your applications grows over time. You want to be able to quickly identify why a test has failed so that you can quickly start digging into how to fix it.

Video Tutorial

Log and Logf

Let’s start with Log and Logf methods. These are helpful logging methods that hang off the *testing.T struct available to us within our test functions:

t.Run("subtest 1", func(t *testing.T) {
    t.Log("running subtest 1")

    t.Logf("format string: %s", "hello world")

These helpful functions are subtly different from your standard fmt package print statements in the sense that they only log out if your test has failed, or if you are running your tests in verbose mode.

Error and Errorf

We’ve also got Error and Errorf available to us. These are effectively Log or Logf statements with the added functionality of calling t.Fail() as well. This will mean your particular test gets marked as failed.

t.Run("subtest 2", func(t *testing.T) {
    t.Error("Some error running subtest 2")
    // t.Fail() <- this gets called by t.Error!

Fatal and Fatalf

Finally, let’s look at Fatal and Fatalf - these are another step up from Error and Errorf as they call FailNow which means that your current tests stop immediately and no sub-tests are run:

t.Run("failing tests", func(t *testing.T) {
    result := map[string]string{
        "test": "results",
    t.Fatalf("Some massive error has occurred: %+v", result)

    t.Run("tests that wont run", func(t *testing.T) {
        t.Log("an example of a test")

Let’s take a look at this now - as you can see from the output, the tests that won't run sub-test is never executed:

go test -v
=== RUN   TestSomething
=== RUN   TestSomething/subtest_1
    main_test.go:7: running subtest 1
    main_test.go:9: format string: hello world
=== RUN   TestSomething/failing_tests
    main_test.go:21: Some massive error has occurred: map[test:results]
--- FAIL: TestSomething (0.00s)
    --- PASS: TestSomething/subtest_1 (0.00s)
    --- FAIL: TestSomething/failing_tests (0.00s)
exit status 1
FAIL     0.196s