Go Lesson 47 – Testing | Dataplexa

Testing in Go

Testing is a core part of professional Go development. Go includes a powerful built-in testing framework that makes writing, running, and maintaining tests simple and fast.

In this lesson, you will learn how to write unit tests, run test suites, test real logic, and follow Go testing best practices.


Why Testing Is Important

Testing ensures that your code works as expected, prevents regressions, and improves code reliability.

Go developers rely heavily on automated tests, especially for APIs, libraries, and concurrent systems.


The Go Testing Package

Go provides the testing package as part of the standard library.

Tests are written in files that end with _test.go.


Creating Your First Test

Let’s start with a simple function.

package mathutils

func Add(a int, b int) int {
    return a + b
}

Now create a test file called mathutils_test.go.

package mathutils

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5

    if result != expected {
        t.Errorf("Expected %d, got %d", expected, result)
    }
}

Running Tests

Run all tests in a directory using:

go test

For detailed output:

go test -v

Table-Driven Tests

Table-driven tests are a common Go pattern that allow you to test multiple cases cleanly.

func TestAdd_TableDriven(t *testing.T) {
    tests := []struct {
        a, b int
        expected int
    }{
        {1, 2, 3},
        {5, 5, 10},
        {-1, 1, 0},
    }

    for _, test := range tests {
        result := Add(test.a, test.b)
        if result != test.expected {
            t.Errorf("Add(%d, %d) = %d; want %d",
                test.a, test.b, result, test.expected)
        }
    }
}

Failing a Test

Use t.Fail() or t.Fatalf() to stop execution.

if result != expected {
    t.Fatalf("Critical failure: expected %d, got %d", expected, result)
}

Testing Errors

Functions that return errors should be tested carefully.

func Divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}
func TestDivide_Error(t *testing.T) {
    _, err := Divide(10, 0)
    if err == nil {
        t.Error("Expected error, got nil")
    }
}

Skipping Tests

You can skip tests when needed.

func TestSkip(t *testing.T) {
    t.Skip("Skipping this test temporarily")
}

Benchmarking Code

Go supports performance benchmarking.

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(10, 20)
    }
}

Run benchmarks with:

go test -bench=.

Code Coverage

Go can generate test coverage reports.

go test -cover

To generate an HTML report:

go test -coverprofile=coverage.out
go tool cover -html=coverage.out

Best Practices for Testing

  • Write small, focused tests
  • Use table-driven tests
  • Test edge cases
  • Avoid hard-coded dependencies
  • Keep tests fast

Practice Exercises

Exercise 1

Write a test for a function that checks if a number is even.

Exercise 2

Create a benchmark for a string concatenation function.


Key Takeaways

  • Go includes built-in testing tools
  • Tests live in _test.go files
  • Table-driven tests are idiomatic
  • Benchmarks and coverage are first-class features

What’s Next?

In the next lesson, you will build a real-world project using goroutines to apply concurrency concepts practically.