Chapter 1 - Pytest Fundamentals
Haiyue
6min
Chapter 1: Pytest Fundamentals
Learning Objectives
- Understand pytest’s core concepts and advantages
- Master pytest installation and basic usage
- Write your first test case
- Learn about test discovery mechanisms and naming conventions
Knowledge Points
Pytest Overview and Advantages
- Concise syntax: Uses standard assert statements, no special assertion methods needed
- Automatic test discovery: Automatically discovers and runs test files and test functions
- Rich plugin ecosystem: Hundreds of plugins to extend functionality
- Detailed failure information: Provides clear error reports and debugging information
- Fixture support: Powerful test data and resource management mechanism
- Parameterized testing: Easy implementation of data-driven tests
Installation and Environment Setup
# Install pytest using pip
pip install pytest
# Verify installation
pytest --version
Test Discovery Mechanism
Pytest automatically discovers tests following these naming conventions:
| Type | Naming Convention |
|---|---|
| Test files | test_*.py or *_test.py |
| Test functions | test_* |
| Test classes | Test* |
| Test methods | test_* |
Basic Commands
# Run all tests
pytest
# Run specific file
pytest test_example.py
# Run specific directory
pytest tests/
# Verbose output
pytest -v
# Display local variables
pytest -l
Example Code
First Test File
# test_basic.py
def add(a, b):
"""Simple addition function"""
return a + b
def test_add_positive_numbers():
"""Test adding positive numbers"""
result = add(2, 3)
assert result == 5 # Use standard assert statement
def test_add_negative_numbers():
"""Test adding negative numbers"""
result = add(-2, -3)
assert result == -5
def test_add_zero():
"""Test adding with zero"""
result = add(5, 0)
assert result == 5
Running Tests
# Run from command line
$ pytest test_basic.py -v
# Example output:
# ========================= test session starts =========================
# collected 3 items
#
# test_basic.py::test_add_positive_numbers PASSED [ 33%]
# test_basic.py::test_add_negative_numbers PASSED [ 66%]
# test_basic.py::test_add_zero PASSED [100%]
#
# ========================= 3 passed in 0.01s =========================
Using Test Classes
# test_calculator.py
class Calculator:
"""Simple calculator class"""
def add(self, a, b):
return a + b
def subtract(self, a, b):
return a - b
class TestCalculator:
"""Calculator test class"""
def setup_method(self):
"""Execute before each test method"""
self.calc = Calculator()
def test_addition(self):
"""Test addition functionality"""
assert self.calc.add(2, 3) == 5
assert self.calc.add(-1, 1) == 0
def test_subtraction(self):
"""Test subtraction functionality"""
assert self.calc.subtract(5, 3) == 2
assert self.calc.subtract(0, 5) == -5
Test Failure Example
# test_failure_example.py
def divide(a, b):
"""Division function (intentionally contains error)"""
return a / b # No handling for division by zero
def test_divide_success():
"""Test normal division"""
assert divide(10, 2) == 5
def test_divide_by_zero():
"""Test division by zero (this test will fail)"""
# Here we expect an exception, but the function crashes directly
result = divide(10, 0)
assert result is None # This line will never execute
Running failed tests will provide detailed error information:
$ pytest test_failure_example.py -v
# Output includes:
# FAILURES
# test_failure_example.py::test_divide_by_zero - ZeroDivisionError: division by zero
# along with detailed call stack information
Project Structure Best Practices
project/
├── src/
│ └── calculator.py # Source code
├── tests/
│ ├── __init__.py # Make tests a package
│ ├── test_calculator.py # Test file
│ └── conftest.py # pytest configuration file
├── pytest.ini # pytest configuration
└── requirements.txt # Dependencies file
Tips
- Use
assertstatements for assertions, pytest will automatically provide detailed failure information - Test function names should describe the specific scenario being tested
- Each test should be independent, not relying on results from other tests
- Follow the AAA pattern: Arrange, Act, Assert
Cautions
- Ensure test files and functions follow naming conventions
- Avoid using complex logic in tests
- Tests should execute quickly, avoid time-consuming operations
Common Command Options
| Option | Function |
|---|---|
-v, --verbose | Display verbose output |
-q, --quiet | Simplified output |
-s | Display print output |
-x, --exitfirst | Stop at first failure |
--tb=short | Simplified error traceback |
--collect-only | Only collect tests, don’t run |
With this, we’ve completed the introduction to pytest fundamentals, laying a solid foundation for further learning of advanced features.