The pytest-pyspec plugin transforms pytest output into a beautiful, readable format similar to RSpec. It provides semantic meaning to your tests by organizing them into descriptive hierarchies, using the prefixes Describe/Test, With/Without/When, and test_/it_, while allowing docstrings and decorators to override the descriptions.
- Semantic Output: Transform pytest's default output into readable, hierarchical descriptions
- Multiple Prefixes: Support for
describe/test(objects),with/without/when(contexts), andit/test(tests) - Docstring Support: Override test descriptions using docstrings
- Consolidated Output: Smart grouping that avoids repeating parent headers
- Natural Language: Automatic lowercase formatting of common words (the, is, are, etc.)
- Decorator Support: Override descriptions right next to your classes and tests
pip install pytest pytest-pyspecpytest --pyspecA minimal car example with properties and behaviors:
class DescribeCar:
def test_has_engine(self):
assert True
class WithFullTank:
def test_drive_long_distance(self):
assert True
class WithoutFuel:
def test_cannot_start_engine(self):
assert True
class WhenTheEngineIsRunning:
def test_consumes_fuel(self):
assert TrueWith pytest-pyspec, this produces:
a Car
✓ has engine
with Full Tank
✓ drive long distance
without Fuel
✓ cannot start engine
when the Engine is Running
✓ consumes fuel
pytest-pyspec supports three types of prefixes to create semantic test hierarchies:
Define what you're testing:
class DescribeCar: # or class TestCar:
def test_has_four_wheels(self):
assert TrueOutput:
a Car
✓ has four wheels
Define the context or state:
class DescribeCar:
class WithFullTank:
def test_can_drive_long_distances(self):
assert True
class WithoutFuel:
def test_cannot_start_engine(self):
assert True
class WhenTheEngineIsRunning:
def test_consumes_fuel(self):
assert TrueOutput:
a Car
with Full Tank
✓ can drive long distances
without Fuel
✓ cannot start engine
when the Engine is Running
✓ consumes fuel
Define the expected behavior:
class DescribeCar:
def it_has_four_wheels(self):
assert True
def test_has_engine(self):
assert TrueOutput:
a Car
✓ has four wheels
✓ has engine
Override automatic naming with custom descriptions:
class TestCar:
"""sports car"""
def test_top_speed(self):
"""reaches 200 mph"""
assert True
class WhenTheNitroIsActivated:
"""when nitro boost is activated"""
def test_acceleration(self):
"""accelerates rapidly"""
assert TrueOutput:
a sports car
✓ reaches 200 mph
when nitro boost is activated
✓ accelerates rapidly
Prefer decorators over docstrings? Import the helpers directly from pytest_pyspec:
import pytest_pyspec as spec
@spec.describe("Car")
class DescribeCar:
@spec.it("reaches 200 mph")
def test_top_speed(self):
assert True
@spec.when("nitro boost is activated")
class WhenTheNitroIsActivated:
@spec.it("accelerates rapidly")
def test_acceleration(self):
assert TrueOutput:
a Car
✓ reaches 200 mph
when nitro boost is activated
✓ accelerates rapidly
You can also import individual helpers (describe, with_, without, when,
it) directly from pytest_pyspec if you prefer from ... import ... style.
with is still exposed as with_ because the plain name is reserved.
Decorators always win when both a docstring and a decorator are present, so you can keep docstrings for documentation/IDE help while letting decorators drive runtime output.
The plugin is automatically enabled when you use the --pyspec flag. No additional configuration is required.
For more information, see the documentation.