stestr: Parallel Python Test Runner
stestr is a parallel Python test runner built around the `subunit` stream protocol. It provides a robust command-line interface for discovering, running, and managing tests, designed to efficiently handle large test suites and integrate well into continuous integration pipelines. The current version is 4.2.1, with minor and patch releases occurring every few months to enhance compatibility and add features.
Common errors
-
stestr: error: argument --repository-type: invalid choice: 'sql' (choose from 'file')
cause You are attempting to use the 'sql' repository type, which was removed in stestr 4.0.0.fixRemove the `--repository-type=sql` flag from your stestr commands or configuration. stestr now only supports the 'file' repository type by default. If you need SQL storage, use `subunit2sql` separately. -
stestr init: error: No test files found in /path/to/repo
cause stestr could not locate any test files based on its default discovery rules or the specified configuration.fixEnsure you have a `setup.cfg` (or `pyproject.toml` or `tox.ini`) with a `[stestr]` section correctly defining `test_path` and `test_file_prefix` to point to your test files. For example: ```ini [stestr] test_path = tests test_file_prefix = test_ ``` Also, ensure the test files exist and follow the naming convention. -
Tests are skipped, not run, or run in an unexpected order without a clear error message.
cause This behavior was a known bug in stestr versions prior to 4.0.1, specifically affecting the `unittest` runner.fixUpgrade to stestr 4.0.1 or later (`pip install --upgrade stestr`) to fix issues with unittest discovery and execution. -
Test results show 'inprogress' indefinitely, or a test worker crashes without reporting failure status.
cause Older stestr versions (before 3.2.1) had issues with detecting and reporting failures from test workers that exited unexpectedly (e.g., due to segfaults).fixUpgrade to stestr 3.2.1 or later (`pip install --upgrade stestr`) to ensure proper detection and reporting of test worker failures.
Warnings
- breaking The 'sql' repository type, and all associated CLI flags and Python API calls for selecting it, have been completely removed in stestr 4.0.0. This was previously deprecated in 3.2.0.
- gotcha Before stestr 4.0.1, the `unittest` runner could exhibit issues where requested tests were unexpectedly skipped, not run, or executed in an incorrect order, leading to difficult-to-debug failures.
- gotcha Prior to stestr 3.2.1, test worker failures (e.g., segfaults or abrupt process exits) might not have been properly detected or reported, potentially leaving tests in an 'inprogress' state indefinitely.
- gotcha stestr 4.1.0 introduced compatibility fixes for `subunit 1.4.3`. Older stestr versions might encounter issues when used with newer `subunit` releases, particularly with output parsing or stream handling.
- gotcha stestr now supports configuring options via `pyproject.toml` (since 4.1.0) and `tox.ini` (since 3.2.0), in addition to the traditional `.stestr.conf`. This can lead to configuration inconsistencies if multiple methods are used simultaneously.
Install
-
pip install stestr
Quickstart
import os
import subprocess
import shutil
import tempfile
# Create a temporary directory for demonstration
temp_dir = tempfile.mkdtemp()
current_dir = os.getcwd()
os.chdir(temp_dir)
try:
# 1. Create a 'tests' directory
os.makedirs("tests")
# 2. Create a simple unittest file
test_code = """
import unittest
class ExampleTests(unittest.TestCase):
def test_success(self):
self.assertTrue(True)
def test_failure(self):
self.assertFalse(False, "This test is designed to fail.")
def test_another_success(self):
self.assertEqual(2 + 2, 4)
"""
with open("tests/test_my_app.py", "w") as f:
f.write(test_code)
# 3. Create a stestr configuration file (e.g., setup.cfg or .stestr.conf)
# Using setup.cfg for modern compatibility
config_code = """
[stestr]
test_path = tests
test_file_prefix = test_
"""
with open("setup.cfg", "w") as f:
f.write(config_code)
print(f"Working directory: {os.getcwd()}")
print("\n--- Initializing stestr repository ---")
subprocess.run(["stestr", "init"], check=True)
print("\n--- Running tests with stestr ---")
result = subprocess.run(["stestr", "run"], capture_output=True, text=True)
print(result.stdout)
if result.stderr:
print("STDERR:")
print(result.stderr)
if result.returncode != 0:
print("\nNote: stestr run reported failures (expected for demonstration).")
else:
print("\nstestr run completed successfully.")
except subprocess.CalledProcessError as e:
print(f"Error: stestr command failed. Command: {' '.join(e.cmd)}")
print(f"Stdout: {e.stdout}")
print(f"Stderr: {e.stderr}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
os.chdir(current_dir)
shutil.rmtree(temp_dir)
print(f"\nCleaned up temporary directory: {temp_dir}")