unittest-parallel
unittest-parallel is a parallel unit test runner for Python with coverage support.
Run Tests in Parallel
Install unittest-parallel from PyPI:
pip install unittest-parallel
unittest-parallel discovers tests like python -m unittest discover. Specify the directory
containing your tests with -s and the project's top-level directory with -t:
unittest-parallel -t . -s tests
By default, unittest-parallel runs tests using all CPU cores.
Test Coverage
To run tests with coverage, add --coverage (line coverage) or --coverage-branch (line and
branch coverage):
unittest-parallel -t . -s tests --coverage-branch
Add --coverage-html DIR or --coverage-xml FILE to write a report, and
--coverage-fail-under MIN to fail the run if coverage is below MIN. Coverage from all
workers is combined, including import-time code executed during discovery.
Parallelism Level
By default, unittest-parallel runs test modules in parallel (--level=module), which works with
class and module fixtures.
The parallelism options are:
-
--level=module- Run test modules in parallel (default). Module fixtures run once per module. -
--level=class- Run test classes in parallel. Class fixtures run once per class. Module fixtures (setUpModule) run once per class and may run concurrently, so use--level=moduleif you have module fixtures. -
--level=test- Run individual tests in parallel. This will likely fail if you have any class or module fixtures.
Process and Thread Pools
By default, unittest-parallel uses a process pool. Worker processes are reused across test suites.
Use --disable-process-pooling to run each suite in a fresh process if suites leak process-global
state.
--thread uses a thread pool instead of a process pool. It works on CPython with the GIL and on
free-threaded Python, but it only
improves performance on free-threaded Python, where threads can run CPU-bound tests on multiple
cores without process-startup overhead.
Do not use --thread with unittest.mock, since mocks patch global state shared by all threads.
-b / --buffer cannot be used with --thread.
Custom Runner and Result
--runner and --result take a class as <module>.<class>.
When --result is set, the result class reports errors itself; unittest-parallel does not reprint
them. When --runner or --result is set, the combined Ran N tests summary is omitted (workers
may still print their own).
Speedup Potential
When you have many independent test modules that take longer to run than the cost of
parallelization, unittest-parallel typically speeds up unittest discover by about the number of
CPU cores. With 4 cores that is about 4 times faster; with 8 cores, about 8 times faster.
If most tests are very short, you may see little speedup, or a slowdown, compared to
unittest discover.
I/O-Bound Tests
If your tests are I/O-bound (for example, they call web services), you may benefit from using more
workers than CPU cores (-j):
unittest-parallel -j 100 -t . -s tests
Real-World Speedups
I wrote unittest-parallel for a large production backend API application with thousands of unit
tests. As expected, unittest-parallel ran tests 4 times faster using 4 cores, compared to unittest discover.
A user reports that their tests ran 20 times faster on their development machine and 6 times faster on their test machine.
Another user reports that "it shaved 70% off the runtime of my painfully long integration tests."
Another user reports that "tests take 2x less times to run."
Usage
usage: unittest-parallel [-h] [-v] [-q] [-f] [-b] [-k TESTNAMEPATTERNS]
[-s START] [-p PATTERN] [-t TOP] [--runner RUNNER]
[--result RESULT] [-j COUNT]
[--level {module,class,test}]
[--disable-process-pooling] [--thread] [--coverage]
[--coverage-branch] [--coverage-rcfile RCFILE]
[--coverage-include PAT] [--coverage-omit PAT]
[--coverage-source SRC] [--coverage-html DIR]
[--coverage-xml FILE] [--coverage-fail-under MIN]
options:
-h, --help show this help message and exit
-v, --verbose Verbose output
-q, --quiet Quiet output
-f, --failfast Stop on first fail or error
-b, --buffer Buffer stdout and stderr during tests
-k TESTNAMEPATTERNS Only run tests which match the given substring
-s, --start-directory START
Directory to start discovery ('.' default)
-p, --pattern PATTERN
Pattern to match tests ('test*.py' default)
-t, --top-level-directory TOP
Top level directory of project (defaults to start
directory)
--runner RUNNER Custom unittest runner class <module>.<class>
--result RESULT Custom unittest result class <module>.<class>
parallelization options:
-j, --jobs COUNT The number of test workers (default is 0, all cores)
--level {module,class,test}
Set the test parallelism level (default is 'module')
--disable-process-pooling
Do not reuse processes used to run test suites
--thread Use a thread pool for parallelization
coverage options:
--coverage Run tests with coverage
--coverage-branch Run tests with branch coverage
--coverage-rcfile RCFILE
Specify coverage configuration file
--coverage-include PAT
Include only files matching one of these patterns.
Accepts shell-style (quoted) wildcards.
--coverage-omit PAT Omit files matching one of these patterns. Accepts
shell-style (quoted) wildcards.
--coverage-source SRC
A list of packages or directories of code to be
measured
--coverage-html DIR Generate coverage HTML report
--coverage-xml FILE Generate coverage XML report
--coverage-fail-under MIN
Fail if coverage percentage under min
Development
This package is developed using python-build. It was started using python-template as follows:
template-specialize python-template/template/ unittest-parallel/ -k package unittest-parallel -k name 'Craig A. Hobbs' -k email 'craigahobbs@gmail.com' -k github 'craigahobbs' -k noapi 1
Metadata
Release files for unittest-parallel 1.8.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unittest_parallel-1.8.6.tar.gz | 11.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unittest_parallel-1.8.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.2 kB
Release files / unittest_parallel-1.8.6.tar.gz
| Download URL | unittest_parallel-1.8.6.tar.gz |
|---|---|
| Size | 11.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
13e304d9a46ce49daa0af7354cb16f86751e0fa45c376aecd9ab379e54d7841d
|
|
BLAKE2b-256 checksum How to use checksums |
2aeaf362b5f240db72f8029273b89af5c59217a3c1c9ee71d937e6ea7f5b274c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / unittest_parallel-1.8.6-py3-none-any.whl
| Download URL | unittest_parallel-1.8.6-py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f04b0ada502f6b3d655ef49ea2a785f0e37869f9d0ce7a075c1a18ec204ac93
|
|
BLAKE2b-256 checksum How to use checksums |
454c8d1732d73eb2399f1e5a5097ae30dbdf85da12c2da6d0135b22748333fe9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|