Selectively Running Tests in Go
This should most likely be filed in "things I'll probably forget unless I write it down." This post covers how to selectively run a subset of tests in Go. This can be useful for running a single test, all tests with a certain naming convention in a project, etc.
Overview
Let's start with a really basic example. We have two packages: bar and foo. Each package has a file with the same name as the package, a unit test file, and an integration test file.
├── bar
│ ├── bar.go
│ ├── bar_integration_test.go
│ └── bar_test.go
├── foo
│ ├── foo.go
│ ├── foo_integration_test.go
│ └── foo_test.go
├── go.mod
└── go.sum
The test files in the bar and foo packages look similar to what the bar package contents look like below:
Run All Tests
If you're looking to just run all the tests in your project, you can do this really easily with the following command:
go test ./... -v
This results in the following output:
=== RUN TestBarIntegrationTestSuite
=== RUN TestBarIntegrationTestSuite/Test
--- PASS: TestBarIntegrationTestSuite (0.00s)
--- PASS: TestBarIntegrationTestSuite/Test (0.00s)
=== RUN TestBarTestSuite
=== RUN TestBarTestSuite/Test
--- PASS: TestBarTestSuite (0.00s)
--- PASS: TestBarTestSuite/Test (0.00s)
PASS
ok github.com/bgreeley/golang-integration-test/bar 0.213s
=== RUN TestFooIntegrationTestSuite
=== RUN TestFooIntegrationTestSuite/Test
--- PASS: TestFooIntegrationTestSuite (0.00s)
--- PASS: TestFooIntegrationTestSuite/Test (0.00s)
=== RUN TestFooTestSuite
=== RUN TestFooTestSuite/Test
--- PASS: TestFooTestSuite (0.00s)
--- PASS: TestFooTestSuite/Test (0.00s)
PASS
ok github.com/bgreeley/golang-integration-test/foo 0.400s
The ./...
shorthand means to run all of the tests in all of the folders in this project recursively.
The -v
option shows more verbose output for which tests were run, which passed / failed, how much time passed, etc.
Run Tests in a Single Package
If you want to run the tests in a single package, you can use the following command:
go test ./bar/... -v
This results in the following output:
=== RUN TestBarIntegrationTestSuite
=== RUN TestBarIntegrationTestSuite/Test
--- PASS: TestBarIntegrationTestSuite (0.00s)
--- PASS: TestBarIntegrationTestSuite/Test (0.00s)
=== RUN TestBarTestSuite
=== RUN TestBarTestSuite/Test
--- PASS: TestBarTestSuite (0.00s)
--- PASS: TestBarTestSuite/Test (0.00s)
PASS
ok github.com/bgreeley/golang-integration-test/bar 0.214s
Run Tests in a Single Test File
If you want to run the tests in a single test file, you can use the following command:
go test ./bar/bar_test.go -v
This results in the following output:
=== RUN TestBarTestSuite
=== RUN TestBarTestSuite/Test
--- PASS: TestBarTestSuite (0.00s)
--- PASS: TestBarTestSuite/Test (0.00s)
PASS
ok command-line-arguments 0.356s
Run a Specific Test
If you want to run the a specific test in a single test, you can use the following command:
go test ./bar/bar_test.go -run TestBarTestSuite -v
This results in the following output:
=== RUN TestBarTestSuite
=== RUN TestBarTestSuite/Test
--- PASS: TestBarTestSuite (0.00s)
--- PASS: TestBarTestSuite/Test (0.00s)
PASS
ok command-line-arguments 0.229s
Run Similarly Named Tests Across Different Files
If you want to run similarly named tests across different files, you can use the following command:
go test ./... -run "^Test.*IntegrationTestSuite$" -v
This is handy if you have a test name pattern for all integration tests and want to run all of these at once.
This results in the following output:
=== RUN TestBarIntegrationTestSuite
=== RUN TestBarIntegrationTestSuite/Test
--- PASS: TestBarIntegrationTestSuite (0.00s)
--- PASS: TestBarIntegrationTestSuite/Test (0.00s)
PASS
ok github.com/bgreeley/golang-integration-test/bar 0.214s
=== RUN TestFooIntegrationTestSuite
=== RUN TestFooIntegrationTestSuite/Test
--- PASS: TestFooIntegrationTestSuite (0.00s)
--- PASS: TestFooIntegrationTestSuite/Test (0.00s)
PASS
ok github.com/bgreeley/golang-integration-test/foo 0.407s
If you're having trouble writing a pattern, you can use list
instead of run
to see which tests will execute for the given pattern. In our case, if we run:
go test ./... -list "^Test.*IntegrationTestSuite$" -v
This results in the following output:
TestBarIntegrationTestSuite
ok github.com/bgreeley/golang-integration-test/bar 0.211s
TestFooIntegrationTestSuite
ok github.com/bgreeley/golang-integration-test/foo 0.402s
There are a lot more ways to control what's being tested, how it's being tested, different formats the results can be published in, etc. I'll cover those in future posts to keep this one more focused.