Why tests: go test and a first test
Every time you changed your app, you tested it the same way: run it, type some input, read the output, decide if it looks right. That works — until the app has ten functions and you'd have to re-check all of them after every change. You won't. So bugs sneak back in.
A test is code that checks other code, automatically. You write it once; go test runs it in a fraction of a second, as often as you like.
Go has testing built in — no library to install. Two conventions do all the work:
- Test code lives in a file whose name ends in
_test.go(e.g.text_test.go). Go keeps it out of your normal build; it only compiles when you run tests. - A test is a function named
TestSomethingthat takes one argument,t *testing.T.
Here's a complete first test. Say your app has this function:
func double(n int) int {
return n * 2
}
The test for it:
package main
import "testing"
func TestDouble(t *testing.T) {
got := double(5)
want := 10
if got != want {
t.Errorf("double(5) = %d, want %d", got, want)
}
}
Read it plainly: call the function, compare got with want, and if they differ, call t.Errorf to report it. t.Errorf doesn't stop the program — it records the failure and lets the rest of the test keep running.
Run it from your project folder:
go test
If everything matches, you get a quiet, satisfying:
ok yourapp 0.2s
That ok means every test passed. Want to see each one by name? Add -v (verbose):
go test -v
got/want is the whole style. Notice the error message says exactly what happened and what was expected: double(5) = 11, want 10. When a test fails months from now, that one line tells you what broke without opening the code. Always phrase failures this way.
Next: the pattern that lets one test check many cases at once — and we'll point it straight at a bug you've already met.