Good resources for mastering `go test`


(Anik Hasibul) #1

Hey there,

Can you please share some good resources for mastering go test or *_test.go.

I only know that go test is being used for checking errors and benchmarking.

But I this it’s something different and more.

So please share your helpful knowledges about:

  1. What is go test?
  2. How to create a test file?
  3. Why to test?
  4. I am not getting any output, so how can I say My code is OK

(Liza) #2

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


(system) #3

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.