Почему тестировщик не пригласил Pytest на свой день рождения? Потому что он боялся, что тесты падут и вечеринка закончится с ошибкой 404 – "Файл не найден"!
Pytest – это один из наиболее популярных фреймворков для написания тестов на Python.
Он известен своей простотой в использовании, обширным сообществом и широким спектром функциональности. Однако, даже если вы являетесь опытным пользователем Pytest, вероятно, вы не используете все его функции.
В этой статье мы рассмотрим топ малоизвестных, но полезных функций Pytest.
![](https://habrastorage.org/getpro/habr/upload_files/5f0/1a3/b92/5f01a3b92315b82ac199a4d65c165b54.jpg)
1. Множественный запуск тестов
Pytest позволяет запускать тесты несколько раз с использованием параметра --count. Это полезно в следующих сценариях:
Поиск непостоянных ошибок.
Запустив тесты множество раз, мы можем выявить ошибки, которые проявляются только в редких случаях, что помогает повысить надежность нашего кода.
Исследование производительности.
Многократный запуск тестов позволяет оценить производительность нашего кода, обнаружить утечки памяти и другие производственные проблемы.
Иногда при тестировании разработанного программного обеспечения возникают проблемы, связанные с производительностью. Многократный запуск тестов может оказаться полезным инструментом для оценки производительности нашего кода и выявления проблем, которые могут быть вызваны различными факторами, такими как архитектурные особенности, внешние зависимости или динамические условия окружения.
Преимущества множественного запуска тестов для оценки производительности включают:
Обнаружение непостоянных проблем
При многократном запуске тестов можно выявить непостоянные проблемы, такие как утечка памяти, бутылочное горлышко в производительности и нестабильное поведение приложения.
Сбор статистики
Многократный запуск тестов позволяет собирать статистику о времени выполнения и ресурсах, используемых тестами. Это позволяет определить средние значения, дисперсию и другие статистические показатели, которые могут быть полезными для оценки производительности.
Регрессионное тестирование производительности
Путем многократного запуска тестов и сравнения результатов мы можем создать базовую линию производительности. После внесения изменений в код или окружение, мы можем сравнивать результаты новых запусков с базовой линией, чтобы обнаружить регрессию производительности.
Пример использования множественного запуска тестов для оценки производительности:
pytest --count=10 performance_test.py
В данном случае, тест performance_test.py будет запущен 10 раз, и результаты будут анализироваться для выявления временных изменений в производительности. Это помогает убедиться, что наше программное обеспечение остается производительным даже при различных условиях и изменениях.
Определение стабильности
Многократный запуск также может помочь нам оценить, насколько стабильны тесты и сколько раз они падают из-за нестабильных условий.
pytest --count=100
Допустим, у нас есть тест для функции calculate, и мы хотим убедиться, что он работает стабильно. Мы можем запустить его 10 раз, чтобы проверить, не возникают ли временные ошибки.
Пример:
pytest --count=10 test_calculate.py
Эта команда выполнит тест test_calculate.py 10 раз и предоставит отчет о результатах каждого запуска.
2. Отчеты о покрытии кода
Pytest интегрируется с различными инструментами для анализа покрытия кода, такими как coverage.py. Отчеты о покрытии кода – это важный инструмент для:
Измерения качества наших тестов
Они позволяют определить, какая часть нашего кода осталась непокрытой тестами.
Поиска "мертвого" кода
Мы можем обнаружить участки кода, которые больше не используются, и удалить их.
Оптимизации кода
Отчеты о покрытии помогают вам определить, какие части кода можно улучшить или оптимизировать.
pytest --cov=my_module
Допустим, у нас есть модуль my_module, и мы хотим создать отчет о покрытии кода для него, чтобы убедиться, что наши тесты покрывают большую часть кода.
Пример:
pytest --cov=my_module tests/
Эта команда выполнит тесты из каталога tests/ и создаст отчет о покрытии для модуля my_module. Мы увидим, какие строки кода были покрыты тестами, а какие остались непокрытыми.
3. Параметризация тестов
Использование параметризации позволяет сократить дублирование кода и улучшить читаемость наших тестов.
Мы можем использовать параметры для передачи разных входных данных в один и тот же тест:
import pytest
@pytest.mark.parametrize("input, expected", [(1, 2), (2, 4), (3, 6)])
def test_double(input, expected):
assert double(input) == expected
Это позволяет вам определить только одну реализацию теста, вместо создания нескольких одинаковых кейсов.
Допустим, у нас есть функция validate_email, и мы хотим проверить ее с разными входными данными. Мы можем использовать параметризацию для этой цели.
Пример:
import pytest
@pytest.mark.parametrize("email, is_valid", [("test@example.com", True), ("invalid-email", False)])
def test_validate_email(email, is_valid):
result = validate_email(email)
assert result == is_valid
Эта команда выполнит тест test_validate_email с разными входными данными, проверяя, корректно ли функция validate_email определяет валидность email.
4. Фильтрация и запуск по маркерам
Пометка тестов с использованием декораторов и их последующий запуск по маркерам – это мощный способ организации и выборочного выполнения тестов:
import pytest
@pytest.mark.smoke
def test_smoke_test():
assert some_function() == 42
Затем мы можем запустить только тесты, помеченные как smoke-тесты:
pytest -m smoke
Это удобно, когда у нас есть разные категории тестов, и мы хотим запускать их по отдельности.
Предположим, у нас есть большой набор тестов, и мы хотим запустить только smoke-тесты, чтобы быстро проверить, работает ли базовая функциональность нашего приложения.
pytest -m smoke
запустит только тесты, которые были помечены маркером smoke. Можно использовать этот подход для быстрой проверки основных сценариев нашего приложения перед выпуском.
5. Автоматическое обновление зависимостей
![](https://habrastorage.org/getpro/habr/upload_files/d32/5ef/ddd/d325efddd4d80a271b554c4530e2a8ba.jpg)
С помощью параметра --self-upgrade, Pytest позволяет автоматически обновлять сам фреймворк до последней версии. Это важно для:
Получения последних исправлений ошибок и новых функций.
Гарантии совместимости нашего кода с актуальной версией Pytest.
pytest --self-upgrade
\
Обновляйте Pytest регулярно, чтобы быть в курсе последних изменений и улучшений.
6. Использование параметров командной строки в тестах
С использованием фикстуры request, мы можем передавать параметры командной строки в наши тесты. Это полезно, когда наши тесты зависят от внешних данных:
def test_command_line_args(request):
arg_value = request.config.getoption("--my-arg")
assert some_function(arg_value) == expected_value
Запустим тест с параметром командной строки:
pytest --my-arg=42
Это дает нам гибкость в настройке тестов в зависимости от внешних условий.
Предположим, у нас есть тест, который зависит от значения параметра, передаваемого через командную строку. Например, мы хотим проверить функцию calculate_tax с разными ставками налога.
Пример:
def test_calculate_tax():
tax_rate = float(input("Введем ставку налога: "))
income = 1000
result = calculate_tax(income, tax_rate)
assert result == income * tax_rate
В этом примере значение ставки налога вводится через командную строку при запуске теста.
Заключение
Pytest – мощный инструмент для написания тестов на Python, и в этой статье мы рассмотрели некоторые из его малоиспользуемых функций. Использование этих функций может сделать наш процесс тестирования более эффективным и удобным. Не стесняйтесь исследовать Pytest и использовать его возможности на полную мощь, чтобы улучшить качество нашего кода.