12. Тестирование #
Тестирование — важный этап разработки, обеспечивающий стабильность и надежность кода. Python предлагает встроенные и сторонние инструменты для создания тестов.
12.1. Введение в модуль unittest
#
unittest
— стандартная библиотека Python для тестирования.
Основные понятия: #
- Тест-кейс: отдельный тест, описывающий определенное поведение.
- Тестовый набор (test suite): группа тестов.
- Тестовый запуск (test runner): инструмент для выполнения тестов.
Пример тест-кейса #
import unittest
def add(a, b):
return a + b
class TestMathOperations(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(3, 5), 8)
def test_add_negative_numbers(self):
self.assertEqual(add(-3, -5), -8)
def test_add_mixed_sign_numbers(self):
self.assertEqual(add(3, -5), -2)
if __name__ == "__main__":
unittest.main()
Команды для запуска: #
- Запуск теста из файла:
python test_file.py
- Запуск всех тестов из директории:
python -m unittest discover
12.2. Использование pytest
#
pytest
— мощная и простая в использовании библиотека для тестирования.
Установка #
pip install pytest
Пример теста #
test_math_operations.py
:
def add(a, b):
return a + b
def test_add_positive_numbers():
assert add(3, 5) == 8
def test_add_negative_numbers():
assert add(-3, -5) == -8
def test_add_mixed_sign_numbers():
assert add(3, -5) == -2
Запуск тестов #
pytest
Особенности pytest
:
#
Автоматический поиск тестов: все файлы с именами
test_*.py
или*_test.py
автоматически подхватываются.Маркеры тестов: позволяют группировать тесты.
import pytest @pytest.mark.slow def test_slow_function(): assert True
Запуск тестов с маркером:
pytest -m slow
Фикстуры #
Фикстуры упрощают подготовку данных для тестов.
import pytest
@pytest.fixture
def sample_data():
return {"a": 3, "b": 5}
def test_add_with_fixture(sample_data):
result = sample_data["a"] + sample_data["b"]
assert result == 8
12.3. Мокирование и тестирование асинхронного кода #
Мокирование с использованием unittest.mock
#
Мокирование позволяет заменять реальные объекты тестируемого кода их имитацией.
Пример: #
from unittest.mock import Mock
def fetch_data(api):
return api.get_data()
def test_fetch_data():
mock_api = Mock()
mock_api.get_data.return_value = {"key": "value"}
result = fetch_data(mock_api)
assert result == {"key": "value"}
Тестирование асинхронного кода с pytest-asyncio
#
Установка #
pip install pytest-asyncio
Пример теста #
import asyncio
import pytest
async def async_add(a, b):
await asyncio.sleep(1)
return a + b
@pytest.mark.asyncio
async def test_async_add():
result = await async_add(3, 5)
assert result == 8
Инструменты для асинхронного мокирования #
Для мокирования асинхронных функций можно использовать AsyncMock
.
Пример: #
from unittest.mock import AsyncMock
async def fetch_data(api):
return await api.get_data()
def test_fetch_data():
mock_api = AsyncMock()
mock_api.get_data.return_value = {"key": "value"}
result = asyncio.run(fetch_data(mock_api))
assert result == {"key": "value"}
Рекомендации #
- Используйте
unittest
для простых проектов, где важна встроенность в стандартную библиотеку. - Применяйте
pytest
для крупных проектов благодаря его гибкости и расширяемости. - При тестировании кода, связанного с внешними сервисами, используйте мокирование, чтобы избежать зависимости от этих сервисов.
- Для асинхронного кода выбирайте инструменты, совместимые с
asyncio
, например,pytest-asyncio
иAsyncMock
.