Why
There are many kinds of automated tests and two main kinds are integration tests and unit tests.
Unit tests are designed to run as fast as possible, so any slower processes like databases are mocked out. While super helpful and powerful in terms of providing confidence in the software, it should be only one part of the testing strategy.
Integration tests, as is implied runs tests of the different part of the software integrated together. Technically speaking, you can still mock out the database and other slower layers to keep it running quickly. However, there is value in including a database or other slower services in the process to test as them in an automated fashion.
What this does mean though, is that you want to be able to run only the unit tests or run the integration tests as well. You might also want to have smoke tests, which are run on your live production environment.
How
You could define a separate target in your BUILD
file with the unit tests and let gazelle
automatically build your default test target with all the tests. I found this frustrating to use as I had to keep tweaking the dependencies manually whenever anything changed (which happened often)
Tagging
The easiest way to achieve this for golang and bazel is to tag your source code files. You can do this by adding the following to the top of your integration test files
something_integration_test.go
//go:build integration_test
package somepackage
You can pick any tag name you want instead of integration_test
like integration
, smoke_test
etc.
IDE Support
You will likely need to add this source file into the IDEs build constraints to get the IDE to treat it as a source file. In IntelliJ (IDEA/Goland), you will be warned of this
If you click Edit settings
, you can add the tag in
When running gazelle
, you want to include the files with these tags
Gazelle
bazel run //:gazelle -- -build_tags=integration_test
If you have multiple tags, you can separate them with commas. This command will generate a test target with all of the source files and its dependencies
Bazel Integration on test
To run only the unit tests, you test as normal:
bazel test ... # or the specific target, and it'll run only the unit tests
To run the integration tests as well, include that tag
bazel test ... --define gotags=integration_test # Will run unit & integration tests
Run only Unit Tests
This setup will currently not allow you to run ONLY the integration tests. To be able to do that you’ll need to add a unit_test
tag to the unit test files so that you can exclude them.
something_test.go
//go:build integration_test
package somepackage
You can then run only the unit tests with
bazel test … --define gotags=unit_test # Will run unit & integration tests
Only the integration tests
bazel test … --define gotags=integration_test # Will run unit & integration tests
Or both:
bazel test … --define gotags=unit_test,integration_test # Will run unit & integration tests
Simpler gazelle command
You can enable the tags by default in the BUILD
file so that you don’t have to pass the tags into gazelle each time.
BUILD
# gazelle:build_tags unit_test,integration_test
You can then just run bazel run //:gazelle
which will run with these tags enabled.
Sample Source
You can find sample source code demonstrating this in my github repo, under post/2023/11/separatetests