TestMain Without os.Exit
ID |
go.testmain_no_exit |
Severity |
low |
Remediation Complexity |
simple |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Go |
Tags |
CWE:391, reliability, testing |
Description
Reports a TestMain(m *testing.M) entry point whose body never calls os.Exit. Without that
call the process always exits with status zero, so failing tests do not fail the build.
Rationale
When a test binary defines TestMain, that function replaces the default runner and becomes solely
responsible for translating the result of m.Run() into the process exit code. If it returns
normally instead of calling os.Exit(m.Run()), the process exits 0 no matter how many tests
failed — the failures are silently swallowed and continuous integration reports a green build on a
red test suite. The check fires only on a function named TestMain that takes a *testing.M and
contains no os.Exit call anywhere in its body.
func TestMain(m *testing.M) { // FLAW — never calls os.Exit; failures are hidden
m.Run()
}
func TestMain(m *testing.M) { // OK
os.Exit(m.Run())
}