Единственный тест, который я пишу
Dec 04 2022
В инженерном мире почти постоянно ведутся разговоры о том, какие виды тестов лучше; модульные тесты, интеграционные тесты, сквозные тесты и так далее. Некоторое время назад я решил, что буду писать только один вид теста.
В инженерном мире почти постоянно ведутся разговоры о том, какие виды тестов лучше; модульные тесты, интеграционные тесты, сквозные тесты и так далее.
Некоторое время назад я решил, что буду писать только один вид теста.
Я не совсем уверен, что это аккуратно вписывается в любую из вышеперечисленных категорий. Возможно, «интеграционный тест» является наиболее правильным, но это не совсем его охватывает — не в последнюю очередь потому, что никто не может договориться о том, как на самом деле определить, что означают эти разные ярлыки.
Вот принципы, которым я следую:
- Я не пишу ни одного теста, пока у меня не будет определен четкий общедоступный интерфейс.
- Мои тесты должны максимально точно имитировать поведение реального пользователя . Это означает вызов только общедоступного API или, если это внешний интерфейс, разработанный для конечного пользователя, выполнение только того, что сделал бы конечный пользователь.
- Если функция или компонент не являются частью общедоступного интерфейса, я не тестирую их напрямую. Если невозможно вызвать его косвенно через какой-либо общедоступный путь, какова его цель?
- Никаких удаленных сетевых вызовов. Если это не вызов localhost (например, локальная тестовая база данных), то его необходимо имитировать. Мои тесты должны последовательно проходить без подключения к сети или Интернету.
- Никаких насмешек над внутренними путями кода. Мокать на границе сети — это здорово, но имитировать функции или API, которые существуют в кодовой базе, которую я тестирую, нельзя.
- Никакое состояние не переносилось в разные тесты. Если тест опирается на состояние из предыдущего теста или может каким-либо образом повлиять на это состояние, что-то пошло не так. Это не обязательно должно означать «очистить все состояние после каждого теста».
- Нет тестирования внутреннего состояния. Если мне нужно инициализировать или настроить какое-то внутреннее состояние вручную в моем тесте (без использования другого существующего общедоступного интерфейса), мой тест, вероятно, не будет хорошим.
- Нет тестирования деталей внутренней реализации. Если рефакторинг моего кода приведет к провалу теста, вероятно, это плохой тест.
- Никаких «модульных тестов», которые вызывают внутренние функции. Если я чувствую сильное желание протестировать подобные функции, их, вероятно, следует заранее разбить на отдельные автономные модули или пакеты с четким интерфейсом, полностью отделенным от какой-либо моей бизнес-логики.
- Никаких сквозных тестов, требующих запуска полного сервера и базы данных и нескольких служб и запуска их всех вместе, если только это не крайне целесообразно делать на моем локальном хосте.
- Я сосредотачиваюсь на «охвате вариантов использования», а не «охвате строк кода».
- Сначала напишите тест, если заранее ясно, как будет выглядеть публичный интерфейс. В противном случае сначала напишите код, а затем протестируйте его.
- Я нарушаю любое из приведенных выше правил, когда это лучше сделать, чем не писать тест или оставить вариант использования непроверенным.