Антипаттерны и флаки
Урок разбирает типичные ошибки в тестах и нестабильные «флаки»-тесты.
Флаки-тест (flaky) — тест, который на одном и том же коде иногда проходит, а иногда падает; он подрывает доверие ко всему набору.
Антипаттерн 1: тест на реализацию
Тест проверяет как код устроен внутри, а не что он делает. Признак — тест ломается при рефакторинге, который не меняет поведение. Лекарство: проверять вход → выход и наблюдаемые эффекты, а не приватные детали (см. урок «Что именно тестировать»).
Антипаттерн 2: флаки-тесты
Главные причины нестабильности:
- Реальное время и таймеры — гонки, зависимость от скорости машины. Лечится фейковыми таймерами.
- Случайность —
Math.random, случайные данные. Лечится моком или проверкой инварианта. - Зависимость от порядка — общее состояние между тестами. Лечится изоляцией и
beforeEach. - Реальная сеть — таймауты, недоступность. Лечится моками.
Флаки опаснее честно красного теста: команда привыкает «просто перезапустить» и в итоге игнорирует и настоящие падения.
Антипаттерн 3: тест без проверки (ложная зелень)
Тест есть, но в нём нет реального expect — он всегда зелёный и ничего не гарантирует. Покажем, чем это опасно:
function divide(a, b) {
return a / b; // баг: нет защиты от деления на 0
}
// ПЛОХОЙ "тест": вызвали, но ничего не проверили
function badTest() {
divide(10, 0); // результат проигнорирован
console.log('\u2713 badTest "прошёл" (но ничего не проверил!)');
}
// ХОРОШИЙ тест: есть проверка
function goodTest() {
const result = divide(10, 0);
const ok = Number.isFinite(result);
console.log((ok ? '\u2713 passed' : '\u2717 FAILED') +
': divide(10,0) даёт конечное число (получили ' + result + ')');
}
badTest();
goodTest();Вывод:
✓ badTest "прошёл" (но ничего не проверил!) ✗ FAILED: divide(10,0) даёт конечное число (получили Infinity)
Плохой тест зелёный и бесполезен. Хороший — ловит реальный баг (Infinity). Всегда добавляйте осмысленный expect.
Антипаттерн 4: хрупкость и переусложнение
- Логика в тесте (циклы, условия, вычисление ожидаемого) — тест сам может содержать баг. Ожидаемые значения лучше писать явно.
- Слишком много моков — тест проверяет моки, а не код. Если всё замокано, что вообще тестируется?
Итог
- Не тестируйте реализацию — только поведение.
- Флаки чаще всего от времени, случайности, порядка и сети; убирайте их источники.
- Тест без
expect— ложная зелень, бесполезен. - Избегайте логики в тестах и чрезмерного мокинга.