Pytest plugin to collect code coverage from applications running inside Docker containers
Project description
pytest-cov-container
Collect code coverage from Python applications running inside Docker containers during integration tests. Works alongside pytest-cov to combine container coverage with your local test coverage.
Built for projects using AWS SAM local testing, but works with any Docker-based test workflow.
How It Works
- Before tests — moves your
<build_dir>/run.shaside to_orig_run.sh, then injects a coverage wrapper,.coveragerc, and a shimrun.shthat exec's the wrapper. The wrapper invokes your unmodified_orig_run.shundercoverage. Your production entrypoint is the test entrypoint by construction — no duplicate command string to drift. - During tests — your containerized app runs under
coveragevia the injected wrapper, which forwardsSIGTERMto your app on container shutdown so coverage data is saved cleanly. - After tests — extracts
.coverage.*files from containers and runscoverage combineto merge them with local results.
Installation
pip install pytest-cov-container
Requires Python 3.11+.
Configuration
Add to your pyproject.toml:
[tool.pytest-cov-container]
image_pattern = "samcli/lambda*"
label = "pytest-cov-container"
[tool.pytest-cov-container.path_mapping]
"src/api" = "/var/task"
[tool.pytest-cov-container.python]
build_dir = ".aws-sam/build/ApiFunction"
| Key | Description |
|---|---|
image_pattern |
Glob pattern to match container image tags |
label |
Docker label to filter containers |
path_mapping |
Maps host source paths to container paths (used by coverage combine) |
build_dir |
SAM build output directory where coverage files are injected |
entrypoint |
Override (discouraged). Replace convention-discovered <build_dir>/run.sh with this command via sh -c. Drift between this string and prod run.sh is the bug class this plugin's default path eliminates. Omit the field to use convention discovery. Setting to the empty string raises a load-time error. |
language |
Language driver to use (default: "python") |
enabled |
Set to false to disable (default: true) |
Default Path: Convention Discovery
The plugin reads your existing <build_dir>/run.sh (whatever sam build produced) and arranges for coverage to wrap it. Requirements:
<build_dir>/run.shmust exist aftersam build.- Your build_dir must include the
coveragepackage as an installed dependency (the plugin checks for acoverage*.pthfile under anysite-packagesdirectory belowbuild_dir). This is what enables subprocess coverage attach.
If either precondition fails, inject() raises with a migration hint.
Usage
Run your tests with --cov as usual:
pytest --cov=src/api tests/
The plugin activates automatically when:
- pytest-cov is active (
--covflag present) [tool.pytest-cov-container]is configured inpyproject.toml
Disable it for a run with:
pytest --cov=src/api --no-cov-container tests/
Mid-Session Collection
If you need to collect coverage before containers stop (e.g., in a session-scoped fixture teardown), use the public API:
from pytest_cov_container import collect_container_coverage
@pytest.fixture(scope="session")
def sam_api():
proc = start_sam(...)
yield SAM_URL
collect_container_coverage()
proc.terminate()
This sends SIGUSR1 to running containers to flush coverage data, then extracts the files.
Pluggable Drivers
Language support is pluggable via entry points. The built-in Python driver handles:
- Moving your
<build_dir>/run.shaside to_orig_run.sh(mode preserved, idempotent across re-runs) - Writing
.coveragercwithparallel = trueandsigterm = true - Writing
_cov_wrapper.pythat starts coverage, splitsSIGUSR1/SIGTERMhandling (save-only vs save+forward), forwardsSIGTERMto the child process so the runtime grace period saves cleanly, and invokes your unmodified_orig_run.sh - Writing a shim
run.shthat exec's the wrapper - Extracting
.coverage.*files from/tmpin containers
To add a driver for another language, register an entry point:
[project.entry-points."pytest_cov_container.drivers"]
node = "my_package.drivers.node:NodeDriver"
Drivers must implement the LanguageDriver protocol from pytest_cov_container.models.
Development
# Run tests
hatch test
# Run across all Python versions
hatch test --all
# Format and lint
hatch fmt
# Type check
hatch run types:check
# Security scan
hatch run security:scan
# Cut a release. Pass a version literal or a hatch segment (`patch`,
# `minor`, `major`, `rc`, etc.) to bump + tag + push in one shot.
# Omit the arg to release whatever __about__.py currently has.
hatch run release patch # 0.2.0 → 0.2.1
hatch run release minor # 0.2.0 → 0.3.0
hatch run release 0.3.5 # explicit
hatch run release # use current version
License
pytest-cov-container is distributed under the terms of the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_cov_container-0.2.0.tar.gz.
File metadata
- Download URL: pytest_cov_container-0.2.0.tar.gz
- Upload date:
- Size: 72.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48b7beffe2aefd90dfc2e4170e01da8e41c2d11b05a0db421a400a378ce8dbe1
|
|
| MD5 |
08c8284ebfe31f628ca4701db67d70f5
|
|
| BLAKE2b-256 |
447ca26d9bf962a91433fdd311e4c36e66bc029a2fe061698e7eb720e7599e61
|
Provenance
The following attestation bundles were made for pytest_cov_container-0.2.0.tar.gz:
Publisher:
release.yaml on tomaDev/pytest-cov-container
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_cov_container-0.2.0.tar.gz -
Subject digest:
48b7beffe2aefd90dfc2e4170e01da8e41c2d11b05a0db421a400a378ce8dbe1 - Sigstore transparency entry: 1548703953
- Sigstore integration time:
-
Permalink:
tomaDev/pytest-cov-container@6eb8ff822ebe7b98b564cdeff435075d3b1fe46d -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/tomaDev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@6eb8ff822ebe7b98b564cdeff435075d3b1fe46d -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytest_cov_container-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pytest_cov_container-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8eef3d97b1b403ee7034fcb9d7a53fa953409ec56623699cce22d9003d15697
|
|
| MD5 |
4799999de60f06829353a1b8ea94aa0d
|
|
| BLAKE2b-256 |
6d4683aaa25685a3328f81f852f8fa4dc5d4b5ecb2f5f98b7703113b68832cd8
|
Provenance
The following attestation bundles were made for pytest_cov_container-0.2.0-py3-none-any.whl:
Publisher:
release.yaml on tomaDev/pytest-cov-container
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_cov_container-0.2.0-py3-none-any.whl -
Subject digest:
e8eef3d97b1b403ee7034fcb9d7a53fa953409ec56623699cce22d9003d15697 - Sigstore transparency entry: 1548703979
- Sigstore integration time:
-
Permalink:
tomaDev/pytest-cov-container@6eb8ff822ebe7b98b564cdeff435075d3b1fe46d -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/tomaDev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@6eb8ff822ebe7b98b564cdeff435075d3b1fe46d -
Trigger Event:
push
-
Statement type: