DEV Community

qing
qing

Posted on

5 Proven Pytest Tips

pytest Best Practices: Testing Python Code Like a Pro

Good tests are as important as good code. Here's how to write professional pytest tests.

Install

pip install pytest pytest-asyncio pytest-cov httpx
Enter fullscreen mode Exit fullscreen mode

Basic Test Structure

# tests/test_users.py
import pytest
from myapp import create_user, get_user, UserNotFoundError

class TestCreateUser:
    def test_creates_user_with_valid_data(self):
        user = create_user(name="Alice", email="alice@example.com")
        assert user.id is not None
        assert user.name == "Alice"
        assert user.email == "alice@example.com"

    def test_raises_on_invalid_email(self):
        with pytest.raises(ValueError, match="Invalid email"):
            create_user(name="Bob", email="not-an-email")

    def test_raises_on_duplicate_email(self):
        create_user(name="Alice", email="alice@example.com")
        with pytest.raises(ValueError, match="already exists"):
            create_user(name="Another Alice", email="alice@example.com")
Enter fullscreen mode Exit fullscreen mode

Fixtures

import pytest
from myapp import create_app, db

@pytest.fixture(scope="session")
def app():
    app = create_app(testing=True)
    return app

@pytest.fixture(scope="function")
def client(app):
    with app.test_client() as client:
        with app.app_context():
            db.create_all()
            yield client
            db.drop_all()

@pytest.fixture
def sample_user(client):
    user = create_user(name="Test User", email="test@example.com")
    return user
Enter fullscreen mode Exit fullscreen mode

Async Tests

import pytest
import pytest_asyncio
import httpx

@pytest.mark.asyncio
async def test_async_endpoint():
    async with httpx.AsyncClient(app=app, base_url="http://test") as client:
        response = await client.post("/users/", json={
            "username": "testuser",
            "email": "test@example.com",
            "age": 25,
        })
    assert response.status_code == 201
    data = response.json()
    assert data["username"] == "testuser"
Enter fullscreen mode Exit fullscreen mode

Parametrize

@pytest.mark.parametrize("email,valid", [
    ("user@example.com", True),
    ("user+tag@example.co.uk", True),
    ("not-an-email", False),
    ("@example.com", False),
    ("user@", False),
])
def test_email_validation(email, valid):
    if valid:
        user = create_user(name="Test", email=email)
        assert user.email == email
    else:
        with pytest.raises(ValueError):
            create_user(name="Test", email=email)
Enter fullscreen mode Exit fullscreen mode

Coverage

# Run with coverage
pytest --cov=myapp --cov-report=html --cov-report=term-missing

# Set minimum coverage
pytest --cov=myapp --cov-fail-under=80
Enter fullscreen mode Exit fullscreen mode

Follow me for more Python tips! 🐍


💡 Related: **Content Creator Ultimate Bundle (Save 33%)* — $29.99*


喜欢这篇文章?关注获取更多Python自动化内容!

Top comments (0)