These questions are too broad to answer in full, so I’ll just provide a general overview for each.
-
go test
is the command used to run tests you define in _test.go
files. It helps you use the testing
package, which is documented here: https://golang.org/pkg/testing/
- You create a test file in the following format:
yourname_test.go
. Go will expect that any file with a _test.go
suffix should contain tests within it.
- One of the reasons to test your code is to catch issues during development before your code goes into production. It can also be used for optimization purposes, such as with benchmark tests.
- When you write tests you add failure conditions with the help of the
testing
package. You will get output if any of these failure conditions is met. There are also ways to get more output by running tests in verbose
mode, but the first step is to actually write some tests that fail.
Tests can be as simple or as complex as you want to make them. Here is an example of a very simple test for a custom integer addition function. Sorry if there are any mistakes, it is just a rough example, and I am keeping it a bit verbose for the purposes of clarity. TestAddition
would go into a _test.go
file.
func TestAddition(t *testing.T) {
addend1 := 2
addend2 := 2
expectedAnswer := 4
myAnswer := myCustomAddFunc(addend1, addend2)
if myAnswer != expectedAnswer {
t.Errorf("Expected %d, got %d", expectedAnswer, myAnswer)
}
}
If the test fails, you will get the error output in t.Errorf()
above (in relation to your question #4). By using -v
you can also get PASS
output with the names of your passed test cases instead of just the failures.
But testing just one set of addends isn’t very trustworthy, is it? And what if your custom function actually takes ...int
so that you can add more than two integers at a time, which you want to test as well? You can either create a new test function like above for each test case or utilise table driven tests to test your code against different sets of data. Example:
func TestAddition(t *testing.T) {
// Define your test cases:
testCases := []struct {
addends []int
expectedAnswer int
}{
{[]int{2,2}, 4},
{[]int{1,1,1,1}, 4},
{[]int{-1,0}, -1},
{[]int{1}, 1},
}
// Loop through each defined test case
for _, tc := range testCases {
// Run the test! The first parameter is the name of the test, it can be any string you want
t.Run(fmt.Sprintf("%v", tc.addends), func(t *testing.T) {
myAnswer := myCustomAddFunc(tc.addends...)
if myAnswer != tc.expectedAnswer {
t.Errorf("Expected %d, got %d", tc.expectedAnswer, myAnswer)
}
})
}
}
This way you can add as many test cases as you want without having to rewrite the rest of the testing code.
This answer doesn’t really even scratch the surface of go test
. I suggest starting with the documentation I linked above to the testing
package. You can also read more about table driven tests/subtests here: https://blog.golang.org/subtests