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
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")
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
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"
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)
Coverage
# Run with coverage
pytest --cov=myapp --cov-report=html --cov-report=term-missing
# Set minimum coverage
pytest --cov=myapp --cov-fail-under=80
Follow me for more Python tips! 🐍
💡 Related: **Content Creator Ultimate Bundle (Save 33%)* — $29.99*
喜欢这篇文章?关注获取更多Python自动化内容!
Top comments (0)