Testing packages
In Go it is customary to write (unit) tests for your package. Writing testsinvolves the testing
package and the program go test
.Both have excellent documentation.
The go test
program runs all the test functions. Without any defined tests forour even
package, go test
yields:
% go test
? even [no test files]
Let us fix this by defining a test in a test file. Test files reside in thepackage directory and are named _test.go
. Those test files are just likeother Go programs, but go test
will only execute the test functions. Each testfunction has the same signature and its name should start withTest
: func TestXxx(t
testing.T)
.
When writing test you will need to tell go test
whether a test wassuccessful or not. A successful test function just returns. Whenthe test fails you can signal this with the followingfunctions. These are the most important ones (see go doc testing
or go help testfunc
for more):
func (t *T) Fail()
,Fail
marks the test function as having failed butcontinues execution.func (t *T) FailNow()
,FailNow
marks the test function as having failedand stops its execution. Any remaining tests in this file are skipped, andexecution continues with the next test.func (t *T) Log(args …interface{})
,Log
formats its arguments usingdefault formatting, analogous toPrint()
, and records the text in the errorlog.func (t *T) Fatal(args …interface{})
,Fatal
is equivalent toLog()
followed byFailNow()
.
Putting all this together we can write our test. First we pick a name:even_test.go
. Then we add the following contents:
package even 1
import "testing" 2
func TestEven(t *testing.T) { 3
if !Even(2) {
t.Log("2 should be even!")
t.Fail()
}
}
A test file belongs to the current 1 package. This is not only convenient, butalso allows tests of unexported functions and structures. We then 2 import thetesting
package. And finally the test we want to execute. The code here 3should hold no surprises: we check if the Even
function works OK. And now, themoment we have been waiting for executing the test.
% go test
ok even 0.001s
Our test ran and reported ok
. Success! If we redefine our test function, wecan see the result of a failed test:
// Entering the twilight zone
func TestEven(t *testing.T) {
if Even(2) {
t.Log("2 should be odd!")
t.Fail()
}
}
We now get:
FAIL even 0.004s
--- FAIL: TestEven (0.00 seconds)
2 should be odd!
FAIL
And you can act accordingly (by fixing the test for instance).
Writing new packages should go hand in hand with writing (some)documentation and test functions. It will make your code better and itshows that you really put in the effort.
The Go test suite also allows you to incorporate example functions which serveas documentation and as tests. These functions need to start with Example
.
func ExampleEven() {
if Even(2) {
fmt.Printf("Is even\n")
}
// Output: 1
// Is even
}
Those last two comments lines 1 are part of the example, go test
uses thoseto check the generated output with the text in the comments. If there isa mismatch the test fails.