gotestsum: a go test runner with readable output, JUnit XML and flaky test reruns
'go test' runner with output optimized for humans, JUnit XML for CI integration, and a summary of the test results.
At a glance
- What is it?
- gotestsum wraps go test -json to print human-friendly test output, emit JUnit XML for CI, and rerun failed tests. It suits Go teams whose CI needs structured results and whose local runs need less noise.
- Who is it for?
- Adopt gotestsum if your CI needs JUnit XML from go test, or if flaky tests make you rerun whole packages. Skip it if plain go test output already satisfies your pipeline and you have no use for a summary or a structured report.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 170 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap between go test -json and something a human can read
go test can emit machine-readable output with -json, but that stream is not meant to be read. gotestsum consumes it, reformats it for a terminal, and keeps the structured data available for machines. The README describes the tool as running tests using go test -json and printing formatted test output plus a summary. That is the whole idea: one command produces something a developer watches during a run and something a CI server can parse afterward. It is aimed at Go teams that already run go test but want a summary line, colorized pass and fail markers, and a JUnit XML artifact without writing a parser. The README notes it is used by some popular Go projects, which is a statement about adoption rather than a guarantee about your use case.
How gotestsum sits between go test and your terminal
The data flow is narrow and worth understanding before you adopt it. gotestsum invokes go test with -json, reads the test2json event stream, and renders it. The --jsonfile flag writes that same line-delimited input to a file, which the README says can be used to compare runs or find flaky tests. The --junitfile flag converts the events into a JUnit XML report. Because the JSON stream is the intermediate representation, every feature is downstream of it: formats, the summary, the JUnit conversion, and the rerun logic. The repository layout reflects this, with a testjson package exposed at pkg.go.dev for parsing the JSON output yourself, plus cmd/ and internal/ directories around the main entry point. That design means gotestsum does not replace the Go toolchain. It does not compile or link anything on its own; it drives go test and interprets what comes back. If go test cannot build a package, gotestsum reports the build error rather than fixing it.
Installing gotestsum and running it against a real package
The README gives three routes: download a binary from the releases page, install with go install, or run without installing. The go install form is the shortest path for a machine that already has a Go toolchain. Note the module path in the command, gotest.tools/gotestsum, which differs from the GitHub repository path.
go install gotest.tools/gotestsum@latestAfter that, gotestsum is on your PATH and can be invoked directly. If you would rather not install anything, the README also documents running it straight from the module cache.
go run gotest.tools/gotestsum@latestFor a first real run, point it at a package and ask for a JUnit file, which is the CI-oriented path most teams start with.
gotestsum --junitfile unit-tests.xml ./...You should see formatted test output as the run proceeds and a summary at the end. The summary ends with a line shaped like the one in the README, counting tests run, skipped, failed, build errors, and elapsed time including build time. The unit-tests.xml file is the artifact to hand to your CI system. To change what the terminal shows, set --format; the README lists dots, pkgname (the default), testname, testdox, standard-quiet and standard-verbose, and --help lists the rest. The environment variable GOTESTSUM_FORMAT does the same job as the flag.
JUnit XML naming, and why CI systems reject it
The most common friction point with any JUnit producer is field naming, and gotestsum exposes it rather than hiding it. The package names written into testsuite.name and testcase.classname default to the full package path. If your CI system groups results by a different key, two flags change it: --junitfile-testsuite-name and --junitfile-testcase-classname. Both accept short, relative, or full, where short is the base name of the package, relative is the path from the repository root, and full is the default. This is a real trade-off in the sense that the default is not universally correct; the README acknowledges that the values may not work with your CI system. There is also a smaller operational detail: if Go is not installed or the go binary is not on PATH, gotestsum emits a warning about failing to look up the Go version for the JUnit XML, and the README says the GOVERSION environment variable can be set to suppress it. That matters for container images that run gotestsum against a prebuilt test binary.
Reruns, watch mode and the slowest-test tool
The --rerun-fails flag reruns failed tests rather than the whole suite, which the README frames as a time saver on flaky suites. That is a targeted feature: it does not make flakiness go away, it stops a single flaky test from forcing a full re-run. Separately, --watch reruns tests for the package that changed whenever a .go file is saved, which is a local development convenience rather than a CI one. The gotestsum tool slowest subcommand reads a JSON file produced with --jsonfile and either lists the slowest tests or edits the source of those tests to add a conditional t.Skip, so that gotestsum -- -short ./... skips them. That last workflow is opinionated: it writes to your test files. Treat the automatic source update as something to run deliberately and review, not as a step in a pipeline. The --post-run-command flag runs an arbitrary command after the run with environment variables such as TESTS_FAILED, TESTS_TOTAL, GOTESTSUM_ELAPSED and GOTESTSUM_JUNITFILE set, which is how the README's desktop notification example is wired.
Where gotestsum is the wrong layer
gotestsum is a presentation and reporting layer, and it inherits every limitation of go test. It cannot run tests in parallel beyond what go test itself does, so a request for parallel execution is really a question about your go test flags, which gotestsum passes through. It does not manage caches; the go test cache behaves as it does without gotestsum, and the README does not document any cache control of its own. It does not retry at the package level with backoff, quarantine flaky tests, or track flakiness over time; --rerun-fails is a single rerun mechanism, not a flake management system. The --jsonfile is the raw material if you want to build that yourself, and the README points at the testjson package for parsing it. If your CI already ingests go test -json directly and your developers are content with standard output, gotestsum adds a binary to install and keep current without changing what your pipeline learns.
gotestsum versus driving go test yourself
The alternative is not another test runner so much as the toolchain you already have: go test with -json, plus a converter you maintain. go test -json gives you the event stream, and go test -v gives you verbose output, but neither produces a JUnit file or a DONE summary line. gotestsum's difference in approach is that it owns the rendering and the conversion in one binary, and exposes the intermediate JSON so you can build on it. The cost of that convenience is a dependency you update on its own schedule. The repository's go.mod pins a set of libraries including gotestdox for the testdox format and fsnotify for watch mode, so the binary carries more than a thin wrapper around the standard library. If your only requirement is a JUnit file, the honest comparison is between maintaining a small converter and adopting gotestsum's flags; the latter is less code, the former is fewer moving parts.
Maintenance, licensing and the upgrade path
The repository is not archived, and the last push was on 2026-04-15, so it is reasonable to describe the project as still receiving changes. The most recent release listed is v1.13.0 from 2025-09-11, preceded by v1.12.3 and v1.12.2. The go.mod declares go 1.24.0, which sets a floor on the toolchain you need to build it from source; if your CI image ships an older Go, the go install route will fail and the release binary is the fallback. The project is licensed under Apache-2.0, and the repository includes a NOTICE file alongside the LICENSE, which is the usual Apache-2.0 pattern for attribution. That licence permits commercial and internal use and modification; if you redistribute gotestsum inside a product, read the NOTICE and the licence text rather than assuming the header is enough. Upgrades are a binary swap or a re-run of go install, but the environment variable names and flags are part of your CI configuration, so treat a version bump as a config review, not just a download.
Editorial conclusion
Adopt gotestsum if your CI needs JUnit XML from go test, or if flaky tests make you rerun whole packages. Skip it if plain go test output already satisfies your pipeline and you have no use for a summary or a structured report. Before rolling it out, verify that your CI system accepts the testsuite.name and testcase.classname values the defaults produce, and check which --format your terminal renders correctly.
Frequently asked questions
How do I install gotestsum?
Download a binary from the releases page, or build from source with go install gotest.tools/gotestsum@latest. The README also documents running it without installing via go run gotest.tools/gotestsum@latest.
What is the difference between gotestsum and go test?
gotestsum runs go test -json and reformats the output, adding a summary line and optional JUnit XML or JSON file output. Plain go test gives you the raw output and does not produce a JUnit report or a DONE summary.
How do I get JUnit XML output from gotestsum?
Set the --junitfile flag or the GOTESTSUM_JUNITFILE environment variable to a file path, for example gotestsum --junitfile unit-tests.xml. The package names in the report can be adjusted with --junitfile-testsuite-name and --junitfile-testcase-classname.
Which output formats does gotestsum support?
The README lists dots, pkgname (the default), testname, testdox, standard-quiet and standard-verbose, and says --help shows the full list. The format is set with --format or the GOTESTSUM_FORMAT environment variable.
Can gotestsum rerun only the tests that failed?
Yes. The --rerun-fails flag reruns failed tests instead of the entire suite, which the README describes as a time saver when working with flaky test suites.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gotestyourself-gotestsum)