Что такое модульный тест
Модульный тест (unit test) — это небольшая программа, которая проверяет одну часть вашего кода, обычно одну функцию. Вы запускаете тесты после каждого изменения; если изменение что-то ломает, тест сразу сообщает вам об этом — раньше, чем это заметят ваши пользователи.
Стандартный инструмент в мире Python — pytest. Он устанавливается один раз командой pip install pytest и не требует шаблонного кода: тест — это обычная функция, а проверка — обычная инструкция assert.
Кроме того, тесты делают изменения безопасными: с хорошими тестами вы можете переписать функцию и за секунды узнать, ведёт ли она себя по-прежнему.
Тестовые файлы и тестовые функции
Два правила именования делают тест тестом:
1. Имя файла начинается с test_ — для calc.py вы пишете test_calc.py. pytest ищет в папке файлы с такими именами (имена, оканчивающиеся на _test.py, тоже подходят) и запускает только их.
2. Имя функции начинается с test_, и функция не принимает аргументов — def test_add():. Функции без этого префикса не собираются, поэтому вспомогательные функции могут находиться в том же файле.
Внутри теста вы вызываете функцию, сравниваете то, что получили, с тем, что ожидаете, и позволяете assert сообщить о разнице. Не прошедший assert вызывает ошибку, которая помечает тест как проваленный; если ошибки нет, тест проходит.
Первый проходящий тест
test_add вызывает add(2, 3) и сравнивает результат с 5 в одном assert. Значения совпадают, поэтому ошибки нет и тест проходит: в строке написано PASSED, а запуск заканчивается строкой 1 passed.
Вывод: полная программа на Python
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
Проваленный тест
В этой функции add есть ошибка — она умножает. Тест это обнаруживает: pytest повторно выводит не прошедшую строку assert, показывает значения с обеих сторон — assert 6 == 5 — и запуск заканчивается строкой 1 failed.
Вывод: полная программа на Python
# В add есть ошибка: она умножает вместо сложения.
def add(a, b):
return a * b
def test_add():
got = add(2, 3)
assert got == 5
Запуск тестов
python3 -m pytest запускает все тестовые файлы в текущей папке (если pytest есть в вашем PATH, то же самое делает просто pytest). Вывод по умолчанию краткий: одна точка на каждый пройденный тест и строка с итогами.
pytest -v (подробный режим) перечисляет все тесты по имени и пишет после каждого PASSED или FAILED. Используйте его, чтобы увидеть, что на самом деле было запущено. Если указать имя файла, pytest test_calc.py запустит только этот файл.
Два теста, подробный вывод
В файле две тестовые функции — по одной на каждую проверяемую функцию. С -v каждая выводится на отдельной строке — видно, что обе были запущены и обе прошли, а в итогах написано 2 passed.
Вывод: полная программа на Python
def double(n):
return n * 2
def half(n):
return n // 2
def test_double():
assert double(4) == 8
def test_half():
assert half(8) == 4