Автотесты «на пальцах»
Гигиена
Интеграционные тесты
Автотесты «на пальцах»
Гигиена
Интеграционные тесты
В предыдущих советах я рассказал о «механике» модульных тестов: что и как тестировать, что не тестировать. Получился набор правил, которых я придерживаюсь:
Тестировать только публичный интерфейс.
Проверять, что вернул запрос.
Проверять последствия вызова команды.
Использовать заглушки вместо внешних запросов.
Проверять факт вызова внешней команды.
Сегодня расскажу о гигиене в тестах: минимальном наборе правил, которых стоит придерживаться, чтобы писать хорошие тесты.
Пишите в едином стиле и используйте линтеры
Тесты — это тоже код. Как и обычный код, тесты без форматирования и структуры тяжело читать и мучительно поддерживать. В каше из проверок и зависимостей легко допустить ошибку: проверить не то или создать неправильную зависимость и получить бесполезный тест, который всегда проходит.
Чтобы минимизировать количество таких ошибок, программисты придумали стили кодирования — стандарты оформления кода. В них описывают, как форматировать, структурировать и организовывать код и комментарии, какую использовать систему именования, какого кода стоит избегать.
См. совет о линтерах
Чтобы за стилем кодирования следили роботы, а не люди, программисты придумали линтеры — программы, автоматически проверяющие код на соответствие выбранному стилю кодирования.
См. совет о линтерах
Для всех популярных фреймворков тестирования есть плагины к линтерам, которые проверяют специфичные для тестов вещи:
К сожалению, не всё можно проверить автоматически: линтер не сможет понять, насколько хорошо код покрыт проверками, нет ли лишних зависимостей, понятны ли человеку описания проверок. Поэтому помимо линтеров советую изучить сборники лучших практик тестирования:
Разделяйте фазы теста
Тесты состоят из трёх фаз: настройки, испытания и проверки. Во время настройки мы создаём нужные зависимости и заглушки, готовим модуль к тестированию. Во время испытания вызываем функции, которые хотим проверить. Во время проверки сверяем то, что получилось, с тем, что должно быть.
Чтобы быстрее находить и воспринимать эти фазы, отделяйте их друг от друга переводом строки:
// Плохо: всё в кучу
it('wipes user data from state', () => {
const state = { userName: 'Tony Stark', userFirstName: 'Tony', userEmail: 'tony@stark.com' }
expect(reducer(state, { type: 'SWITCH_TO_INITIAL_SCREEN' })).toEqual(jasmine.objectContaining({
userName: null,
userFirstName: null,
userEmail: null,
}))
})
// Хорошо: фазы отделены, видно, что и как проверяем
it('wipes user data from state', () => {
const state = { // Настройка
userName: 'Tony Stark',
userFirstName: 'Tony',
userEmail: 'tony@stark.com',
}
const newState = reducer(state, { type: 'SWITCH_TO_INITIAL_SCREEN' }) // Испытание
expect(newState).toEqual(jasmine.objectContaining({ // Проверка
userName: null,
userFirstName: null,
userEmail: null,
}))
})
Пишите для людей
Тесты читают люди. Чем человечнее, лаконичнее и понятнее они написаны, тем легче людям с ними работать. Используйте описания тестов, понятные человеку, а не машине:
// Плохо: бесполезное описание
it 'works'
// Хорошо
it 'sends welcome email to presentee'
// Плохо: говорим с машинами
it 'sets lock_status to nil'
// Хорошо
it 'unlocks next achievement'
// Плохо: опять говорим с машинами
it 'calls UsersMailer.reset_notification'
// Хорошо
it 'sends password reset instructions'
P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.