README
¶
Forked from t-yuki
This is a fork of https://github.com/boumenot/gocover-cobertura.
At the time of this writing the repository appears to be on pause with several outstanding PRs, and forks with interesting contributions. This repo consolidates those outstanding forks, and combines them into one repo.
[2026-05-01]: This project has evolved from a private fork created for my own needs into something that is now used by many others. Historically, I have not focused heavily on maintaining this repository—I’ve occasionally merged PRs or made fixes, but for my purposes, the functionality was “good enough.”
However, that context has changed. While this fork met my original goals, it is now clear that others are relying on it. As a result, I feel a greater sense of responsibility for its quality and stability.
To address this, I plan to strengthen the repository by introducing a regression test suite based on popular open-source Go projects. The current test coverage is minimal and needs improvement. Although several PRs have identified issues, the lack of comprehensive testing makes it difficult to confidently ensure that new changes do not introduce regressions.
The goal of the regression suite is to lock in current behavior and enable more deliberate, explicit decisions when making changes. I also hope to extract simplified reproductions from identified issues, which should help improve long-term maintainability (AI has been especially helpful in this area).
I don’t expect to spend much more time here, but I will be more intentional about stewardship now that others depend on it.
go tool cover XML (Cobertura) export
This is a simple helper tool for generating XML output in Cobertura format for CIs like Jenkins and others from go tool cover output.
Installation
Just type the following to install the program and its dependencies:
$ go get github.com/boumenot/gocover-cobertura
Usage
gocover-cobertura reads from the standard input:
$ go test -coverprofile=coverage.txt -covermode count github.com/gorilla/mux
$ gocover-cobertura < coverage.txt > coverage.xml
Note that you should run this from the directory which holds your go.mod file.
Windows note: PowerShell does not support the < operator for stdin
redirection. Use piping instead:
Get-Content coverage.txt | gocover-cobertura > coverage.xml
In cmd.exe, < works but may cause encoding issues with non-ASCII file
paths. The piping approach above avoids this problem on both shells.
Flags
Some flags can be passed (each flag should only be used once):
-
-by-filesCode coverage is organized by class by default. This flag organizes code coverage by the name of the file, which the same behavior as
go tool cover. -
-ignore-dirs PATTERNignore directories matching
PATTERNregular expression. Full directory names are matched, asgithub.com/boumenot/gocover-cobertura(and sogithub.com/boumenotandgithub.com), examples of use:# A specific directory -ignore-dirs '^github\.com/boumenot/gocover-cobertura/testdata$' # All directories autogen and any of their subdirs -ignore-dirs '/autogen$' -
-ignore-files PATTERNignore files matching
PATTERNregular expression. Full file names are matched, asgithub.com/boumenot/gocover-cobertura/profile.go, examples of use:# A specific file -ignore-files '^github\.com/boumenot/gocover-cobertura/profile\.go$' # All files ending with _gen.go -ignore-files '_gen\.go$' # All files in a directory autogen (or any of its subdirs) -ignore-files '/autogen/' -
-ignore-gen-filesignore generated files. Typically files containing a comment indicating that the file has been automatically generated. See
genCodeReregexp in ignore.go. -
-ignore-non-code-linesignore lines with no code. The coverage report generated by
go tool coverincludes some lines with no code. This flag strips lines with no code from coverage data. -
-path DIRset the project directory for package resolution. By default,
gocover-coberturaresolves packages relative to the current working directory. Use this flag when running from a different directory than the module root, for example in monorepos with nested modules:gocover-cobertura -path /repo/services/api < coverage.txt > coverage.xml -
-strictexit with an error if any profiles are skipped due to missing package or module information. By default, skipped profiles produce warnings on stderr but the tool exits successfully. Use this flag in CI pipelines to catch silent data loss:
gocover-cobertura -strict < coverage.txt > coverage.xml
Build tags
If your tests use build tags,
you must pass the same tags when running gocover-cobertura. The tool uses
packages.Load to
resolve source files, and it needs matching tags to find the right files.
Pass tags via the
GOFLAGS environment
variable:
# Single tag
GOFLAGS="-tags=integration" gocover-cobertura < coverage.txt > coverage.xml
# Multiple tags
GOFLAGS="-tags=integration,e2e" gocover-cobertura < coverage.txt > coverage.xml
On Windows (PowerShell):
$env:GOFLAGS="-tags=integration"; gocover-cobertura < coverage.txt > coverage.xml
Why is this needed? When you run go test -tags=integration -coverprofile=coverage.txt,
the coverage profile includes files that are only compiled with that tag (e.g. files
with //go:build integration). Without the matching tag, gocover-cobertura cannot
locate those files and will skip them with a warning on stderr.
Troubleshooting
Warning: skipping profile — no package/module information available
This warning means gocover-cobertura could not resolve a package from the
coverage profile. Common causes:
- Missing build tags — see Build tags above.
- Wrong working directory — run from the directory containing
go.mod, or use the-pathflag. - Standard library packages — coverage profiles occasionally include stdlib packages, which have no module info. These are safely skipped.
Warning: skipping profile — unable to determine file path
The package was resolved but a specific source file was not found. This
typically happens when the coverage profile was generated on a different
platform (e.g. _windows.go files in a profile generated on Windows, but
the converter is running on Linux). These files are safely skipped.
Branch coverage is always 0
The Cobertura format supports branch coverage (branch-rate, branch="true"
on lines), but gocover-cobertura always reports branch-rate="0".
Go's coverage instrumentation tracks which statement blocks were executed, not which branch paths were taken. While branch points (if/else, switch) can sometimes be inferred from block boundaries, Go does not produce enough structural information to reliably count the number of branch arms at a decision point. Reporting inaccurate branch coverage would be worse than reporting none, so this tool leaves branch-rate at 0.
Regression Tests
A snapshot-based regression test suite verifies that conversion output remains
stable across code changes. The suite converts real coverage profiles from
open-source Go projects and compares the XML output against checked-in golden
files. Each regression fixture validates the default output against
golden.xml and the -ignore-non-code-lines output against
golden-ignore-non-code-lines.xml.
Running regression tests (Linux only):
go test -tags regression -run TestRegression -v -timeout 600s
Updating golden files after intentional changes:
go test -tags regression -run TestRegression -update -v -timeout 600s
git diff testdata/regression/ # review the changes
Platform note: Golden files are generated on Linux. The regression tests
are skipped on non-Linux platforms because coverage profiles may reference
platform-specific source files (e.g. _windows.go) that are unavailable on
other operating systems. To regenerate golden files on Windows, use WSL.
Current corpus:
| Project | Tag | Lines |
|---|---|---|
| gorilla/mux | v1.8.1 | 946 |
| spf13/cobra | v1.8.1 | 4,420 |
| approvals/go-approval-tests | v1.9.1 | 1,785 |
| junegunn/fzf | v0.60.0 | 14,137 |
| stretchr/testify | v1.10.0 | 3,196 |
| prometheus/prometheus | v3.2.0 | 78,123 |
| kubernetes/kubernetes | v1.32.0 | 26,956 |
AuthorsMerger
Christopher Boumenot (boumenot)
Thanks
- Yukinari Toyota (t-yuki)
- This tool is originated from gocov-xml by Alexey Palazhchenko (AlekSi)
- DarcySail's PR
- maxatome's PR
- elliotmr's branch
Documentation
¶
There is no documentation for this package.