As a software developer nowadays, we are expected to pick things up rather quickly. You can be assigned to a JIRA ticket to make changes to an app written in a programming language you are not that familiar with. It's normal to compare or ask for example how is it done in Go when you are used to the Java way. What do you do? Pass up on that task or jump straight in? You can refuse the task and pick something else but I wonder how management would see that.
Anyway, here's a look at unit testing in Go with a Java background. This Go repo, go-unit-testing is a port of this Java repo, tdd-junit.
Tools
- Visual Studio Code 1.126 with a Go extension
- Windows 11 Home 10.0.26200
- Go version 1.22.1
Those are the tools I used to build this example.
Let's Go Unit Testing
Go has a built-in package for testing and surprisingly, it's called testing. It is part of Go's standard library. Comparing to Java, JUnit is not part of the standard library.
Below is the function that we will test. It's under the mathfun package.
package mathfun
func GetGcf(x int, y int) int {
if y == 0 {
return x
} else {
return GetGcf(y, x%y)
}
}
Let's write the code that will test our function. Under the mathfun package, create the file math_fun_test.go. The _test.go tells Go that this file contains test functions. Below is the code of the said file:
package mathfun
import (
"testing"
)
func TestWithTwoPositiveNumbers(t *testing.T) {
actual := GetGcf(12, 16)
expected := 4
if expected != actual {
t.Errorf(`GCF of 12 and 16, expected = %d, actual = %d`, expected, actual)
}
}
func TestWithZero(t *testing.T) {
actual := GetGcf(0, 6)
expected := 6
if expected != actual {
t.Errorf(`GCF of 0 and 6, expected = %d, actual = %d`, expected, actual)
}
}
Basically, the above code exercises the GetGcf function. Making sure to try and run every line of code in it. It checks for correct return values.
Ok, unlike Java, it's function names and not annotations (e.g. @Test) but still the function naming is DAMP. Test function names have the form of TestName, where Name is the DAMP (Descriptive and Meaning Phrase) of the test. The testing.T type parameter is used for logging and reporting your test result.
One thing that's been ingrained in me is the assertEquals. So it was surprising that Go didn't have an assert function but just do an if statement and based on that error out. I kinda like assert equals expected actual thing.
Running Go Unit Tests
The "go test" command. Executes all test function (names beginning with Test) it could find inside files ending in _test.go.
C:\workspace\go-unit-test\mathfun> go test
PASS
ok go-unit-test/mathfun 0.578s
go text -v for verbose output
C:\workspace\go-unit-test\mathfun> go test -v
=== RUN TestWithTwoPositiveNumbers
--- PASS: TestWithTwoPositiveNumbers (0.00s)
=== RUN TestWithZero
--- PASS: TestWithZero (0.00s)
PASS
ok go-unit-test/mathfun 0.556s
The command below runs the test in current directory. The last bit will run tests in all directories.
C:\workspace\go-unit-test\mathfun> go test .
ok go-unit-test/mathfun 0.550s
C:\workspace\go-unit-test\mathfun> cd ..
C:\workspace\go-unit-test> go test .
? go-unit-test [no test files]
C:\workspace\go-unit-test> go test ./...
? go-unit-test [no test files]
ok go-unit-test/mathfun (cached)
As you can see above, Go caches successful test results to avoid running it again. The rule is, if the test binary is the same and there are no flags in the command line telling Go to rerun the test, then it will pull the cached test. Changes to your code or test code invalidates the cached test result so this isn't much of a big deal but if you really want to invalidate the cached test results, you can go clean -testcache
The command below does per package testing and the last two run the test per function.
C:\workspace\go-unit-test> go test ./mathfun
ok go-unit-test/mathfun (cached)
C:\workspace\go-unit-test> go test -run ^TestWithTwoPositiveNumbers$ go-unit-test/mathfun
ok go-unit-test/mathfun 0.566s
C:\workspace\go-unit-test> go test -v -run ^TestWithTwoPositiveNumbers$ go-unit-test/mathfun
=== RUN TestWithTwoPositiveNumbers
--- PASS: TestWithTwoPositiveNumbers (0.00s)
PASS
ok go-unit-test/mathfun 0.527s
If you need more information on the go test command, it is right at your finger tips.
C:\workspace\go-unit-test\mathfun> go help test
usage: go test [build/test flags] [packages] [build/test flags & test binary flags]
'Go test' automates testing the packages named by the import paths.
It prints a summary of the test results in the format:
...snipped...
Go Unit Testing Summary
At the end of the day. Comparing it to JUnit, I'd say same nail pounded by a different hammer. Same principles really. As much as possible, all code has to be exercised and make sure the actual output is the same as the expected output.
No comments:
Post a Comment