# unittest-parallel
[](https://pypi.org/project/unittest-parallel/)
[](https://pypi.org/project/unittest-parallel/)
[](https://github.com/craigahobbs/unittest-parallel/blob/main/LICENSE)
[](https://pypi.org/project/unittest-parallel/)
unittest-parallel is a parallel unit test runner for Python with coverage support.
## Run Tests in Parallel
To run tests in parallel with unittest-parallel, specify the directory containing your unit tests
with the `-s` argument and your package's top-level directory using the `-t` argument:
~~~
unittest-parallel -t . -s tests
~~~
By default, unittest-parallel runs tests using all CPU cores.
### Test Coverage
To run tests with coverage, add either the `--coverage` option (for line coverage) or the
`--coverage-branch` for line and branch coverage.
~~~
unittest-parallel -t . -s tests --coverage-branch
~~~
### Parallelism Level
By default, unittest-parallel runs test modules in parallel (`--level=module`). Here is the list of
all parallelism options:
- `--level=module` - Run test modules in parallel (default)
- `--level=class` - Run test classes in parallel. Use this option if you have
[class fixtures](https://docs.python.org/3/library/unittest.html#class-and-module-fixtures).
- `--level=test` - Run individual tests in parallel. Using this option will likely fail if you have any
[class or module fixtures](https://docs.python.org/3/library/unittest.html#class-and-module-fixtures).
## Speedup Potential
Generally speaking, unittest-parallel will run your unit tests faster by a factor of the number of
CPU cores you have, as compared to `unittest discover`.
In other words, if you have 4 CPU cores, unittest-parallel will run your tests 4 times faster. If
you have 8 CPU cores, it will run 8 times faster, and so on.
Note that you may see less benefit from unittest-parallel if your average test duration is short
compared to the underlying cost of parallelization.
### I/O-Bound Tests
If your tests are I/O-bound (e.g., call web services), you may benefit from using a higher number of
test processes (`-j`). In the following case, the I/O-bound tests run 100 times faster.
~~~
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](https://github.com/craigahobbs/unittest-parallel/issues/24) that their tests
ran 20 times faster on their development machine and 6 times faster on their test machine.
[Another user](https://github.com/craigahobbs/unittest-parallel/issues/5) reports that "it shaved
70% off the runtime of my painfully long integration tests."
[Another user](https://github.com/craigahobbs/unittest-parallel/issues/3) 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] [--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 processes (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
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](https://github.com/craigahobbs/python-build#readme).
It was started using [python-template](https://github.com/craigahobbs/python-template#readme) 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
~~~
Raw data
{
"_id": null,
"home_page": "https://github.com/craigahobbs/unittest-parallel",
"name": "unittest-parallel",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "test, unittest, coverage, parallel",
"author": "Craig A. Hobbs",
"author_email": "craigahobbs@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/37/e6/403f321ef147f367353858fc156edd6b9805075cb0cb74838883366f8bb4/unittest_parallel-1.7.5.tar.gz",
"platform": null,
"description": " # unittest-parallel\n\n[](https://pypi.org/project/unittest-parallel/)\n[](https://pypi.org/project/unittest-parallel/)\n[](https://github.com/craigahobbs/unittest-parallel/blob/main/LICENSE)\n[](https://pypi.org/project/unittest-parallel/)\n\nunittest-parallel is a parallel unit test runner for Python with coverage support.\n\n\n## Run Tests in Parallel\n\nTo run tests in parallel with unittest-parallel, specify the directory containing your unit tests\nwith the `-s` argument and your package's top-level directory using the `-t` argument:\n\n~~~\nunittest-parallel -t . -s tests\n~~~\n\nBy default, unittest-parallel runs tests using all CPU cores.\n\n\n### Test Coverage\n\nTo run tests with coverage, add either the `--coverage` option (for line coverage) or the\n`--coverage-branch` for line and branch coverage.\n\n~~~\nunittest-parallel -t . -s tests --coverage-branch\n~~~\n\n\n### Parallelism Level\n\nBy default, unittest-parallel runs test modules in parallel (`--level=module`). Here is the list of\nall parallelism options:\n\n- `--level=module` - Run test modules in parallel (default)\n\n- `--level=class` - Run test classes in parallel. Use this option if you have\n [class fixtures](https://docs.python.org/3/library/unittest.html#class-and-module-fixtures).\n\n- `--level=test` - Run individual tests in parallel. Using this option will likely fail if you have any\n [class or module fixtures](https://docs.python.org/3/library/unittest.html#class-and-module-fixtures).\n\n\n## Speedup Potential\n\nGenerally speaking, unittest-parallel will run your unit tests faster by a factor of the number of\nCPU cores you have, as compared to `unittest discover`.\n\nIn other words, if you have 4 CPU cores, unittest-parallel will run your tests 4 times faster. If\nyou have 8 CPU cores, it will run 8 times faster, and so on.\n\nNote that you may see less benefit from unittest-parallel if your average test duration is short\ncompared to the underlying cost of parallelization.\n\n\n### I/O-Bound Tests\n\nIf your tests are I/O-bound (e.g., call web services), you may benefit from using a higher number of\ntest processes (`-j`). In the following case, the I/O-bound tests run 100 times faster.\n\n~~~\nunittest-parallel -j 100 -t . -s tests\n~~~\n\n\n### Real-World Speedups\n\nI wrote unittest-parallel for a large production backend API application with thousands of unit\ntests. As expected, unittest-parallel ran tests 4 times faster using 4 cores, compared to `unittest\ndiscover`.\n\n[A user reports](https://github.com/craigahobbs/unittest-parallel/issues/24) that their tests\nran 20 times faster on their development machine and 6 times faster on their test machine.\n\n[Another user](https://github.com/craigahobbs/unittest-parallel/issues/5) reports that \"it shaved\n70% off the runtime of my painfully long integration tests.\"\n\n[Another user](https://github.com/craigahobbs/unittest-parallel/issues/3) reports that \"tests take\n2x less times to run.\"\n\n\n## Usage\n\n~~~\nusage: unittest-parallel [-h] [-v] [-q] [-f] [-b] [-k TESTNAMEPATTERNS]\n [-s START] [-p PATTERN] [-t TOP] [--runner RUNNER]\n [--result RESULT] [-j COUNT]\n [--level {module,class,test}]\n [--disable-process-pooling] [--coverage]\n [--coverage-branch] [--coverage-rcfile RCFILE]\n [--coverage-include PAT] [--coverage-omit PAT]\n [--coverage-source SRC] [--coverage-html DIR]\n [--coverage-xml FILE] [--coverage-fail-under MIN]\n\noptions:\n -h, --help show this help message and exit\n -v, --verbose Verbose output\n -q, --quiet Quiet output\n -f, --failfast Stop on first fail or error\n -b, --buffer Buffer stdout and stderr during tests\n -k TESTNAMEPATTERNS Only run tests which match the given substring\n -s, --start-directory START\n Directory to start discovery ('.' default)\n -p, --pattern PATTERN\n Pattern to match tests ('test*.py' default)\n -t, --top-level-directory TOP\n Top level directory of project (defaults to start\n directory)\n --runner RUNNER Custom unittest runner class <module>.<class>\n --result RESULT Custom unittest result class <module>.<class>\n\nparallelization options:\n -j, --jobs COUNT The number of test processes (default is 0, all cores)\n --level {module,class,test}\n Set the test parallelism level (default is 'module')\n --disable-process-pooling\n Do not reuse processes used to run test suites\n\ncoverage options:\n --coverage Run tests with coverage\n --coverage-branch Run tests with branch coverage\n --coverage-rcfile RCFILE\n Specify coverage configuration file\n --coverage-include PAT\n Include only files matching one of these patterns.\n Accepts shell-style (quoted) wildcards.\n --coverage-omit PAT Omit files matching one of these patterns. Accepts\n shell-style (quoted) wildcards.\n --coverage-source SRC\n A list of packages or directories of code to be\n measured\n --coverage-html DIR Generate coverage HTML report\n --coverage-xml FILE Generate coverage XML report\n --coverage-fail-under MIN\n Fail if coverage percentage under min\n~~~\n\n\n## Development\n\nThis package is developed using [python-build](https://github.com/craigahobbs/python-build#readme).\nIt was started using [python-template](https://github.com/craigahobbs/python-template#readme) as follows:\n\n~~~\ntemplate-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\n~~~\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Parallel unit test runner with coverage support",
"version": "1.7.5",
"project_urls": {
"Homepage": "https://github.com/craigahobbs/unittest-parallel"
},
"split_keywords": [
"test",
" unittest",
" coverage",
" parallel"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a73866041cebcd126811e1e0e4de91d6d7b03209e8239b5270922d0dc44ec48c",
"md5": "6ab43f0271635e3ba086253aa159addf",
"sha256": "220ffc562ed18ccaa50d60fcad96d253827c9026b331a2c29bd275e245fd03b5"
},
"downloads": -1,
"filename": "unittest_parallel-1.7.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6ab43f0271635e3ba086253aa159addf",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 9189,
"upload_time": "2025-08-03T18:14:26",
"upload_time_iso_8601": "2025-08-03T18:14:26.875823Z",
"url": "https://files.pythonhosted.org/packages/a7/38/66041cebcd126811e1e0e4de91d6d7b03209e8239b5270922d0dc44ec48c/unittest_parallel-1.7.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "37e6403f321ef147f367353858fc156edd6b9805075cb0cb74838883366f8bb4",
"md5": "a3938be3e63f1a47a00d0b95da4d6c48",
"sha256": "df8cfdd84f0ccf8e9e0fdb34f88d152968fe8460b2c7ed5181cd529231d0fe21"
},
"downloads": -1,
"filename": "unittest_parallel-1.7.5.tar.gz",
"has_sig": false,
"md5_digest": "a3938be3e63f1a47a00d0b95da4d6c48",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 9869,
"upload_time": "2025-08-03T18:14:28",
"upload_time_iso_8601": "2025-08-03T18:14:28.233466Z",
"url": "https://files.pythonhosted.org/packages/37/e6/403f321ef147f367353858fc156edd6b9805075cb0cb74838883366f8bb4/unittest_parallel-1.7.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-03 18:14:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "craigahobbs",
"github_project": "unittest-parallel",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "unittest-parallel"
}