Note: there are some failing tests around that need to be fixed. We suggest running only the test that is
part of the exercise by running go test -run TestName
in order to avoid unnecessary noise.
Note: there are not universal solutions. The proposed one are illustrative. There are many possible correct solutions.
- Write one or more (the more the better) unit tests.
If unsure where to start:
api/v1
orconfig
can be quite simple; for more complex scenarios:middleware
. - Check the coverage before/after the tests. You can use the
make cover-view
makefile target. - Write one or more integration tests, e.g. tests which involve two or more packages.
If unsure where to start:
ledger
is probably the simplest case,controller
provides more (and more complex) opportunities. - Check how the coverage changed before/after the integration tests.
- Compile the test binaries, and then run them.
Solutions: please checkout the part1_solution
branch and git grep solution:part1
- Modify the
TestMerge
test under model/todo_merge_test.go to be a table based test. - Try to have shared code initializing one
Todo
item to be merged - Try to make the test execution parallel
- Run
go test -v -run TestMerge
to see all the tests (and their names) - Try to use
go test -run TestMerge/xxx
to run one single test
Examples: Sub tests and table tests examples
- Try to run the rendering tests under model/todo_render_test.go with
go test -run TestRender
- Let the test generate the golden files with
go test -run TestRender -update
- Verify that the generated golden file is what we expect
- Check if the test is now passing by matching the golden file
go test -run TestRender
- Extend the tests and verify the generated files are valid
Examples: Fixtures and golden files examples
- Bootstrap a ginkgo suite:
go install github.com/onsi/ginkgo/v2/ginkgo
go get github.com/onsi/gomega/
go mod tidy
mkdir e2e && cd e2e
ginkgo bootstrap .
- Run tests using ginkgo:
ginkgo -v ./e2e/...
- Write and run one or more e2e tests using ginkgo. You can either assume the
go-todo-app
is running, or run it as part of the test suite. Evaluate the pros and cons of each approach. - Integrate gingko custom matcher in the e2e test(s) you wrote
- Compile the e2e test binary which uses ginkgo, and run it
Solutions: please checkout the part3_solution
branch and git grep solution:part3
Change the code so that model/todo_dep_test.go is deterministic (hint: the New(title string)
function has a dependency from the time
package that can be replaced / injected)
The TestTodoCreate
function under controller/controller_dep_test.go is not testing the returned uuid. This is because fetching the uuid requires the interaction with a remote service.
- Make the test validate uuid
- Change the code so that uuid can be deterministic
- Add a negative test (when the call to the service fails)
- Let the test validate that the uuid is requested only once per call
Examples under https://github.com/fedepaol/gotestbootcamp/tree/main/dependency_injection
- Check the uuid/uuid_test.go and see why it fails
- Modify the code so that the result of uuid/uuid_test.go is deterministic.
- Change the test so that:
- it verifies that the endpoint is called only once per
NewUUID
call - it verifies it can handle uuids of len=3 and len=10
- it verifies that when the call returns a failure, the function returns an error
- it verifies that the endpoint is called only once per
Examples under https://github.com/fedepaol/gotestbootcamp/tree/main/httpserver
- Extend the
TestWithRedis
test under store/redis_test.go - Fill the emtpy tests
- Add more tests
- Run the benchmark test under controller/controller_bench_test.go with
go test -run xx -bench . -benchmem
(note the run xx to avoid running the tests too). - Replace the implementation being instrumented the the one using a Reader (
todoFromRequestReader
) and benchmark again - Install benchstat with
go install golang.org/x/perf/cmd/benchstat@latest
- Validate the difference between the two approaches:
go test -run xx -bench . -benchmem -count 10 > withreader.txt
# replace the implementation back
go test -run xx -bench . -benchmem -count 10 > withstrings.txt
benchstat withstrings.txt withreader.txt
Examples under https://github.com/fedepaol/gotestbootcamp/tree/main/benchmarking
- Integrate
go-cmp
in the tests used previously. Make sure to usecmp.Diff
andcmp.Equal
Good candidates can be tests formodel
or forapi/v1
(go get github.com/google/go-cmp
) - Rewrite existing unit tests to use
testify/assert
(go get github.com/stretchr/testify
)