Pytest Syntax
1. Basic Test Syntax
To define a test function, use the test_ prefix for the function name. This ensures that Pytest recognizes it as a test.
Example:
def test_addition():
assert 1 + 1 == 2
output:

2. Using Fixtures for Setup and Teardown
Fixtures are reusable pieces of setup code that can be shared across multiple tests. They are defined using the @pytest.fixture decorator.
Basic Example:
import pytest
@pytest.fixture
def setup_data():
data = {"name": "John", "age": 30}
return data
def test_user_name(setup_data):
assert setup_data["name"] == "John"
3. Parameterized Testing
Parameterized testing allows you to run the same test with different sets of inputs, reducing redundancy.
Example:
import pytest
@pytest.mark.parametrize("input1, input2, expected", [
(1, 1, 2),
(2, 2, 4),
(3, 3, 6)
])
def test_addition(input1, input2, expected):
assert input1 + input2 == expected
4. Assertions
Assertions are crucial for verifying that the code behaves as expected. Pytest provides detailed output when assertions fail.
Common Assertions:
def test_example():
assert 1 == 1 # Equality assertion
assert 1 != 2 # Inequality assertion
assert [1, 2, 3] == [1, 2, 3] # List equality
assert "apple" in "pineapple" # Containment assertion
assert not isinstance(123, str) # Type assertion
5. Running Tests
To execute tests, use the following command:
pytest
You can also specify a file or directory:
pytest test_example.py # Run tests in a specific file
pytest tests/ # Run tests in a directory
Command-Line Options:
-v: Verbose output.--maxfail=<num>: Stop after a specific number of failures.
6. Working with Asynchronous Tests
For testing asynchronous code, use the pytest-asyncio plugin.
Example:
import pytest
import asyncio
@pytest.mark.asyncio
async def test_async_addition():
await asyncio.sleep(1)
assert 2 + 2 == 4
- Decorator:
@pytest.mark.asyncioallows testing of asynchronous functions.
7. Organizing and Discovering Tests
Pytest automatically discovers tests in files prefixed with test_ or suffixed with _test.py. You can organize tests in directories.
Test Structure Example:
tests/
test_basic.py
test_advanced.py
subdir/
test_submodule.py
8. Skipping Tests and Expected Failures
You can skip tests or mark them as expected failures using decorators.
Skipping a Test:
import pytest
@pytest.mark.skip(reason="This test is not yet implemented.")
def test_not_implemented():
assert False
Expected Failure:
@pytest.mark.xfail
def test_expected_failure():
assert 1 == 2 # This will be marked as an expected failure
9. Testing Class-Based OOP Structures
Pytest supports testing classes and their methods effectively.
9.1 Testing Classes and Methods
You can test classes and their methods by creating instances within your tests and verifying their behavior.
Example:
# person.py
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
def is_adult(self):
return self.age >= 18
Test:
from person import Person
def test_person_greet():
person = Person("Alice", 30)
assert person.greet() == "Hello, my name is Alice and I am 30 years old."
def test_person_is_adult():
adult = Person("Bob", 25)
child = Person("Charlie", 10)
assert adult.is_adult() is True
assert child.is_adult() is False
9.2 Using Fixtures with Classes
Fixtures can create and manage instances of classes for reuse across multiple tests.
Example:
import pytest
from person import Person
@pytest.fixture
def person_instance():
return Person("Diana", 22)
def test_person_greet_with_fixture(person_instance):
assert person_instance.greet() == "Hello, my name is Diana and I am 22 years old."
9.3 Testing Inheritance
Test whether subclasses correctly extend or override the behavior of parent classes.
Example:
# employee.py
class Employee(Person): # Inherits from Person
def __init__(self, name, age, employee_id):
super().__init__(name, age)
self.employee_id = employee_id
def greet(self):
return f"{super().greet()} My employee ID is {self.employee_id}."
Test:
from employee import Employee
def test_employee_greet():
employee = Employee("Eve", 28, "E12345")
expected_greeting = "Hello, my name is Eve and I am 28 years old. My employee ID is E12345."
assert employee.greet() == expected_greeting
9.4 Mocking Dependencies in Classes
Mock external dependencies, such as database connections or APIs, when testing class behavior.
Example:
from unittest.mock import MagicMock
from payment_gateway import Order, PaymentGateway
def test_order_checkout():
mock_gateway = MagicMock()
mock_gateway.process_payment.return_value = {"status": "success", "amount": 100}
order = Order(mock_gateway)
assert order.checkout(100) is True
mock_gateway.process_payment.assert_called_once_with(100)
9.5 Testing Exceptions in Classes
Verify that classes handle exceptions properly using pytest.raises.
Example:
import pytest
from bank_account import BankAccount
def test_negative_balance_raises_exception():
with pytest.raises(ValueError, match="Balance cannot be negative."):
BankAccount(-100)