💻 Примеры: Calculator, pytest, маркировки, параметризация
⚡ Ключевые примеры
# test_calculator.py
import pytest
from calculator import Calculator
@pytest.fixture
def calculator():
return Calculator()
def test_sum(calculator):
assert calculator.sum(4, 5) == 9
def test_div_by_zero(calculator):
with pytest.raises(ArithmeticError):
calculator.div(10, 0)
@pytest.mark.parametrize('a,b,res', [(4,5,9),(-6,-10,-16),(10,0,10)])
def test_sum_param(a, b, res):
assert Calculator().sum(a, b) == res
Пример 1: Класс Calculator
# Lesson1/calculator.py
class Calculator:
def sum(self, a, b):
return a + b
def sub(self, a, b):
return a - b
def mul(self, a, b):
return a * b
def div(self, a, b):
if b == 0:
raise ArithmeticError("На ноль делить нельзя")
return a / b
def pow(self, a, b=2):
return a ** b
def avg(self, nums):
if len(nums) == 0:
return 0
s = sum(nums)
return self.div(s, len(nums))
Пример 2: Тесты с фикстурой
# Lesson1/test_calculator.py
import pytest
from calculator import Calculator
@pytest.fixture
def calculator():
return Calculator()
# Тесты для метода sum
def test_sum_positive_numbers(calculator):
assert calculator.sum(4, 5) == 9
def test_sum_negative_numbers(calculator):
assert calculator.sum(-6, -10) == -16
def test_sum_positive_and_negative(calculator):
assert calculator.sum(-6, 6) == 0
def test_sum_floats(calculator):
res = calculator.sum(5.6, 4.3)
assert round(res, 1) == 9.9
def test_sum_with_zero(calculator):
assert calculator.sum(10, 0) == 10
# Тесты для метода div
def test_division(calculator):
assert calculator.div(10, 2) == 5
def test_division_by_zero(calculator):
with pytest.raises(ArithmeticError, match="На ноль делить нельзя"):
calculator.div(10, 0)
# Тесты для метода avg
def test_avg_empty_list(calculator):
assert calculator.avg([]) == 0
def test_avg_list(calculator):
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 5]
assert calculator.avg(numbers) == 5
Пример 3: Маркировки тестов
# Lesson1/test_calculator_marks.py
import pytest
from calculator import Calculator
# Пропуск теста
@pytest.mark.skip(reason="Тест будет исправлен позже")
def test_sum_positive_nums():
calculator = Calculator()
res = calculator.sum(4, 5)
assert res == 9
# Условный пропуск
import sys
@pytest.mark.skipif(sys.version_info < (3, 8), reason="Требуется Python 3.8 или выше")
def test_sum_negative_nums():
calculator = Calculator()
res = calculator.sum(-6, -10)
assert res == -16
# Ожидаемый сбой
@pytest.mark.xfail(strict=True, reason="Метод в процессе разработки")
def test_sum_with_error():
calculator = Calculator()
res = calculator.sum(4, 5)
assert res == 10 # Умышленная ошибка
# Пользовательские маркеры
@pytest.mark.positive_test
def test_sum_positive():
calculator = Calculator()
assert calculator.sum(4, 5) == 9
@pytest.mark.positive_test
def test_div_positive():
calculator = Calculator()
assert calculator.div(10, 2) == 5
Запуск только positive_test:
pytest -m positive_test
Вывод:
collected 9 items / 7 deselected / 2 selected
PASSED test_calculator_marks.py::test_sum_positive
PASSED test_calculator_marks.py::test_div_positive
Пример 4: Конфигурация pytest.ini — выборочный запуск
# pytest.ini (в корне проекта)
[pytest]
python_functions = *sum*
markers =
positive_test: Тесты для позитивных сценариев
negative_test: Тесты для негативных сценариев
После добавления этой конфигурации команда
pytest запустит только тесты, содержащие слово sum в имени.
Пример 5: Параметризация тестов
# Lesson1/test_calculator_parametrize.py
import pytest
from calculator import Calculator
@pytest.mark.parametrize('num1, num2, result', [
(4, 5, 9),
(-6, -10, -16),
(-6, 6, 0),
(5.61, 4.29, 9.9),
(10, 0, 10)
])
def test_sum(num1, num2, result):
calculator = Calculator()
res = calculator.sum(num1, num2)
assert res == result
@pytest.mark.parametrize('nums, result', [
([], 0), # Пустой список
([1, 2, 3, 4, 5, 6, 7, 8, 9, 5], 5) # Среднее арифметическое
])
def test_avg(nums, result):
calculator = Calculator()
res = calculator.avg(nums)
assert res == result
Вывод
pytest -v:
test_calculator_parametrize.py::test_sum[4-5-9] PASSED
test_calculator_parametrize.py::test_sum[-6--10--16] PASSED
test_calculator_parametrize.py::test_sum[-6-6-0] PASSED
test_calculator_parametrize.py::test_sum[5.61-4.29-9.9] PASSED
test_calculator_parametrize.py::test_sum[10-0-10] PASSED
test_calculator_parametrize.py::test_avg[nums0-0] PASSED
test_calculator_parametrize.py::test_avg[nums1-5] PASSED
Пример 6: Разбор домашнего задания из лекции
В лекции разбирали класс
SimpleMath — ДЗ урока 01.
# simple_math.py
class SimpleMath:
def square(self, n):
return n ** 2
def cube(self, n):
return n ** 3
# test_simple_math.py
from simple_math import SimpleMath
math = SimpleMath()
def test_square_positive():
"""Тест метода square для положительного числа."""
assert math.square(2) == 4
def test_square_negative():
"""Тест метода square для отрицательного числа."""
assert math.square(-3) == 9
def test_square_zero():
"""Тест метода square для нуля."""
assert math.square(0) == 0
def test_cube_positive():
"""Тест метода cube для положительного числа."""
assert math.cube(3) == 27
def test_cube_negative():
"""Тест метода cube для отрицательного числа."""
assert math.cube(-2) == -8
def test_cube_zero():
"""Тест метода cube для нуля."""
assert math.cube(0) == 0