Today, I want to introduce you to the most powerful testing framework in the Python world – Pytest. As a Python developer, writing test cases is an essential skill. With its simple syntax and powerful features, Pytest has rightfully earned its title as the king of Python testing.
Why Choose Pytest?
I remember when I first started writing tests, I used Python’s built-in unittest. While it worked, I always felt it was particularly cumbersome. It wasn’t until I encountered Pytest that I realized writing tests could be this simple!
Let’s compare the traditional unittest and the pytest code:
# unittest way
import unittest
class TestCalculator(unittest.TestCase):
def test_add(self):
self.assertEqual(2 + 2, 4)
# pytest way
def test_add():
assert 2 + 2 == 4
Doesn’t it feel like Pytest is much more concise? No need to inherit from TestCase, you can simply use assert!
Basic Usage of Pytest
1. Install Pytest
First, we need to install pytest:
pip install pytest
2. Write Your First Test Case
Let’s see how to write a simple test case:
# test_sample.py
def test_string():
assert "hello" + " world" == "hello world"
def test_number():
assert 3 * 4 == 12
Tip: The test file name should start with test_
or end with _test
, and the test functions should also start with test
!
3. Run the Tests
Run it directly in the command line:
pytest
Pytest will automatically discover and run all test cases, isn’t that convenient?
Advanced Features
1. Test Fixtures
This is one of Pytest’s most powerful features! Fixtures help us prepare test data and share it across multiple tests:
import pytest
@pytest.fixture
def user_data():
return {
"name": "Kitty",
"age": 18
}
def test_user_name(user_data):
assert user_data["name"] == "Kitty"
def test_user_age(user_data):
assert user_data["age"] == 18
2. Parameterized Tests
Want to test the same function with different parameters? Parameterized tests help you achieve that:
import pytest
@pytest.mark.parametrize("input,expected", [
("hello", 5),
("python", 6),
("test", 4)
])
def test_string_length(input, expected):
assert len(input) == expected
3. Exception Testing
Testing if your code correctly raises exceptions is also very simple:
def test_zero_division():
with pytest.raises(ZeroDivisionError):
1 / 0
Tip: In real projects, exception testing is particularly important as it can help us identify potential issues early!
Common Techniques
-
Skip Tests: Use @pytest.mark.skip
decorator to skip certain tests. -
Conditional Skips: @pytest.mark.skipif
can decide whether to skip tests based on conditions. -
Group Tests: Use @pytest.mark.group_name
to group tests.
@pytest.mark.slow
def test_slow_function():
# This is a time-consuming test
pass
Then you can run pytest -m slow
to only execute tests marked with slow.
Practical Exercise
Try writing a simple calculator class and create test cases for it:
class Calculator:
def add(self, a, b):
return a + b
def divide(self, a, b):
return a / b
# Exercise: Please write test cases for the Calculator class, including:
# 1. Test normal addition
# 2. Test exception when dividing by zero
# 3. Use parameterized tests for multiple addition operations