Sling Academy
Home/Golang/Testing Functions in Go: Writing Unit Tests and Benchmarks

Testing Functions in Go: Writing Unit Tests and Benchmarks

Last updated: November 26, 2024

Introduction

Unit testing is a crucial aspect of developing reliable software. In Go, the process of testing is efficiently managed through Go's built-in testing package. Additionally, Go provides functionality for writing benchmarks, allowing developers to measure the performance of their functions. In this article, we'll navigate through the basics of writing unit tests and benchmarks in Go, elucidating with various examples.

Setting Up Your Environment

Before writing tests in Go, ensure that your environment is correctly set up:

go mod init example.com/m

Writing Unit Tests in Go

Unit tests in Go are structured within functions that start with Test in their name and accept a single argument of type *testing.T. These tests are typically created inside files named something_test.go.

An Example in Practice

Consider a simple function that adds two numbers:

package mathop

// Add sums two integers.
func Add(a, b int) int {
    return a + b
}

To test this function, create a new file mathop_test.go:

package mathop

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5
    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}

To run your tests, use the command:

go test

Writing Benchmarks in Go

Benchmarks help measure the performance characteristics of programs. These are similar to tests but are prefixed with Benchmark instead. Benchmarks take a parameter of type *testing.B and use a loop structure to repeatedly execute code for performance measurement.

Benchmark Example

To write a benchmark for the Add function, add the following code in mathop_test.go:

package mathop

import "testing"

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

To run benchmarks, use the command:

go test -bench=.

Writing Table-driven Tests

Table-driven tests are a convenient way to test different inputs on a function while minimizing code duplication. Here’s how to implement table-driven tests for the Add function:

func TestAddTableDriven(t *testing.T) {
    var tests = []struct {
        a, b int
        expected int
    }{
        {1, 1, 2},
        {0, 0, 0},
        {-1, 1, 0},
        {2, 2, 4},
    }

    for _, tt := range tests {
        testname := fmt.Sprintf("%d,%d", tt.a, tt.b)
        t.Run(testname, func(t *testing.T) {
            ans := Add(tt.a, tt.b)
            if ans != tt.expected {
                t.Errorf("got %d, want %d", ans, tt.expected)
            }
        })
    }
}

Conclusion

Testing and benchmarking are foundational practices in well-maintained codebases. Using Go's built-in tools, such as the testing package, enhances code reliability and performance optimization. Through structured unit tests and benchmarks, you can confidently manage your Go applications both in terms of correctness and efficiency.

Next Article: Best Practices for Organizing Functions in Large Go Projects

Previous Article: Memoization with Functions for Optimized Recursion in Go

Series: Functions in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant