Vai al contenuto

HTML_TAG_97_📋 Copia Tutti i comandi pioppo_HTML_TAG_98_ __HTML_TAG_99_📄 Genera il testo PDF Guida_HTML_TAG_100_

pytest Cheatsheet

Installazione

Tabella_103_

Comandi di base

Tabella_104_

Uso avanzato

Tabella_105_

Configurazione

pytest.ini File di configurazione

Luogo nella directory radice del progetto:

[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 Configurazione

Progetti Python moderni che utilizzano 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. piy - Fissaggio condiviso

Posizionare nella directory di test root per gli apparecchi condivisi:

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"
    )

Common Use Cases

Use Case 1: Basic Unit Testing

# 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

Use Case 2: Testing with 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

Use Case 3: Test parametrizzati

# 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

Use Case 4: Test di integrazione con marcatori

# 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

Use Case 5: Coverage Report Generation

# 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

Migliori Pratiche

  • Utilizzare i nomi dei test descrittivi: test dei nomi con prefisso test_ e descrivere ciò che essi provano (ad esempio test_user_registration_with_valid_email)
  • Follow AAA pattern: Test struttura con Arrange (setup), Act (execute), Assert (verificare) sezioni per chiarezza
  • Utilizzare i dispositivi per il setup/teardown: Apparecchiature piatte di levaggio invece dei metodi di setup/teardown per una migliore riutilizzabilità e iniezione di dipendenza
  • I test di marzo rettamente Utilizzare i marcatori (INLINE_CODE_64__, @pytest.mark.integration) per classificare i test e abilitare l'esecuzione selettiva
  • I test sono isolati. Ogni test dovrebbe essere indipendente e non fare affidamento sullo stato da altri test; utilizzare dispositivi con scopi appropriati
  • Utilizzare parametrizzazioni per test simili: Invece di scrivere più test simili, utilizzare @pytest.mark.parametrize per testare più ingressi
  • Configura pytest.ini o pyproject. Toml: Impostare i default a livello di progetto per la scoperta di test, marcatori e opzioni di riga di comando nei file di configurazione
  • **Asserzioni focalizzate sulla scrittura ** Utilizzare affermazioni semplici e chiare; l'introspezione di pitest mostra automaticamente informazioni di guasto dettagliate
  • ** Utilizzare conftest.py per apparecchi condivisi**: Posizionare i dispositivi riutilizzabili in file conftest.py a livelli di directory appropriati
  • **I test ripetuti ** Eseguire i test durante lo sviluppo con pytest -x per arrestarsi al primo fallimento per un feedback più veloce
  • ** Copertura del test del motorino ** Controlla regolarmente i report di copertura e mira alla copertura 80%+, ma concentrati sui test significativi sulla percentuale

Risoluzione dei problemi

Traduzione: ** Valori di uscita cluttering** | Configura filtri di avviso in pytest.ini: filterwarnings = ignore::DeprecationWarning_, o utilizzare -W flag: pytest -W ignore::UserWarning |