Loading...
Loading...
Compare original and translation side by side
AsyncClientAsyncClientundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
python_files = ["test_*.py"]
python_functions = ["test_*"]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: marks tests as integration tests",
]
filterwarnings = [
"error",
"ignore::DeprecationWarning",
][tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
python_files = ["test_*.py"]
python_functions = ["test_*"]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: marks tests as integration tests",
]
filterwarnings = [
"error",
"ignore::DeprecationWarning",
]import pytest
def test_addition():
assert 1 + 1 == 2
def test_exception_raised():
with pytest.raises(ValueError, match="invalid value"):
raise ValueError("invalid value")
class TestUserService:
def test_create_user(self):
user = create_user(name="Alice")
assert user.name == "Alice"
def test_create_user_empty_name(self):
with pytest.raises(ValueError):
create_user(name="")import pytest
def test_addition():
assert 1 + 1 == 2
def test_exception_raised():
with pytest.raises(ValueError, match="invalid value"):
raise ValueError("invalid value")
class TestUserService:
def test_create_user(self):
user = create_user(name="Alice")
assert user.name == "Alice"
def test_create_user_empty_name(self):
with pytest.raises(ValueError):
create_user(name="")import pytest
@pytest.fixture
def sample_user():
return {"name": "Alice", "email": "alice@example.com"}
@pytest.fixture
def db_session():
session = create_session()
yield session
session.rollback()
session.close()
@pytest.fixture(autouse=True)
def reset_cache():
"""Automatically reset cache before each test."""
cache.clear()
yield
cache.clear()import pytest
@pytest.fixture
def sample_user():
return {"name": "Alice", "email": "alice@example.com"}
@pytest.fixture
def db_session():
session = create_session()
yield session
session.rollback()
session.close()
@pytest.fixture(autouse=True)
def reset_cache():
"""Automatically reset cache before each test."""
cache.clear()
yield
cache.clear()undefinedundefinedconftest.pyundefinedconftest.pyundefinedundefinedundefinedasyncio_mode = "auto"async def test_async_endpoint(client):
response = await client.get("/api/health")
assert response.status_code == 200
assert response.json() == {"status": "ok"}
async def test_async_service():
result = await fetch_data("https://api.example.com/data")
assert result is not Noneasyncio_mode = "auto"async def test_async_endpoint(client):
response = await client.get("/api/health")
assert response.status_code == 200
assert response.json() == {"status": "ok"}
async def test_async_service():
result = await fetch_data("https://api.example.com/data")
assert result is not Noneimport pytest
from httpx import ASGITransport, AsyncClient
from myapp.main import create_app
from myapp.dependencies import get_db
@pytest.fixture
def app():
app = create_app()
# Override dependencies for testing
app.dependency_overrides[get_db] = lambda: fake_db
yield app
app.dependency_overrides.clear()
@pytest.fixture
async def client(app):
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as ac:
yield ac
async def test_create_item(client):
response = await client.post(
"/api/items",
json={"name": "Test Item", "price": 9.99},
)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Item"
async def test_get_item_not_found(client):
response = await client.get("/api/items/999")
assert response.status_code == 404import pytest
from httpx import ASGITransport, AsyncClient
from myapp.main import create_app
from myapp.dependencies import get_db
@pytest.fixture
def app():
app = create_app()
# Override dependencies for testing
app.dependency_overrides[get_db] = lambda: fake_db
yield app
app.dependency_overrides.clear()
@pytest.fixture
async def client(app):
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as ac:
yield ac
async def test_create_item(client):
response = await client.post(
"/api/items",
json={"name": "Test Item", "price": 9.99},
)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Item"
async def test_get_item_not_found(client):
response = await client.get("/api/items/999")
assert response.status_code == 404from unittest.mock import AsyncMock, MagicMock, patch
def test_with_mock():
mock_service = MagicMock()
mock_service.get_user.return_value = {"name": "Alice"}
result = process_user(mock_service, user_id=1)
mock_service.get_user.assert_called_once_with(1)
assert result["name"] == "Alice"
async def test_with_async_mock():
mock_client = AsyncMock()
mock_client.fetch.return_value = {"data": "value"}
result = await handler(mock_client)
mock_client.fetch.assert_awaited_once()
def test_with_patch():
with patch("myapp.services.external_api.call") as mock_call:
mock_call.return_value = {"status": "ok"}
result = my_function()
assert result["status"] == "ok"from unittest.mock import AsyncMock, MagicMock, patch
def test_with_mock():
mock_service = MagicMock()
mock_service.get_user.return_value = {"name": "Alice"}
result = process_user(mock_service, user_id=1)
mock_service.get_user.assert_called_once_with(1)
assert result["name"] == "Alice"
async def test_with_async_mock():
mock_client = AsyncMock()
mock_client.fetch.return_value = {"data": "value"}
result = await handler(mock_client)
mock_client.fetch.assert_awaited_once()
def test_with_patch():
with patch("myapp.services.external_api.call") as mock_call:
mock_call.return_value = {"status": "ok"}
result = my_function()
assert result["status"] == "ok"undefinedundefinedimport pytest
@pytest.mark.parametrize(
"input_val, expected",
[
(1, 2),
(2, 4),
(3, 6),
(-1, -2),
],
)
def test_double(input_val, expected):
assert double(input_val) == expected
@pytest.mark.parametrize(
"status_code, is_success",
[
(200, True),
(201, True),
(400, False),
(500, False),
],
ids=["ok", "created", "bad-request", "server-error"],
)
def test_is_success_status(status_code, is_success):
assert is_success_response(status_code) == is_successimport pytest
@pytest.mark.parametrize(
"input_val, expected",
[
(1, 2),
(2, 4),
(3, 6),
(-1, -2),
],
)
def test_double(input_val, expected):
assert double(input_val) == expected
@pytest.mark.parametrize(
"status_code, is_success",
[
(200, True),
(201, True),
(400, False),
(500, False),
],
ids=["ok", "created", "bad-request", "server-error"],
)
def test_is_success_status(status_code, is_success):
assert is_success_response(status_code) == is_successimport pytest
@pytest.mark.slow
def test_large_dataset():
"""Takes a long time to run."""
...
@pytest.mark.integration
async def test_database_connection():
"""Requires a running database."""
...
@pytest.mark.skipif(
sys.platform == "win32",
reason="Unix-only test",
)
def test_unix_socket():
...
@pytest.mark.xfail(reason="Known bug #123")
def test_known_bug():
...import pytest
@pytest.mark.slow
def test_large_dataset():
"""Takes a long time to run."""
...
@pytest.mark.integration
async def test_database_connection():
"""Requires a running database."""
...
@pytest.mark.skipif(
sys.platform == "win32",
reason="Unix-only test",
)
def test_unix_socket():
...
@pytest.mark.xfail(reason="Known bug #123")
def test_known_bug():
...project/
├── src/
│ └── myapp/
│ ├── __init__.py
│ ├── main.py
│ ├── services/
│ └── models/
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Shared fixtures (app, client, db)
│ ├── test_health.py # Health endpoint tests
│ ├── unit/
│ │ ├── __init__.py
│ │ ├── test_models.py
│ │ └── test_services.py
│ └── integration/
│ ├── __init__.py
│ └── test_api.py
└── pyproject.tomlproject/
├── src/
│ └── myapp/
│ ├── __init__.py
│ ├── main.py
│ ├── services/
│ └── models/
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Shared fixtures (app, client, db)
│ ├── test_health.py # Health endpoint tests
│ ├── unit/
│ │ ├── __init__.py
│ │ ├── test_models.py
│ │ └── test_services.py
│ └── integration/
│ ├── __init__.py
│ └── test_api.py
└── pyproject.tomlscope@pytest.fixture(scope="function") # default: new instance per test
def db_session():
...
@pytest.fixture(scope="module") # shared across tests in one module
def db_engine():
...
@pytest.fixture(scope="session") # shared across the entire test session
def app():
return create_app()| Scope | Lifetime | Use Case |
|---|---|---|
| One per test function (default) | Mutable state, per-test isolation |
| One per test class | Shared setup within a test class |
| One per test module | Expensive resources (DB engine, client) |
| One per entire test session | Immutable globals, app factory |
pytest-asyncioscope@pytest.fixture(scope="function") # default: new instance per test
def db_session():
...
@pytest.fixture(scope="module") # shared across tests in one module
def db_engine():
...
@pytest.fixture(scope="session") # shared across the entire test session
def app():
return create_app()| 作用域(Scope) | 生命周期(Lifetime) | 适用场景(Use Case) |
|---|---|---|
| 每个测试函数一个(默认) | 可变状态,测试间隔离 |
| 每个测试类一个 | 测试类内的共享初始化 |
| 每个测试模块一个 | 资源密集型组件(数据库引擎、客户端) |
| 整个测试会话周期内一个 | 不可变全局对象,应用工厂 |
pytest-asyncio@pytest.fixture
def app():
app = create_app()
app.dependency_overrides[get_db] = lambda: fake_db
yield app
app.dependency_overrides.clear() # CRITICAL: prevent leaking to next testautouse@pytest.fixture(autouse=True)
def _cleanup_overrides(app):
yield
app.dependency_overrides.clear()@pytest.fixture
def app():
app = create_app()
app.dependency_overrides[get_db] = lambda: fake_db
yield app
app.dependency_overrides.clear() # 关键:防止影响后续测试autouse@pytest.fixture(autouse=True)
def _cleanup_overrides(app):
yield
app.dependency_overrides.clear()undefinedundefinedundefinedundefinedtest_<what>_<condition>_<expected>test_create_user_empty_name_raises_errorsetUptearDownconftest.pypytest.raisesparametrizetest_<测试对象>_<条件>_<预期结果>test_create_user_empty_name_raises_errorsetUptearDownconftest.pypytest.raisesparametrize