Comments 14
А еще лучше был бы формат в виде советов с примерами, а не загадок, поскольку проблемных мест больше, чем указано )
На самом деле этот набор легко укладывается в короткий перечень рекомендаций, который можно выложить на конфлюенс и прикрепить временно в фронтовом чатике. И в любом случае эти вещи будут контролироваться в рамках код ревью, даже если нет строгой последовательности issue-PR-review.
А повысить качество написания тестов в команде удобнее на собственном примере, отталкиваясь от лучших практик, от того, как надо делать, а не как не надо. И обучалку-доклад-митап построить в виде "вот у нас есть такой кейз в нашем коде, и покрывать его тестами надо вот таким образом, как у меня (вот пермалинк на гитлаб). Это лучше, чем решение в лоб таймаутом по таким-то причинам." По крайней мере я так делал. С выкладыванием этого на конфлюенс. Что не отменяет короткого перечня рекомендаций по оформлению тестов)
Не логичнее ли вместо моков делать интеграционные тесты, которые хоть и сложнее, но всё же хотя бы реальные?
Логичнее отделять мух от котлет, т.е. делать юнит тесты с моками И интеграционные тесты с реальными связями.
Тесты с моками(не стабами) говорят о том, что на том или ином наборе компонент действительно ведет себя тем или иным способом. Позвал 5 раз функцию1, 15 раз функцию3 и др. Выполняется этот тест быстрее чем интеграционый. В разы быстрее!
Интеграционный тест показывает работу кода в реальных боевых условиях. Да он приближен к реальности больше, чем тест с моками, но и выполняется он значительно медленнее! И, если он нашел какую-то багу, значит не написан какой-то из тестов с моками и это можно сделать тем самым ускорить и улучшить процесс тестирования.
При тестах с моками можно увереннее говорить «Ошибка в компоненте1» или «Ошибка работы компонента2 в методе3 при пустой строке». Да, конечно что-то вы не сможете получить сразу, т.к. ненаписан тест. Но ведь все же итеративно!
Увидели багу, добавили тест. Поправили багу, зарефакторили, запустили тесты. Все ок? Вперед к другой задаче. Тест больше не нужен, т.к. уже не актуален после рефакторинга? ОК, выпилем его. Это же до боли привычный мир разработки
Сначала говорится, что если результат `require()` нужен только одному тесту, то его не нужно выносить наверх. Затем, спустя 10 пунктов, это объявляется антипаттерном и предлагается избавиться от `require()` в теле тестов.
Дело в том, что тестовые данные по хорошему нужно грузить не через `requiire`, а через стандартное чтение файла с парсингом. Иначе вы всё равно навсегда оставите его в памяти и сделаете потенциально мутируемым.
Так что в примере должно было быть чтение файла, а не `require`.
Правда, есть нюанс — `require` отрабатывает в разы быстрее, чем это комбо. Поэтому в продакшне обычно используется именно он для быстрого запуска приложения.
А есть какие-нибудь подтверждения, что такая загрузка данных локально в тесте вообще хоть что-то ускоряет?
По моей информации, V8 очень хорошо вычищает неиспользуемые значения из замыкания, и дополнительно помогать ему не нужно.
И ещё вопрос: откуда в тестах берутся гигабайты данных? Для проверки бизнес-логики столько не надо. Поэтому совет #4 выглядит как предложение сэкономить на спичках
А есть какие-нибудь подтверждения, что такая загрузка данных локально в тесте вообще хоть что-то ускоряет?
Не ускоряет, а позволяет не тратить лишнюю память.
По моей информации, V8 очень хорошо вычищает неиспользуемые значения из замыкания, и дополнительно помогать ему не нужно.
Так они очень даже используемые, и будут все подгружены в момент запуска тестов. Возможно, по мере прохождения тестов они и будут выгружаться — но вряд ли, да и поздно уже.
И ещё вопрос: откуда в тестах берутся гигабайты данных? Для проверки бизнес-логики столько не надо. Поэтому совет #4 выглядит как предложение сэкономить на спичках
Всё зависит от объёма проекта, количества тестов, и данных, которыми он занимается. Так что в большинстве случае это, конечно, будет экономия на спичках. Но почему бы так не делать, если это не заставляет предпринимать лишние усилия.
Упс, уже спросили.
18.
Тест, который проверяет, что тестируемый метод работает строго определенным образом: обращается к другим методам в строго определенном порядке и не обращается ни к чему еще.
Неприятные ошибки при написании юнит тестов