pytest Cheatsheet¶
Installation¶
| Plattform | Befehl |
|---|---|
| pip (All platforms) | pip install pytest |
| Ubuntu/Debian | sudo apt install python3-pytest |
| Fedora/RHEL | sudo dnf install python3-pytest |
| Arch Linux | sudo pacman -S python-pytest |
| macOS (Homebrew) | brew install pytest |
| Windows (Chocolatey) | choco install pytest |
| Virtual Environment | python -m venv venv && source venv/bin/activate && pip install pytest |
| With Common Plugins | pip install pytest pytest-cov pytest-xdist pytest-mock pytest-html |
| Verify Installation | pytest --version |
Grundlegende Befehle¶
| Befehl | Beschreibung |
|---|---|
pytest |
Führe alle Tests im aktuellen Verzeichnis und Unterverzeichnissen aus |
pytest test_file.py |
Tests in einer bestimmten Datei ausführen |
pytest tests/ |
Führe alle Tests in einem bestimmten Verzeichnis aus |
pytest test_file.py::test_function |
Führen Sie eine bestimmte Testfunktion aus |
pytest test_file.py::TestClass |
Führen Sie alle Tests in einer bestimmten Klasse aus |
pytest test_file.py::TestClass::test_method |
Führen Sie eine bestimmte Testmethode in einer Klasse aus |
pytest -v |
Tests mit ausführlicher Ausgabe ausführen (Testnamen anzeigen) |
pytest -vv |
Tests mit sehr ausführlicher Ausgabe ausführen (vollständige Details anzeigen) |
pytest -q |
Tests im stillen Modus ausführen (minimale Ausgabe) |
pytest -s |
Zeige Druckanweisungen und stdout während der Testausführung |
pytest -x |
Stopp nach erstem Testfehler |
pytest --maxfail=3 |
Stopp nach N Testfehlern |
pytest -k "test_user" |
Tests ausführen, die dem Schlüsselwortausdruck entsprechen |
pytest -k "user and not admin" |
Tests ausführen, die mehrere Schlüsselwörter erfüllen (UND/NICHT-Logik) |
pytest -m "slow" |
Tests ausführen, die mit einem bestimmten Marker gekennzeichnet sind |
pytest -m "not slow" |
Tests ausführen unter Ausschluss bestimmter Marker |
pytest --collect-only |
Zeige, welche Tests ausgeführt würden, ohne sie tatsächlich auszuführen |
pytest --lf |
Führe nur Tests aus, die im letzten Durchlauf fehlgeschlagen sind (zuletzt fehlgeschlagen) |
pytest --ff |
Führe zuerst fehlgeschlagene Tests aus, dann andere (Fehler zuerst) |
pytest -l |
Lokale Variablen in Tracebacks bei Fehlern anzeigen |
Erweiterte Verwendung¶
| Befehl | Beschreibung |
|---|---|
pytest -n auto |
Tests parallel mit allen verfügbaren CPU-Kernen ausführen (erfordert pytest-xdist) |
pytest -n 4 |
Tests parallel mit 4 Worker-Prozessen ausführen |
pytest --durations=10 |
Zeige die 10 langsamsten Testdauern |
pytest --durations=10 --durations-min=1.0 |
Zeige langsamste Tests, die mindestens 1 Sekunde dauern |
pytest --cov=myproject |
Tests mit Code-Coverage-Bericht ausführen (erfordert pytest-cov) |
pytest --cov=myproject --cov-report=html |
HTML-Coveragereport im htmlcov/-Verzeichnis generieren |
pytest --cov=myproject --cov-report=term-missing |
Zeige Abdeckung mit fehlenden Zeilennummern im Terminal |
pytest --cov=myproject --cov-fail-under=80 |
Fehlschlag, wenn Abdeckung unter 80% liegt |
pytest --cov-branch |
Branch-Coverage-Analyse einbeziehen |
pytest --junitxml=report.xml |
JUnit XML-Bericht für CI/CD-Integration generieren |
pytest --html=report.html |
HTML-Testbericht generieren (erfordert pytest-html) |
pytest --pdb |
In Python-Debugger (PDB) bei Testfehlern einsteigen |
pytest --trace |
In PDB zu Beginn jedes Tests einsteigen |
pytest --setup-show |
Zeige Setup und Teardown von Fixtures während der Ausführung |
pytest --fixtures |
Alle verfügbaren Fixtures und ihre Docstrings auflisten |
pytest --markers |
Alle registrierten Marker auflisten |
pytest --tb=short |
Kürzeres Traceback-Format verwenden |
pytest --tb=line |
Zeige eine Zeile pro Fehler in der Traceback |
pytest --tb=no |
Traceback-Ausgabe deaktivieren |
pytest -W error::DeprecationWarning |
Behandle Deprecation-Warnungen als Fehler |
pytest --capture=no |
Deaktiviere die Ausgabeerfassung (identisch mit -s) |
pytest --timeout=300 |
Setze Timeout auf 300 Sekunden pro Test (erfordert pytest-timeout) |
pytest --count=3 |
Wiederholen Sie jeden Test 3 Mal (erfordert pytest-repeat) |
pytest --random-order |
Tests in zufälliger Reihenfolge ausführen (erfordert pytest-random-order) |
pytest -ra |
Kurze Testergebniszusammenfassung für alle Tests (bestanden, fehlgeschlagen, übersprungen, etc.) |
Konfiguration¶
pytest.ini Konfigurationsdatei¶
Im Projektstammverzeichnis platzieren:
[pytest]
# Minimum pytest version required
minversion = 7.0
# Directories to search for tests
testpaths = tests
# Test file patterns
python_files = test_*.py *_test.py
# Test class patterns
python_classes = Test* *Tests
# Test function patterns
python_functions = test_*
# Default command line options
addopts =
-ra
--strict-markers
--strict-config
--verbose
--cov=myproject
--cov-report=html
--cov-report=term-missing
# Custom markers
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
integration: marks tests as integration tests
unit: marks tests as unit tests
smoke: marks tests as smoke tests
database: marks tests requiring database connection
api: marks tests for API testing
# Directories to ignore
norecursedirs = .git .tox dist build *.egg venv node_modules
# Warning filters
filterwarnings =
error
ignore::UserWarning
ignore::DeprecationWarning
# Logging configuration
log_cli = true
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)s] %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
pyproject.toml Konfiguration¶
Moderne Python-Projekte mit pyproject.toml:
[tool.pytest.ini_options]
minversion = "7.0"
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"-ra",
"--strict-markers",
"--cov=myproject",
"--cov-branch",
"--cov-report=html",
"--cov-report=term-missing:skip-covered",
"--cov-fail-under=80",
]
markers = [
"slow: marks tests as slow",
"integration: integration tests",
"unit: unit tests",
"smoke: smoke tests",
]
filterwarnings = [
"error",
"ignore::UserWarning",
]
conftest.py - Gemeinsame Fixtures¶
Im Stammverzeichnis des Testordners für gemeinsame Fixtures platzieren:
import pytest
# Session-scoped fixture (runs once per test session)
@pytest.fixture(scope="session")
def database():
"""Provide database connection for entire test session"""
db = create_database_connection()
yield db
db.close()
# Module-scoped fixture (runs once per test module)
@pytest.fixture(scope="module")
def api_client():
"""Provide API client for test module"""
client = APIClient()
yield client
client.cleanup()
# Function-scoped fixture (default, runs for each test)
@pytest.fixture
def sample_data():
"""Provide sample data for testing"""
return {"id": 1, "name": "Test User"}
# Autouse fixture (automatically used by all tests)
@pytest.fixture(autouse=True)
def reset_state():
"""Reset application state before each test"""
clear_cache()
yield
cleanup_resources()
# Parametrized fixture
@pytest.fixture(params=["sqlite", "postgres", "mysql"])
def db_type(request):
"""Test with multiple database types"""
return request.param
# Configure pytest hooks
def pytest_configure(config):
"""Add custom configuration"""
config.addinivalue_line(
"markers", "custom: custom marker description"
)
Häufige Anwendungsfälle¶
Anwendungsfall 1: Grundlegende Unittests¶
# Create test file
cat > test_calculator.py << 'EOF'
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
EOF
# Run the tests
pytest test_calculator.py -v
Anwendungsfall 2: Testen mit Fixtures¶
# Create test with fixtures
cat > test_user.py << 'EOF'
import pytest
@pytest.fixture
def user_data():
return {"username": "testuser", "email": "test@example.com"}
def test_user_creation(user_data):
assert user_data["username"] == "testuser"
assert "@" in user_data["email"]
EOF
# Run tests with fixture details
pytest test_user.py -v --setup-show
Anwendungsfall 3: Parametrisierte Tests¶
# Create parametrized tests
cat > test_math.py << 'EOF'
import pytest
@pytest.mark.parametrize("input,expected", [
(2, 4),
(3, 9),
(4, 16),
(5, 25),
])
def test_square(input, expected):
assert input ** 2 == expected
EOF
# Run parametrized tests
pytest test_math.py -v
Anwendungsfall 4: Integrationstests mit Markern¶
# Create tests with markers
cat > test_api.py << 'EOF'
import pytest
@pytest.mark.unit
def test_data_validation():
assert True
@pytest.mark.integration
def test_api_endpoint():
# Simulated API test
assert True
@pytest.mark.slow
@pytest.mark.integration
def test_full_workflow():
# Long-running test
assert True
EOF
# Run only unit tests
pytest test_api.py -m unit -v
# Run integration tests excluding slow ones
pytest test_api.py -m "integration and not slow" -v
Anwendungsfall 5: Generierung von Testabdeckungsberichten¶
# Run tests with coverage and generate reports
pytest --cov=myproject --cov-report=html --cov-report=term-missing
# View coverage report
# HTML report will be in htmlcov/index.html
# Run with coverage threshold
pytest --cov=myproject --cov-fail-under=80
# Generate coverage badge
pytest --cov=myproject --cov-report=term --cov-report=html
Best Practices¶
- Verwenden Sie beschreibende Testnamen: Benennen Sie Tests mit
test_Präfix und beschreiben Sie, was sie testen (z.B.test_user_registration_with_valid_email) - Befolgen Sie das AAA-Muster: Strukturieren Sie Tests mit Arrange (Einrichtung), Act (Ausführung), Assert (Überprüfung) Abschnitten für Klarheit
- Verwenden Sie Fixtures für Setup/Teardown: Nutzen Sie pytest Fixtures anstelle von Setup/Teardown-Methoden für bessere Wiederverwendbarkeit und Dependency Injection
- Markieren Sie Tests entsprechend: Verwenden Sie Marker (
@pytest.mark.slow,@pytest.mark.integration) zum Kategorisieren von Tests und zur selektiven Ausführung - Halten Sie Tests isoliert: Jeder Test sollte unabhängig sein und nicht vom Zustand anderer Tests abhängen; verwenden Sie Fixtures mit geeigneten Geltungsbereichen
- Verwenden Sie Parametrisierung für ähnliche Tests: Anstatt mehrere ähnliche Tests zu schreiben, verwenden Sie
@pytest.mark.parametrizezum Testen mehrerer Eingaben - Konfigurieren Sie pytest.ini oder pyproject.toml: Legen Sie projektweite Standardeinstellungen für Testermittlung, Marker und Befehlszeilenoptionen in Konfigurationsdateien fest
- Schreiben Sie fokussierte Assertionen: Verwenden Sie einfache, klare Assertionen; Die Introspektion von pytest zeigt automatisch detaillierte Fehlerinformationen
- Verwenden Sie conftest.py für gemeinsame Fixtures: Platzieren Sie wiederverwendbare Fixtures in
conftest.pyDateien auf geeigneten Verzeichnisebenen - Führen Sie Tests häufig aus: Führen Sie Tests während der Entwicklung mit
pytest -xaus, um bei der ersten Fehlermeldung zu stoppen und schnelleres Feedback zu erhalten - Überwachen Sie die Testabdeckung: Überprüfen Sie regelmäßig Testabdeckungsberichte und streben Sie eine Abdeckung von 80%+ an, konzentrieren Sie sich aber auf aussagekräftige Tests statt auf Prozentsätze
Fehlerbehebung¶
| Problem | Lösung |
|---|---|
| Tests not discovered | Ensure files match patterns: test_*.py or *_test.py, functions start with test_, classes start with Test |
| Import errors in tests | Add empty __init__.py files in test directories, or install package in editable mode: pip install -e . |
| Fixture not found | Check fixture is defined in same file or conftest.py, verify correct scope, ensure fixture name matches parameter |
| Tests pass locally but fail in CI | Check for environment-specific dependencies, ensure consistent Python versions, verify all dependencies in requirements.txt |
| Slow test execution | Use pytest --durations=10 to identify slow tests, consider parallel execution with pytest -n auto, mark slow tests with @pytest.mark.slow |
| Coverage not working | Install pytest-cov: pip install pytest-cov, ensure source path is correct: --cov=myproject, check .coveragerc configuration |
| Markers not recognized | Register markers in pytest.ini or pyproject.toml under [tool.pytest.ini_options], use --strict-markers to catch typos |
| PDB not working with capture | Use pytest -s --pdb to disable output capturing, or use pytest.set_trace() instead of pdb.set_trace() |
| Fixtures running in wrong order | Check fixture scope (session > module > class > function), use @pytest.fixture(autouse=True) carefully, review dependency chain |
| Parallel tests failing | Stelle sicher, dass Tests isoliert sind und keinen Zustand teilen, prüfe auf Race Conditions, verwende geeignete Sperrungen für gemeinsam genutzte Ressourcen |
| Memory leaks in tests | Use @pytest.fixture(scope="function") for proper cleanup, ensure fixtures yield and cleanup properly, check for circular references |
The translation preserves the markdown formatting, keeps technical terms in English, and maintains the original structure and punctuation.pytest -W ignore::UserWarning |