notexOPENOverview
Notex/Languages/Understanding the Basics of Testing
05.01LESSON 01 OF 29 · 3 MIN READ

Understanding the Basics of Testing

Always free to read

Go’s testing support has two parts: libraries and tooling. The testing package in the standard library provides the types and functions to write tests, while the go test tool that’s bundled with Go runs your tests and generates reports. Unlike many other languages, Go places its tests in the same directory and package as the production code. Every test is written in a file whose name ends with _test.go. If you are writing tests against foo.go, place your tests in a file named foo_test.go. Since tests are located in the same package, they can access and test unexported functions and variables. You’ll see in a bit how to write tests that ensure that you are testing only a public API.

Note

Complete code samples for this topic are found.

Let’s write a simple function and then a test to make sure the function works. In the examples/adder directory, in the file adder.go, you have the following:

func addNumbers(x, y int) int {
    return x + x
}

The corresponding test is in adder_test.go:

func Test_addNumbers(t *testing.T) {
    result := addNumbers(2,3)
    if result != 5 {
        t.Error("incorrect result: expected 5, got", result)
    }
}

Test functions start with the word Test and take in a single parameter of type *testing.T. By convention, this parameter is named t. Test functions do not return any values. The name of the test (apart from starting with the word “Test”) is meant to document what you are testing, so pick something that explains what you are testing. When writing unit tests for individual functions, the convention is to name the unit test Test followed by the name of the function. When testing unexported functions, some people use an underscore between the word Test and the name of the function.

Also note that you use standard Go code to call the code being tested and to validate that the responses are as expected. When there’s an incorrect result, you report the error with the t.Error method, which works like the fmt.Print function. You’ll see other error-reporting methods in a bit.

You’ve just seen the library portion of Go’s test support. Now let’s take a look at the tooling. Just as go build builds a binary and go run runs a program, the command go test runs the test functions in the current directory:

$ go test
--- FAIL: Test_addNumbers (0.00s)
    adder_test.go:8: incorrect result: expected 5, got 4
FAIL
exit status 1
FAIL    test_examples/adder     0.006s

It looks like you found a bug in your code. Taking a second look at addNumbers, you see that you are adding x to x, not x to y. Let’s change the code and rerun the test to verify that the bug is fixed:

$ go test
PASS
ok      test_examples/adder     0.006s

Tip

There are many ways to control the behavior of go test. Some of the most helpful are:

  • Pass a file or directory name to go test to run tests in that file or directory. Using./... runs all tests in the current directory and all subdirectories (go test./...)

  • The -v flag runs tests with verbose output.

  • Use the -run flag to provide a test name or pattern to specify which test functions to run. (go test -run=Test_addNumbers)

For a complete listing of go test flags and configuration, run go help testflag.

Progress is saved on this device.
KEEP EXPLORING

One note leads to another.

Back to the library →
⌕
Search across the entire library ⌘ K