ZOPE.TESTRUNNER(1)

๐Ÿ“ฆ
version 8.3 ยท 6 versions
, in fedora 44

ZOPE.TESTRUNNER(1) โ€” bestie, welcome to the manual page for zope.testrunner, aka the Zope testrunner script. It's giving โœจtest runner eraโœจ and we're about to get into every single detail. No cap. ๐Ÿ’…

โœจ NAME โœจ

zope.testrunner โ€” the Zope testrunner script. That's the whole name, and honestly it's iconic. ๐ŸŽ€

๐Ÿ’– DESCRIPTION ๐Ÿ’–

Okay so first things first, here's the usage vibe:

usage: zope-testrunner [-h] [--package PACKAGE] [--module MODULE]
       [--test TEST] [--unit] [--non-unit] [--layer LAYER]
              [-a AT_LEVEL] [--all] [--only-level ONLY_LEVEL] [--list-tests]
              [--require-unique] [--verbose] [--quiet] [--progress]
              [--no-progress] [--auto-progress] [--color] [--no-color]
              [--auto-color] [--subunit] [--subunit-v2] [--slow-test N] [-1]
              [--show-secondary-failures] [--ndiff] [--udiff] [--cdiff]
              [--ignore-new-thread REGEXP] [--buffer] [--xml XMLOUTPUT]
              [--stop-on-error] [--post-mortem] [--gc GC] [--gc-option
              {DEBUG_STATS,DEBUG_INSTANCES,DEBUG_OBJECTS,DEBUG_COLLECTABLE,DEBUG_UNCOLLECTABLE,DEBUG_SAVEALL,DEBUG_LEAK}]
              [--gc-after-test] [--repeat REPEAT] [--report-refcounts]
              [--coverage COVERAGE] [--profile {cProfile}] [--profile-directory
              PROF_DIR] [--path PATH] [--test-path TEST_PATH] [--package-path
              ARG ARG] [--auto-path] [--tests-pattern TESTS_PATTERN]
              [--suite-name SUITE_NAME] [--test-file-pattern TEST_FILE_PATTERN]
              [--ignore_dir IGNORE_DIR] [--shuffle] [--shuffle-seed
              SHUFFLE_SEED] [--version] [-j PROCESSES] [--keepbytecode]
              [--usecompiled] [--exit-with-status] [legacy_module_filter]
              [legacy_test_filter]

So what does it do? It discovers and runs unittest tests. That's the main character energy right there. ๐Ÿงชโœจ

๐ŸŒธ positional arguments: ๐ŸŒธ

  • legacy_module_filter โ€” DEPRECATED: Prefer to use --module. (Like, it still works but bestie, use the new thing. ๐Ÿ’€)
  • legacy_test_filter โ€” DEPRECATED: Prefer to use --test. (Same energy, just use --test instead. ๐Ÿ™ˆ)

๐ŸŽ€ options: ๐ŸŽ€

  • -h, --help โ€” show this help message and exit. (The classic "help me help you" moment. ๐Ÿซถ)

๐Ÿ” Searching and filtering: ๐Ÿ”

Options in this group are used to define which tests to run. It's the vibe check for your test suite. ๐Ÿ’…

  • --package, --dir, -s PACKAGE โ€” Search the given package's directories for tests. This can be specified more than once to run tests in multiple parts of the source tree. For example, if refactoring interfaces, you don't want to see the way you have broken setups for tests in other packages. You just want to run the interface tests. Packages are supplied as dotted names. For compatibility with the old test runner, forward and backward slashes in package names are converted to dots. (In the special case of packages spread over multiple directories, only directories within the test search path are searched. See the --path option.) So specific, so slay. ๐ŸŽฏ
  • --module, -m MODULE โ€” Specify a test-module filter as a regular expression. This is a case-sensitive regular expression, used in search (not match) mode, to limit which test modules are searched for tests. The regular expressions are checked against dotted module names. In an extension of Python regexp notation, a leading ! is stripped and causes the sense of the remaining regexp to be negated (so !bc matches any string that does not match bc, and vice versa). The option can be specified multiple test-module filters. Test modules matching any of the test filters are searched. If no test-module filter is specified, then all test modules are used. Regex girlies rise up. ๐Ÿ”ฅ
  • --test, -t TEST โ€” Specify a test filter as a regular expression. This is a case-sensitive regular expression, used in search (not match) mode, to limit which tests are run. In an extension of Python regexp notation, a leading ! is stripped and causes the sense of the remaining regexp to be negated (so !bc matches any string that does not match bc, and vice versa). The option can be specified multiple test filters. Tests matching any of the test filters are included. If no test filter is specified, then all tests are run. Filtering? Obsessed. ๐ŸŒธ
  • --unit, -u โ€” Run only unit tests, ignoring any layer options. Unit tests only, periodt. ๐Ÿ’…
  • --non-unit, -f โ€” Run tests other than unit tests. Not like other tests. ๐Ÿ˜Œ
  • --layer LAYER โ€” Specify a test layer to run. The option can be given multiple times to specify more than one layer. If not specified, all layers are run. It is common for the running script to provide default values for this option. Layers are specified regular expressions, used in search mode, for dotted names of objects that define a layer. In an extension of Python regexp notation, a leading ! is stripped and causes the sense of the remaining regexp to be negated (so !bc matches any string that does not match bc, and vice versa). The layer named zope.testrunner.layer.UnitTests is reserved for unit tests, however, take note of the --unit and non-unit options. Layer cake, but make it tests. ๐Ÿฐ
  • -a, --at-level AT_LEVEL โ€” Run the tests at the given level. Any test at a level at or below this is run, any test at a level above this is not run. Level <= 0 runs all tests. Level up, but for tests. ๐ŸŽฎ
  • --all โ€” Run tests at all levels. All the levels, all the vibes. ๐ŸŒˆ
  • --only-level ONLY_LEVEL โ€” Run only the tests at the given level. Tests on other levels are not run. Default is None, which means the level is not restricted by this option. If this option is used it overrides --at-level and --all options. Only level? Main character choice. ๐Ÿ‘‘
  • --list-tests โ€” List all tests that matched your filters. Do not run any tests. Just window shopping, no buying. ๐Ÿ›๏ธ
  • --require-unique โ€” Require that all test IDs be unique and raise an error if duplicates are encountered. No duplicates allowed, bestie. ๐Ÿšซ
  • --auto-path โ€” Automatically add path of --package to the test paths. Auto-magic path vibes. โœจ

๐Ÿ“Š Reporting: ๐Ÿ“Š

Reporting options control basic aspects of test-runner output. It's giving receipts. ๐Ÿงพ

  • --verbose, -v โ€” Make output more verbose. Increment the verbosity level. Tell me everything, I'm nosy. ๐Ÿ‘€
  • --quiet, -q โ€” Make the output minimal, overriding any verbosity options. Shhh, minimal era. ๐Ÿคซ
  • --progress, -p โ€” Output progress status. We love a progress moment. ๐Ÿ“ˆ
  • --no-progress โ€” Do not output progress status. This is the default, but can be used to counter a previous use of --progress or -p. No progress, just vibes. ๐Ÿšซ๐Ÿ“ˆ
  • --auto-progress โ€” Output progress status, but only when stdout is a terminal. Smart progress, only when it makes sense. ๐Ÿง 
  • --color, -c โ€” Colorize the output. Color? Say less. ๐ŸŒˆ
  • --no-color, -C โ€” Do not colorize the output. This is the default, but can be used to counter a previous use of --color or -c. No color, just plain text realness. โšช
  • --auto-color โ€” Colorize the output, but only when stdout is a terminal. Auto-color, because we're efficient. ๐ŸŽจ
  • --subunit โ€” Use subunit v1 output. Will not be colorized. Subunit v1, no color, all business. ๐Ÿ’ผ
  • --subunit-v2 โ€” Use subunit v2 output. Will not be colorized. Subunit v2, still no color. ๐Ÿ’…
  • --slow-test N โ€” With -c and -vvv, highlight tests that take longer than N seconds (default: 10). Slow tests get called out. ๐Ÿข
  • -1, --hide-secondary-failures โ€” Report only the first failure in a doctest. (Examples after the failure are still executed, in case they do any cleanup.) First failure only, but cleanup still happens. ๐Ÿงน
  • --show-secondary-failures โ€” Report all failures in a doctest. This is the default, but can be used to counter a default use of -1 or --hide-secondary-failures. Show me everything, I can handle it. ๐Ÿ’ช
  • --ndiff โ€” When there is a doctest failure, show it as a diff using the ndiff.py utility. Diff it like it's hot. ๐Ÿ”ฅ
  • --udiff โ€” When there is a doctest failure, show it as a unified diff. Unified diff, unified vibe. ๐Ÿค
  • --cdiff โ€” When there is a doctest failure, show it as a context diff. Context diff, context queen. ๐Ÿ‘‘
  • --ignore-new-thread REGEXP โ€” If a thread with this name is left behind, don't report this at the end. This is a case-sensitive regular expression, used in match mode. This option can be used multiple times. If a thread name matches any of them, it will be ignored. Ignore those leftover threads, we don't need the drama. ๐Ÿงต๐Ÿšซ
  • --buffer โ€” Buffer the standard output and standard error streams during each test. Output during a passing test is discarded. Output during failing or erroring tests is echoed. This option is enabled by default if --subunit or --subunit-v2 is in use, to avoid corrupting the subunit stream. Buffer it, but only for the messy ones. ๐Ÿงบ
  • --xml XMLOUTPUT โ€” If given, XML reports will be written to the specified directory. XML reports? Fancy. ๐Ÿ“„

๐Ÿ”ฌ Analysis: ๐Ÿ”ฌ

Analysis options provide tools for analysing test output. Let's investigate. ๐Ÿ•ต๏ธโ€โ™€๏ธ

  • --stop-on-error, --stop, -x โ€” Stop running tests after first test failure or error. Stop the presses, we have a failure. ๐Ÿ›‘
  • --post-mortem, --pdb, -D โ€” Enable post-mortem debugging of test failures. Post-mortem debugging, the ultimate detective work. ๐Ÿ”
  • --gc, -g GC โ€” Set the garbage collector generation threshold. This can be used to stress memory and gc correctness. Some crashes are only reproducible when the threshold is set to 1 (aggressive garbage collection). Do "--gc 0" to disable garbage collection altogether. The --gc option can be used up to 3 times to specify up to 3 of the 3 Python gc_threshold settings. GC stress test? We love a challenge. ๐Ÿ—‘๏ธ
  • --gc-option, -G {DEBUG_STATS,DEBUG_INSTANCES,DEBUG_OBJECTS,DEBUG_COLLECTABLE,DEBUG_UNCOLLECTABLE,DEBUG_SAVEALL,DEBUG_LEAK} โ€” Set a Python gc-module debug flag. This option can be used more than once to set multiple flags. Debug flags, collect them all. ๐Ÿ†
  • --gc-after-test โ€” After each test, call gc.collect and record the return value rv; when rv is non-zero, output ! on verbosity level 1 and [*rv*] on higher verbosity levels. On verbosity level 4 or higher output detailed cycle information. GC after every test? That's dedication. ๐Ÿ’ช
  • --repeat, -N REPEAT โ€” Repeat the tests the given number of times. This option is used to make sure that tests leave their environment in the state they found it and, with the --report-refcounts option to look for memory leaks. Repeat after me: tests should clean up after themselves. ๐Ÿ”
  • --report-refcounts, -r โ€” After each run of the tests, output a report summarizing changes in refcounts by object type. This option that requires that Python was built with the --with-pydebug option to configure. Refcounts report, for the memory detectives. ๐Ÿ•ต๏ธโ€โ™€๏ธ
  • --coverage COVERAGE โ€” Perform code-coverage analysis, saving trace data to the directory with the given name. A code coverage summary is printed to standard out. Coverage? We love to see it. ๐Ÿ“Š
  • --profile {cProfile} โ€” Run the tests under cProfiler and display the top 50 stats, sorted by cumulative time and number of calls. Profile it, top 50, sorted by time and calls. ๐Ÿ“ˆ
  • --profile-directory PROF_DIR โ€” Directory for temporary profiler files. All files named tests_profile.*.prof in this directory will be removed. If you intend to run multiple instances of the test runner in parallel, be sure to tell them to use different directories, so they won't step on each other's toes. Keep your profiler files separate, bestie. ๐Ÿ“

๐Ÿ›  Setup: ๐Ÿ› 

Setup options are normally supplied by the testrunner script, although they can be overridden by users. Setup era, but make it customizable. โœจ

  • --path PATH โ€” bestie, this drops a path right into Python's search path ๐Ÿ’…. You can hit this option over and over again if you've got multiple search paths to add โ€” it stacks, no cap. Usually it's the test-runner script itself that sets this, not you, but you can override it if you want to be the main character. Heads up though: only tests found in that path actually get run. This one also tells the runner which directories to go hunting in for tests, so peep the search_directory for the whole lore.
  • --test-path TEST_PATH โ€” same energy as above but with one little twist: this path gets searched for tests, but it does NOT get added to the Python search path ๐Ÿ™ˆ. Stackable, multiple times, multiple paths, iconic. Again, normally the test-runner script handles this rather than you, but user override is allowed. And yeah โ€” only tests found in the path will run. Periodt.
  • --package-path ARG ARG โ€” okay so this one is for when a path should be searched for tests but NOT added to the Python search path, plus you also declare which package the files in that path belong to ๐ŸŽ€. It's how we deal with directories that are stitched into packages that aren't otherwise being searched for tests. It takes 2 arguments: the path and the package. Use it multiple times for multiple search paths. The script usually specifies it, users can override, and yep โ€” only tests found in the path get run. Three-for-three on that rule, iykyk.
  • --tests-pattern TESTS_PATTERN โ€” the runner is out here looking for modules that contain tests, and this pattern is how it recognizes them ๐Ÿ‘‘. Those modules can be either packages or plain python files. And if a test module is a package, it switches to the value given by the test-file-pattern to figure out which python files inside the package contain tests. Cute little tag-team, honestly.
  • --suite-name SUITE_NAME โ€” tells the runner the name of the object inside each test_module that holds that module's test suite ๐ŸŒธ.
  • --test-file-pattern TEST_FILE_PATTERN โ€” the pattern for spotting python files inside a tests package ๐Ÿฆ‹. See the docs for the --tests-pattern option, they're literally in the same friend group.
  • --ignore_dir IGNORE_DIR โ€” names a directory to skip entirely when looking for tests ๐Ÿ’€. Not today, directory.
  • --shuffle โ€” shuffles the order the tests are ran in ๐Ÿ”€. Chaos, but make it productive.
  • --shuffle-seed SHUFFLE_SEED โ€” the value used to initialize the tests shuffler โœจ. Set a value and you get repeatable random-ordered tests โ€” same chaos every time, which is honestly so valid for debugging.

โœจ Other: Other options โœจ

Okay the original literally just says "Other options" here so that's the vibe, moving on ๐Ÿซถ

  • --version โ€” prints the version of the testrunner and dips out ๐Ÿ‘‹.
  • -j PROCESSES โ€” use up to that many parallel processes to execute tests ๐Ÿ”ฅ. Can decrease test run time substantially, fr fr. Defaults to 1.
  • --keepbytecode, -k โ€” normally the test runner scans the test paths and test directories, hunting for and deleting pyc or pyo files that don't have a corresponding py file ๐Ÿ˜ญ. Why? To prevent spurious test failures from finding compiled modules where the source modules got deleted. The catch: that scan can be time consuming. This option disables the scan entirely. If you know you haven't removed any modules since the last test run, this can make the test run go much faster ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ.
  • --usecompiled โ€” normally a package has to contain an __init__.py file, and only .py files can contain test code. With this option, compiled Python files (.pyc and .pyo) are allowed instead ๐Ÿงš: a directory containing __init__.pyc or __init__.pyo also counts as a package, and if file XYZ.py contains tests but is absent while XYZ.pyc or XYZ.pyo exists, then the compiled files get used. This is necessary when running tests against a tree where the .py files have been removed after compilation to .pyc/.pyo. Use of this option implies --keepbytecode โญ.
  • --exit-with-status โ€” DEPRECATED ๐Ÿšจ the test runner will always exit with a status. That's it, that's the whole thing, it's giving legacy.

okay that's a wrap bestie ๐Ÿ’– this was zope.testrunner version 8.3, dated August 2026, page ZOPE.TESTRUNNER(1) โ€” go run some tests and slay, mwah ๐ŸŽ€โœจ
๐Ÿ“ฆ where this page comes from