Skip to content

Instantly share code, notes, and snippets.

@bbengfort
Created August 14, 2025 20:19
Show Gist options
  • Save bbengfort/8e8ec1a7472b5b7f90a4a72c452ef167 to your computer and use it in GitHub Desktop.
Save bbengfort/8e8ec1a7472b5b7f90a4a72c452ef167 to your computer and use it in GitHub Desktop.
Tabulate and pretty print a coverage table from go test -cover output.
#!/usr/bin/env python3
# Runs go coverage tools and generates a table of coverage per package.
import os
import argparse
import subprocess
from itertools import groupby
from tabulate import tabulate
def gotest(package="./...", profile="coverage.out"):
cmd = [
"go", "test", "-covermode=count",
"-coverprofile=" + profile,
package
]
subprocess.run(cmd)
def read_coverage(profile="coverage.out"):
with open(profile, "r") as f:
for line in f:
if line.startswith("mode:"):
continue
parts = line.split()
parts[0] = os.path.dirname(parts[0].split(":")[0])
parts[1] = int(parts[1])
parts[2] = int(parts[2])
yield parts
def coverage(profile="coverage.out"):
for pkg, group in groupby(read_coverage(profile), key=lambda x: x[0]):
group = list(group)
total = sum(x[1] for x in group)
covered = sum(x[1] for x in group if x[2] > 0)
yield (
pkg,
covered,
total,
f"{covered / total if total > 0 else 0:0.2%}",
)
def main(args):
# run go test
gotest()
# run go tool cover
cov = list(coverage())
print(tabulate(cov, headers=["Package", "Covered", "Statements", "Coverage"], tablefmt="markdown")) # noqa
# cleanup
os.remove("coverage.out")
if __name__ == "__main__":
opts = {}
parser = argparse.ArgumentParser(
description="runs go coverage tools and gernerates a package coverage table", # noqa
epilog="yeh, this should really be a golang program ... le sigh"
)
for pargs, kwargs in opts.items():
if isinstance(pargs, str):
pargs = (pargs,)
parser.add_argument(*pargs, **kwargs)
args = parser.parse_args()
main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment