TDD/TDF with Golang
The new style of writing a software is Test Driven Development or Test First Development and this isn’t only in Go. With this approach we first write the test or test-cases for a feature or enhancement, which made us think about the feature and its requirement precisely.
A new bank Foo-bar is incorporating and they decided to use Go for there application and to start with application will support 3 major operations
- Balance
- Credit
- Debit
Lets write Credit function and some test cases for above Credit function. To create a project in Go create a directory say foobarbank
and run command
go mod init
Above command will create go.mod
file in the directory. Create file name *_test.go and Go will detect it .
- Write your test in file name *_test.go.
- Test function should always be named as
Test*
. - Test function only takes 1 argument
t *testing.B
. - To run a subtest we can use
t.Run
- We can use
t.Helper()
to deg=fine helper function - To run test run below command
go test
PASS
ok github.com/abhishekamralkar/fooBarBank 0.001s
Coverage:
We can also check the coverage of our test cases
go test -cover
PASS
coverage: 25.0% of statements
ok github.com/abhishekamralkar/fooBarBank 0.001s
Now time to write our `Credit` function which takes amount type int and add to Balance and return Balance as type int, that simple. func
is the keyword in Go to create a function and as Go is statically type language you need to explicitly day what data type of argument a function except and what data type function will return if it return.
Though in this example we just writing test cases for 1 function which isnt true in the actual software. We can output a coverage report in .out
format using go test
go test -coverprofile=coverage.out
PASS
coverage: 25.0% of statements
ok github.com/abhishekamralkar/fooBarBank 0.002s
This will output a coverage.out
file in pwd
and we can use this report to see in html
format using below command
go tool cover -html=coverage.out
This will open a tab in default browser and we can view the coverage as html
Benchmark:
Benchmark are executed by the `go test` command when its -bench flag is provided. Benchmarks are run sequentially.
For a description of the testing flags, see https://golang.org/cmd/go/#hdr-Testing_flags.
- Benchmark function name should start from Benchmark
- It takes exactly 1 parameter
*testing.B
- When Benchmark function executed, it runs
b.N
times and measures how long it takes. - By default Benchmarks are run sequentially.
- We can pass
-bench=.
flag totest
to run benchmark
go test -bench=.
goos: linux
goarch: amd64
pkg: github.com/abhishekamralkar/fooBarBank
cpu: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
BenchmarkCredit-4 666403558 1.768 ns/op
PASS
ok github.com/abhishekamralkar/fooBarBank 1.364s
Output 1.768 ns/op
means is our benchmark function takes on average 1.768 nanoseconds to run . To test this it ran it 666403558 times. This results may defer from computer to computer and depends on the resources.
Helper Functions:
- Helper functions accept a
testing.TB
which is an interface that*testing.T
and*testing.B
both satisfy. - Helper functions cab be called from a test, or a benchmark
t.Helper()
is needed to tell the test suite that this method is a helper.