1. Что такое тестирование программного обеспечения
Тестирование программного обеспечения — это проверка соответствия между реальным и ожидаемым поведением программы, выполняемая на определённом наборе тестов, который подбирается осмысленно и целенаправленно.
Ключевые аспекты тестирования
- Не просто поиск багов. Тестирование подтверждает корректность работы системы в протестированных сценариях.
- Проверка ожиданий. Помогает убедиться, что продукт удовлетворяет функциональным и нефункциональным требованиям.
- Процесс. Включает управление тестами, их проектирование, выполнение и анализ результатов.
Представьте, что вы тестируете карандаш. Задача — не просто искать дефекты (сломанный грифель, трещины), но и проверить, выполняет ли карандаш свои функции: пишет ли он, насколько легко стирается ластиком, как долго хватает ресурса. Если карандаш пишет, но очень бледно — это тоже отклонение от ожиданий.
2. Автоматизация тестирования
Автоматизация тестирования — это процесс использования инструментов и скриптов для выполнения тестов с минимальным участием человека.
Выгода от автоматизации тестирования
- Скорость выполнения тестов. Автоматизированные тесты работают быстрее. Проверка на сотнях конфигураций браузеров с помощью Selenium занимает считанные минуты — вручную это заняло бы дни.
- Повторяемость и масштабируемость. Тесты легко повторять — идеально для регрессионного тестирования. Перед каждым релизом запускается один набор тестов.
- Снижение затрат на долгосрочные проекты. Начальные инвестиции окупаются с каждым запуском: тесты выполняются без участия человека.
- Точность и исключение человеческого фактора. Скрипты выполняют однообразные задачи с неизменной точностью.
- Поддержка сложных сценариев. Автоматизация позволяет проверять нагрузочное тестирование, API с миллионами запросов — то, что трудно проверить вручную.
3. Пирамида тестирования
Пирамида тестирования — концепция, которая помогает эффективно распределить усилия на разные уровни тестирования, чтобы обеспечить качество программного обеспечения.
- Модульные тесты (Unit Tests)
- Интеграционные тесты (Integration Tests)
- End-to-End тесты (E2E Tests)
Уровень 1: Модульные тесты (Unit Tests)
- Основание пирамиды — самый нижний и широкий слой.
- Проверяют отдельные модули или функции программы в изоляции.
- Выполняются быстро, легко автоматизируются, охватывают большую часть логики.
- Пример: тест функции, которая рассчитывает итоговую сумму в корзине покупок.
Уровень 2: Интеграционные тесты (Integration Tests)
- Средний слой пирамиды.
- Проверяют взаимодействие между различными модулями или компонентами.
- Сложнее в реализации и медленнее, чем unit-тесты.
- Пример: тест связи между фронтендом и API.
Уровень 3: End-to-End тесты (E2E Tests)
- Вершина пирамиды — самый узкий слой.
- Проверяют систему целиком, включая пользовательский интерфейс.
- Наиболее сложные, дорогие и медленные — поэтому их количество ограничено.
- Пример: тест сценария оформления заказа на сайте.
Принципы пирамиды
- Больше unit-тестов, меньше интеграционных, ещё меньше E2E.
- Фокус на автоматизации нижних уровней для ускорения разработки.
- Оптимизация затрат за счёт снижения числа дорогих тестов верхнего уровня.
Представьте строительство дома. Модульные тесты — это проверка качества каждого кирпича. Интеграционные — проверка прочности стен. E2E — финальная проверка всего дома: двери, окна, инженерные системы.
4. pytest — инструмент для тестирования в Python
pytest — популярная библиотека для тестирования Python-кода. Проста в использовании, поддерживает автоматический запуск тестов и генерацию отчётов.
Установка
pip install pytest
Соглашения об именовании
pytest автоматически находит тесты, если:
- Имена файлов начинаются с
test_или заканчиваются на_test. - Имена функций начинаются с
test_.
Преимущества pytest перед ручными assert
- Простота и лаконичность: тесты легко писать и читать.
- Гибкость фикстур: общие настройки и ресурсы для тестов.
- Обработка исключений:
pytest.raises()— проверить, что метод выбрасывает ожидаемую ошибку. - Отчёты: подробная информация о причинах провала тестов.
5. Фикстуры pytest
Фикстуры позволяют задавать общие настройки и ресурсы, которые используются несколькими тестами. Это устраняет дублирование кода создания объектов.
# test_calculator.py
import pytest
from calculator import Calculator
@pytest.fixture
def calculator():
return Calculator()
def test_sum_positive_numbers(calculator):
assert calculator.sum(4, 5) == 9
def test_sum_negative_numbers(calculator):
assert calculator.sum(-6, -10) == -16
calculator в сигнатуре теста, находит одноимённую фикстуру и передаёт результат её вызова в тест. Каждый тест получает свой экземпляр.
6. Маркировки тестов в pytest
Маркировки — способ пометить тесты специальными декораторами, чтобы управлять их выполнением.
Пропуск тестов (@pytest.mark.skip)
@pytest.mark.skip(reason="Тест будет исправлен позже")
def test_sum_positive_nums():
calculator = Calculator()
assert calculator.sum(4, 5) == 9
Условный пропуск (@pytest.mark.skipif)
import sys
@pytest.mark.skipif(sys.version_info < (3, 8), reason="Требуется Python 3.8 или выше")
def test_sum_positive_nums():
calculator = Calculator()
assert calculator.sum(4, 5) == 9
Ожидаемый сбой (@pytest.mark.xfail)
@pytest.mark.xfail(strict=True, reason="Метод в процессе разработки")
def test_sum_positive_nums():
calculator = Calculator()
assert calculator.sum(4, 5) == 10 # Умышленная ошибка
Если тест провалится — он помечается xfail. Если неожиданно пройдёт — xpass.
Пользовательские маркеры
@pytest.mark.positive_test
def test_sum_positive_nums():
calculator = Calculator()
assert calculator.sum(4, 5) == 9
@pytest.mark.positive_test
def test_div_positive():
calculator = Calculator()
assert calculator.div(10, 2) == 5
Запуск по маркеру: pytest -m positive_test
Чтобы избежать предупреждений pytest о неизвестных маркерах, документируйте их в pytest.ini:
# pytest.ini
[pytest]
markers =
positive_test: Тесты для позитивных сценариев
Выборочный запуск тестов
# Запускать только тесты, в имени которых есть "sum"
pytest -k "sum"
# С помощью pytest.ini для постоянной фильтрации:
# [pytest]
# python_functions = *sum*