SoFunction
Updated on 2025-03-05

One article will help you understand unit tests in Go

Basic concepts

As mentioned in the previous section, one of the standards for code completion also includes unit testing, which is also an irregularity in many development processes. Developers who have written unit tests should understand that the core value of unit tests is to prove: why is the code I wrote correct? That is to help you check your code from a logical point of view. But on the other hand, unit testing is also very time-consuming from the perspective of unit testing coverage, almost three times the development time of your code, so in many projects with very fast iteration speeds, almost no one asks for unit testing. But unit testing can really fundamentally improve code quality and reduce the probability of low-level errors.

Example 1: Basic test of rounding function

Prerequisites

Go language has built-in instructions for unit test execution. Since the Go Modules method has not been used yet, we still need to set environment variables to perform the test correctly.

export GO111MODULE=off
go test

Code

Suppose we test the following function

package even

func Even(i int) bool {
    return i % 2 == 0
}

Unit test establishment steps

Create a unit test, including the following steps:

  • Create a file named *_test.go in the same directory
  • Perform go test for testing, and these files will be automatically identified
  • Introducing testing package
  • Each Case is named after func TestXxx(t *)

Writing unit tests

Here we test two scenarios, one is an even number and the other is an odd number to check whether our program returns as expected, and if not, exception information will be thrown.

package even

import "testing"

func TestEven(t *) {
    if !Even(2) {
        ("2 should be even!")
        ()
    }
}

func TestNotEven(t *) {
    if Even(3) {
        ("3 should not be even!")
        ()
    }
}

After executing go test

PASS
ok      _/root/workspace/go/test_unittest    0.003s

Example 2: Fail() function

func (t *T) Fail() Let the test fail, the test in the same test case continue to be executed, and subsequent tests will continue to be executed

package even

import "testing"

func TestTestingFail(t *) {
    // Let create a fake case, we will call FailNow
    if Even(2) {
        ("All test cases after Fail will still run")
        ()
    }

    if Even(2) {
        ("The test after Fail will still run")
        ()
    }
}

func TestAfterFailCase(t *) {
    if Even(2) {
        ("This test case after Fail will still run")
        ()
    }
}

After the test is executed, the second part in TestTestingFail can also continue to execute.

--- FAIL: TestTestingFail (0.00s)
    even_fail_test.go:8: All test cases after Fail will still run
    even_fail_test.go:13: The test after Fail will still run
--- FAIL: TestAfterFailCase (0.00s)
    even_fail_test.go:20: This test case after Fail will still run
FAIL
exit status 1
FAIL    _/root/workspace/go/test_unittest    0.004s

Example 3: FailNow function

func (t *T) FailNow() makes the test fail, the tests in the same test case will no longer be executed, and subsequent tests will continue to be executed

package even

import "testing"

func TestTestingFailNow(t *) {
    // Let create a fake case, we will call FailNow
    if Even(2) {
        ("All test cases after FailNow will not run")
        ()
    }

    if Even(2) {
        ("The test after FailNow will be skipped")
        ()
    }
}

func TestAfterFailNowCase(t *) {
    if Even(2) {
        ("This test case after FailNow will still run")
        ()
    }
}

After execution, the second test in TestTestingFailNow will no longer be executed, and the subsequent TestAfterFailNowCase continues to be executed.

--- FAIL: TestTestingFailNow (0.00s)
    even_failnow_test.go:8: All test cases after FailNow will not run
--- FAIL: TestAfterFailNowCase (0.00s)
    even_failnow_test.go:20: This test case after FailNow will still run
FAIL
exit status 1
FAIL    _/root/workspace/go/test_unittest    0.003s

Example 4: Log and Fetal functions

func (t *T) Log(args …interface{}) Use the default format to record logs, equivalent to Print(), to record error logs

func (t *T) Fatal(args …interface{}) is similar to Log function, but FailNow will be called after outputting the log

package even

import "testing"

func TestTestingFatal(t *) {
    // Let create a fake case, we will call FailNow
    if Even(2) {
        ("All test cases after FailNow will not run")
    }

    if Even(2) {
        ("The test after Fatal will not run")
    }
}

func TestAfterFatalCase(t *) {
    if Even(2) {
        ("This test case after Fatal will still run")
    }
}

Fatal's execution process is similar to FailNow

--- FAIL: TestTestingFatal (0.00s)
    even_fatal_test.go:8: All test cases after FailNow will not run
--- FAIL: TestAfterFatalCase (0.00s)
    even_fatal_test.go:18: This test case after Fatal will still run
FAIL
exit status 1
FAIL    _/root/workspace/go/test_unittest    0.005s

This is the article about this article about unit testing in Go. For more relevant Go unit testing content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!