Инструменты и как начать тестировать проект

Карта популярных инструментов и практичный план: с чего начать на проекте, где тестов пока нет.

Инструменты различаются по экосистеме и уровню пирамиды, но идеи у них общие: задать вход, выполнить, проверить ожидание. Освоив принципы, любой фреймворк осваивается быстро.

Инструменты по экосистемам

ЭкосистемаUnit / integrationE2E / браузер
Pythonpytest, unittestPlaywright, Selenium
Java / KotlinJUnit, TestNGSelenium, Playwright
JavaScript / TypeScriptJest, VitestPlaywright, Cypress
C# / .NETxUnit, NUnitPlaywright, Selenium

Названия разные, но в каждом есть способ объявить тест, выполнить действие и проверить результат (assert/expect). Поэтому курс строился на чистом assert: это «эсперанто» тестирования — понятно везде.

Как начать тестировать проект без тестов

Браться сразу за «покрыть всё» — путь к выгоранию. Действуйте прагматично.

  1. Поставьте фреймворк и напишите один тест. Любой, самый простой — главное, чтобы запуск тестов в проекте заработал.
  2. Начните с критичного. Покройте денежную логику, авторизацию, расчёты — то, где ошибка дороже всего.
  3. Пишите тест на каждый найденный баг. Нашли дефект — сначала тест, который его воспроизводит (красный), потом фикс (зелёный). Баг больше не вернётся.
  4. Тестируйте новый код по мере написания. Не пытайтесь покрыть всё старое разом — наращивайте покрытие там, где трогаете код.
  5. Включите CI. Пусть тесты бегут на каждый push автоматически.

Тест на воспроизведение бага — на практике

Классический приём: дефект найден — фиксируем его тестом, потом чиним. Тест навсегда защищает от повторения (это и есть регрессионный тест).

# Нашли баг: функция падала на пустом списке. Сначала ТЕСТ на этот случай.
def average(nums):
    if not nums:          # фикс: обрабатываем пустой список
        return 0
    return sum(nums) / len(nums)


# Регрессионный тест, закрывающий найденный баг
assert average([2, 4, 6]) == 4
assert average([]) == 0          # раньше тут была ошибка деления на ноль
print("Баг закрыт тестом — деление на ноль на пустом списке больше не вернётся")

Вывод:

Баг закрыт тестом — деление на ноль на пустом списке больше не вернётся

Чек-лист тестировщика

  • Проверены и «счастливый путь», и негативные сценарии, и границы.
  • У каждого теста есть явный ожидаемый результат (assert), один тест — одна мысль.
  • Тесты быстрые, изолированные, детерминированные, читаемые (FIRST).
  • Критичная логика (деньги, доступы) покрыта тщательнее прочего.
  • Каждый найденный баг закрыт регрессионным тестом.
  • Тесты запускаются автоматически в CI на каждое изменение.
  • Покрытие используется как подсказка о пробелах, а не как самоцель.

Итог

  • Инструменты разных экосистем (pytest/JUnit/Jest/Playwright) держатся на общих идеях.
  • Начинать тестировать проект — прагматично: критичное, баги-в-тесты, новый код, CI.
  • Чек-лист собирает воедино всё, чему учил курс.
Проверьте себя
1. Почему освоив принципы, легко перейти на любой тест-фреймворк?
AВсе фреймворки называются одинаково
BВ каждом есть способ задать вход, выполнить действие и проверить ожидание — идеи общие
CВсе они написаны на Python
DФреймворки не нужны вовсе
2. С чего разумно начать тестировать проект без тестов?
AСразу добиться 100% покрытия всего старого кода
BПоставить фреймворк, покрыть критичное и писать тест на каждый найденный баг
CУдалить старый код
DТестировать только тривиальные геттеры
3. Зачем писать тест на каждый найденный баг?
AЧтобы увеличить число тестов для отчёта
BЧтобы зафиксировать дефект и не дать ему вернуться (регрессионная защита)
CЧтобы замедлить разработку
DЭто бессмысленно
Поддержать проект