Python Testing với pytest: Viết Bộ Test Toàn Diện

Python Testing với pytest: Viết Bộ Test Toàn Diện
Testing là thiết yếu để xây dựng phần mềm đáng tin cậy. pytest là testing framework phổ biến nhất của Python—đơn giản để bắt đầu, nhưng đủ mạnh cho các ứng dụng phức tạp. Hướng dẫn này covers mọi thứ từ basic tests đến advanced patterns như fixtures, parametrization, và mocking.
Những Gì Bạn Sẽ Học
✅ pytest fundamentals và installation
✅ Viết và tổ chức test cases
✅ Fixtures cho test setup/teardown
✅ Parametrized tests cho data-driven testing
✅ Mocking và patching với pytest-mock
✅ Test coverage với pytest-cov
✅ Testing async code
✅ Best practices cho maintainable tests
Điều Kiện Tiên Quyết
Trước khi tìm hiểu pytest, bạn nên hiểu:
- Python functions và classes từ Giai Đoạn 1: Nền Tảng
- OOP concepts từ Giai Đoạn 2: OOP & Tính Năng Nâng Cao
Ghi chú: Phần này chứa các ví dụ code tương tự phiên bản tiếng Anh. Để tiết kiệm không gian, chúng tôi tập trung vào giải thích khái niệm bằng tiếng Việt và giữ nguyên code examples.
1. Getting Started với pytest
Installation: pip install pytest và các plugins hữu ích: pytest-cov (coverage), pytest-mock (mocking), pytest-asyncio (async testing).
Test Discovery: pytest tự động tìm tests:
- Files named
test_*.pyhoặc*_test.py - Functions bắt đầu với
test_ - Classes bắt đầu với
Test
Running tests: pytest (all tests), pytest -v (verbose), pytest test_file.py::test_function (specific test).
2. Assertions và Test Outcomes
Basic assertions: Dùng Python's built-in assert statement. pytest provides detailed failure messages automatically.
Testing exceptions: Dùng with pytest.raises(ExceptionType) để test exceptions. Có thể check message với match parameter.
Approximate comparisons: Dùng pytest.approx() cho floating point comparisons với relative hoặc absolute tolerance.
3. Test Organization
Project structure: Separate src/ và tests/ directories. conftest.py cho shared fixtures.
Configuration: pytest.ini hoặc pyproject.toml với [tool.pytest.ini_options].
Markers: @pytest.mark.slow, @pytest.mark.skip, @pytest.mark.xfail để categorize và control tests. Run với pytest -m slow.
4. Fixtures: Setup và Teardown
Basic fixtures: Functions decorated với @pytest.fixture provide test data. Tests request fixtures as parameters.
Fixture scopes: function (default, new mỗi test), class, module, session. Higher scope = less setup overhead.
Teardown với yield: Code sau yield runs sau test completion. Perfect cho cleanup resources.
Factory fixtures: Return function thay vì value cho flexible test data creation.
Built-in fixtures: tmp_path (temp directory), capsys (capture stdout/stderr), monkeypatch (modify objects/env vars).
5. Parametrized Tests
Basic parametrization: @pytest.mark.parametrize("param1,param2", [(val1, val2), ...]) runs test với multiple inputs.
IDs cho clarity: pytest.param(value, id="descriptive_name") makes output readable.
Multiple decorators: Stacking @pytest.mark.parametrize creates all combinations.
Parametrized fixtures: @pytest.fixture(params=[...]) runs dependent tests with each param.
6. Mocking và Patching
pytest-mock: mocker fixture provides mocker.patch(), mocker.Mock(), mocker.spy().
Patching functions: mocker.patch("module.function", return_value=...) replaces function.
Patching methods: mocker.patch.object(obj, "method", return_value=...) replaces method.
Environment variables: monkeypatch.setenv("VAR", "value"), monkeypatch.delenv("VAR").
Spy: mocker.spy(obj, "method") tracks calls without replacing implementation.
7. Testing Async Code
Setup: Install pytest-asyncio, configure asyncio_mode = "auto" trong pyproject.toml.
Async tests: @pytest.mark.asyncio decorator, async def test_...(), await coroutines.
Async fixtures: @pytest.fixture với async def, dùng yield cho cleanup.
8. Test Coverage
Setup: pip install pytest-cov.
Running: pytest --cov=myapp --cov-report=term-missing shows uncovered lines.
HTML report: pytest --cov=myapp --cov-report=html generates browsable report.
Threshold: pytest --cov-fail-under=80 fails nếu coverage < 80%.
Configuration: [tool.coverage.run] và [tool.coverage.report] trong pyproject.toml.
9. Real-World Example
Example trong EN version shows complete UserService với:
- Mock database fixture
- Test class organization
- Parametrized invalid email tests
- Authentication test scenarios
- Fixture chaining
Pattern: separate fixture creation, group related tests in classes, use descriptive names.
10. Best Practices
✅ Do's:
- Descriptive test names:
test_login_with_invalid_password_raises_auth_error - One assertion per test (when practical)
- Use fixtures cho setup
- Use parametrize cho multiple similar tests
- Keep tests isolated - no shared state
❌ Don'ts:
- Don't test implementation details (private methods)
- Don't use magic numbers without context
- Don't have tests depend on each other
- Don't ignore test failures
11. Common Pitfalls
Pitfall 1: Flaky tests - Timing-dependent tests. Use proper waits hoặc mocking instead of time.sleep().
Pitfall 2: Over-mocking - Testing mocks thay vì real code. Only mock external dependencies.
Pitfall 3: Not cleaning up - Files/resources left behind. Use tmp_path fixture hoặc teardown.
Summary
Trong guide này, bạn đã học:
✅ pytest fundamentals: installation, test discovery, assertions
✅ Test organization với classes, markers, và configuration
✅ Fixtures cho setup/teardown với different scopes
✅ Parametrized tests cho data-driven testing
✅ Mocking và patching với pytest-mock
✅ Testing async code với pytest-asyncio
✅ Test coverage với pytest-cov
✅ Best practices cho maintainable tests
Testing là skill improves với practice. Start với simple unit tests, gradually add sophisticated patterns khi codebase grows.
Bước Tiếp Theo
Giờ bạn đã hiểu testing, khám phá các chủ đề liên quan:
Thêm Python Deep Dives:
- Type Hints & Typing - Type-safe testing
- Async Programming - Async patterns to test
- Package Management với Poetry - Project setup với testing
Áp Dụng Testing trong Web Development:
- FastAPI Learning Roadmap - Test FastAPI applications
Quay Lại Roadmap:
- Python Learning Roadmap - Lộ trình học hoàn chỉnh
- Giai Đoạn 3: Standard Library & Tools - Nơi testing được giới thiệu
Thuộc chuỗi bài Lộ Trình Học Python
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.