pytest Exit Codes 0-5: What Each One Means in CI
pytest defines exit codes 0 through 5, each meaning something specific - including code 5 for "no tests collected".
Unlike most tools, pytest assigns a distinct meaning to each of its exit codes, so the number tells you precisely what happened.
What it means
0 = all tests passed; 1 = some tests failed; 2 = interrupted (e.g. Ctrl-C); 3 = an internal pytest error; 4 = a command-line usage error; 5 = no tests were collected.
Common causes
- Exit 5: wrong
testpaths/rootdir or files not namedtest_*.py. - Exit 4: a bad CLI flag or option.
- Exit 2: the run was cancelled or a fixture aborted it.
How to fix it
Map the code to its meaning, then act: for 5, fix discovery (paths, naming, conftest.py); for 4, fix the invocation; for 1, read the failing assertions. These are deterministic test outcomes, not transient.
Reading exit codes in CI
- A shell reports
128 + Nwhen a process is terminated by signal N: 137 is SIGKILL (usually the out-of-memory killer), 143 is SIGTERM, 130 is SIGINT. - Exit code 137 in a container almost always means the kernel killed it for memory. Nothing in the application log will explain it.
- A pipeline reports the exit status of its LAST command unless
pipefailis set, which is how a failing command piped toteeproduces a green build. - Some tools use non-zero codes for non-failure outcomes. Check the tool documentation before treating any non-zero code as an error.