Golang std testing: Difference between revisions
From wikinotes
(→Usage) |
(→Usage) |
||
Line 13: | Line 13: | ||
<blockquote> | <blockquote> | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
go test | go test # run all tests | ||
go test ./... # run all tests | go test ./... # run all tests | ||
go test -run FooTest # run top-level tests containing 'FooTest' | go test -run FooTest # run top-level tests containing 'FooTest' | ||
go test -run FooTest ./internal/foo # run tests matching 'FooTest in package at '/internal/foo' | go test -run FooTest ./internal/foo # run tests matching 'FooTest in package at '/internal/foo' | ||
go test ./internal/foo -v # run internal/foo tests, and print | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 01:16, 17 July 2022
Go ships with a minimalist test suite.
Documentation
testing
https://pkg.go.dev/testing@go1.18.3
Usage
go test # run all tests go test ./... # run all tests go test -run FooTest # run top-level tests containing 'FooTest' go test -run FooTest ./internal/foo # run tests matching 'FooTest in package at '/internal/foo' go test ./internal/foo -v # run internal/foo tests, and printyou can also create an ad-hoc test-package and run exclusively a ad-hoc test.go package,
but this is not considered the normgo test internal/foo/bar_test.go
Example
The builtin go test framework is fairly minimalist.
Tests are just functions, you can loop them if useful.
Tests are typically kept alongside code.
// myproject/mypackage/mylib.go package mypackage func Hello(name string) string { return "Hello, " + name }// myproject/mypackage/mylib_test.go package mypackage import "testing" func TestHello(t *testing.T) { res := Hello("Adam") if res != "Hello, Adam" { t.Errorf("Hello() result did not match") } }
Sample Strategies
1x test per struct
The mangos library uses a really clean approach.
A library of assertions is created, then each test
- Instantiates a struct
- Asserts on all public methods of the struct
https://github.com/nanomsg/mangos/blob/master/test/certs_test.go test cases (per struct) https://github.com/nanomsg/mangos/blob/master/test/util.go test assertions Table Tests
See subtests below.
Assertions
There are no assertions, you are responsible for tests and messages.
func TestHello(t *testing.T) { // log message and fail (but continue executing) t.Errorf("expected: %v\nreceived: %v", expects, received) t.Fail() // mark test as failed, but continue t.FailNow() // mark test as failed and stop executing t.Skip("Reason") // log, and stop executing t.TempDir() // provides a tempdir that is deleted once test finishes running }
Subtests
Evaluate subtests under one function using
t.Run("TESTNAME", ...)
.import "example.com/x/hello" // <-- despite sharing package, must import package in test func TestHello(t *testing.T) { tcases := []struct { // <-- slice of structs containing testdata test string name string expects string }{ { test: "ValidName", name: "Adam", }, { test: "NilName", name: nil, } } for _, tcase := range tcases { t.Run(tcase.test, func(t *testing.T) { // <-- t.Run() evaluates each case res := hello.Hello(tcase.name) if res != tcase.expects { t.Errorf("Failed because...") } } } }You can also implement setup/teardown this way using
defer
functions.
Benchmarking
There are tools for benchmarking. See docs
Fuzzing
There are tools for fuzzing tests. See docs