blob: d1d8cc12bd1bd70263882be9ca912fd948e55358 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Introduction
2Writing good tests is not trivial, but in many situations a lot of ground can be covered with table-driven tests: Each table entry is a complete test case with inputs and expected results, and sometimes with additional information such as a test name to make the test output easily readable. If you ever find yourself using copy and paste when writing a test, think about whether refactoring into a table-driven test or pulling the copied code out into a helper function might be a better option.
3
4Given a table of test cases, the actual test simply iterates through all table entries and for each entry performs the necessary tests. The test code is written once and amortized over all table entries, so it makes sense to write a careful test with good error messages.
5
6## Example of a table driven test
7
8Here is a good example from the testing code for the ` fmt ` package ( http://golang.org/pkg/fmt/ ):
9
Faiq Raza2610b062015-11-30 15:34:08 -050010```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110011var flagtests = []struct {
12 in string
13 out string
14}{
15 {"%a", "[%a]"},
16 {"%-a", "[%-a]"},
17 {"%+a", "[%+a]"},
18 {"%#a", "[%#a]"},
19 {"% a", "[% a]"},
20 {"%0a", "[%0a]"},
21 {"%1.2a", "[%1.2a]"},
22 {"%-1.2a", "[%-1.2a]"},
23 {"%+1.2a", "[%+1.2a]"},
24 {"%-+1.2a", "[%+-1.2a]"},
25 {"%-+1.2abc", "[%+-1.2a]bc"},
26 {"%-1.2abc", "[%-1.2a]bc"},
27}
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110028func TestFlagParser(t *testing.T) {
29 var flagprinter flagPrinter
30 for _, tt := range flagtests {
Martin Tournoij27d2c512018-04-10 22:24:43 +010031 t.Run(tt.in, func(t *testing.T) {
32 s := Sprintf(tt.in, &flagprinter)
33 if s != tt.out {
34 t.Errorf("got %q, want %q", s, tt.out)
35 }
36 })
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110037 }
38}
39```
40
Martin Tournoij27d2c512018-04-10 22:24:43 +010041Note the detailed error message provided with ` t.Errorf `: its result and expected result are provided; the input is the subtest name. When the test fails it is immediately obvious which test failed and why, even without having to read the test code.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110042
43A ` t.Errorf ` call is not an assertion. The test continues even after an error is logged. For example, when testing something with integer input, it is worth knowing that the function fails for all inputs, or only for odd inputs, or for powers of two.
44
45## References
46
47 * http://golang.org/doc/code.html#Testing
48 * http://golang.org/doc/faq#assertions
49 * http://golang.org/doc/faq#testing_framework
50 * http://golang.org/pkg/testing/