Problem
cibuildwheel runs the test suite from a temporary working directory, and on some platforms that directory lives in an environment the host cannot reach:
- Android: tests run inside an emulator. The host has no access to the emulator's filesystem, so any file the tests produce is lost.
- iOS: tests run inside a simulator. The host can technically reach the simulator's filesystem, but locating and extracting files manually is awkward.
- Linux: tests run inside a Docker/Podman container, so generated files are discarded when the container is torn down.
The practical consequence: on iOS and Android there is currently no way to get coverage information out of a test run at all. Even on Linux it requires platform-specific workarounds.
There is no unified, portable way for a package author to say "after the tests run, give me these files back".
Proposed solution
Add a new option that lists files produced by the test run and has cibuildwheel copy them out of the (sandboxed) test working directory into a directory on the host. Because the test working directory mirrors the project layout (it is populated via test-sources), authors can refer to outputs using the same relative paths they would use when running the tests locally — including on mobile, where {project}/{package} placeholders are not available.
New configuration / CLI options
-
test-outputs (list of paths /globs, like test-sources)
Files to collect from the test working directory after the test command runs. Glob patterns are supported (e.g. .coverage*, **/junit.xml) (Edit: I think globs are hard to implement on e.g. Android or using docker cp, so we should not allow them). If a declared pattern produces no matches, cibuildwheel emits a warning and continues (the artifact is treated as optional).
Env var: CIBW_TEST_OUTPUTS
-
test-output-dir (string, default ./test-outputs)
Where the collected files are written. To avoid collisions, outputs are namespaced per build identifier (e.g. cp312-manylinux_x86_64), since a single cibuildwheel invocation runs the tests many times across Python versions and architectures. A {identifier} placeholder is supported so the layout is configurable; the effective destination is: {test-output-dir}/{identifier}/<relative path of the output file>
Env var: CIBW_TEST_OUTPUT_DIR.
Per-platform implementation
The mechanism differs only in how files leave the sandbox; the option and the resulting on-host layout are identical everywhere.
Native (macOS, Windows) and Pyodide:
The test working directory is on the local filesystem. After the test command finishes (and before the temp dir is cleaned up), copy the matching files into the per-identifier output directory.
Linux (Docker / Podman):
Resolve the patterns inside the container's test working directory and copy each match out to the host (e.g. via docker cp / podman cp) before the container's temp directory is removed.
Android:
I created python/cpython#149271 that allows to copy files back from the Android emulator. Each test outputs entry would be forwarded to the testbed runner as an output argument; cibuildwheel then places the returned files in the per-identifier output directory.
iOS:
The simulator testbed would gain an equivalent output argument (kept in parity with the Android testbed flag), and cibuildwheel wires it up the same way.
Related issues
These issues are requesting similar features but are docker specific. iOS and Android are not mentioned there:
Problem
cibuildwheel runs the test suite from a temporary working directory, and on some platforms that directory lives in an environment the host cannot reach:
The practical consequence: on iOS and Android there is currently no way to get coverage information out of a test run at all. Even on Linux it requires platform-specific workarounds.
There is no unified, portable way for a package author to say "after the tests run, give me these files back".
Proposed solution
Add a new option that lists files produced by the test run and has cibuildwheel copy them out of the (sandboxed) test working directory into a directory on the host. Because the test working directory mirrors the project layout (it is populated via
test-sources), authors can refer to outputs using the same relative paths they would use when running the tests locally — including on mobile, where{project}/{package}placeholders are not available.New configuration / CLI options
test-outputs(list of paths/globs, liketest-sources)Files to collect from the test working directory after the test command runs.
Glob patterns are supported (e.g.(Edit: I think globs are hard to implement on e.g. Android or using.coverage*,**/junit.xml)docker cp, so we should not allow them). If a declared pattern produces no matches, cibuildwheel emits a warning and continues (the artifact is treated as optional).Env var:
CIBW_TEST_OUTPUTStest-output-dir(string, default./test-outputs)Where the collected files are written. To avoid collisions, outputs are namespaced per build identifier (e.g.
cp312-manylinux_x86_64), since a single cibuildwheel invocation runs the tests many times across Python versions and architectures. A{identifier}placeholder is supported so the layout is configurable; the effective destination is:{test-output-dir}/{identifier}/<relative path of the output file>Env var:
CIBW_TEST_OUTPUT_DIR.Per-platform implementation
The mechanism differs only in how files leave the sandbox; the option and the resulting on-host layout are identical everywhere.
Native (macOS, Windows) and Pyodide:
The test working directory is on the local filesystem. After the test command finishes (and before the temp dir is cleaned up), copy the matching files into the per-identifier output directory.
Linux (Docker / Podman):
Resolve the patterns inside the container's test working directory and copy each match out to the host (e.g. via
docker cp/podman cp) before the container's temp directory is removed.Android:
I created python/cpython#149271 that allows to copy files back from the Android emulator. Each
test outputsentry would be forwarded to the testbed runner as an output argument; cibuildwheel then places the returned files in the per-identifier output directory.iOS:
The simulator testbed would gain an equivalent output argument (kept in parity with the Android testbed flag), and cibuildwheel wires it up the same way.
Related issues
These issues are requesting similar features but are docker specific. iOS and Android are not mentioned there:
/outputin case of test failure on docker #1756