Как стать автором
Обновить

Комментарии 16

отличная статья. недавно переводил руби-проект с тестами на капибаре с веб-китовского движка на селениум — получил все кейсы, которые у вас в статье, и еще немножко :)
вишенкой на торте был случай, когда локально на маке все работает, а в докере под дебианом все падает. оказалось, что между двумя кликабельными элементами была некликабельная зона, и хром под дебианом именно туда и кликал

Меня сейчас закидают тряпками, но я, всё же, выскажусь.
Все эти UI-тесты с эмуляторами реальных сервисов — это прекрасно. Но в 99% случаев не нужны, так как они могут спокойно проверяться без UI (селениум меняется на jasmine), calabash… ещё на что-нибудь другое. Не эмулируйте сервисы вообще, обходитесь в тестах без них.
UI-тесты (селениум, калабаш, эспрессо) — это финальный шаг, интеграционные тесты, их должно быть очень мало. Но именно они могут быть нестабильными. Главное, чтобы они были понятными и выдавали очевидные сообщения.
Пример: вы проверяете как работают платежи в релизной версии приложения и внезапно агрегатор выдаёт вам таймаут — что вы бы ожидали от автоматизированного сценария?
Лично я вижу два выхода:
1) сказать "ой, ну это не наша ошибка, наше приложение ведь нормально отработало"… и это будет flaky тест, только который вы выполнили руками
2) пусть упадёт автоматический сценарий, который сообщит вам, что отвалился платёжный гейт и проверить сценарий не представляется возможным. Хотите довериться своему всемогущему эмулятору, который показывал, что платёж будет проходить? Оцените риски и (не)релизьтесь. Не хотите? Подождите, когда гейт заработает и проверьте отвалившиеся сценарии.
Flaky — это не так плохо. Плохо — когда непонятно, почему flaky.

Я абсолютно согласен с тем, что код надо максимально покрывать юнит-тестами, а не UI-тестами. В том числе юнит-тестами JavaScript кода, отвечающего за отрисовку UI (Jasmine, Karma, вот это всё). Я сам всегда об этом говорю на конференциях.

Но этого недостаточно. Всё равно нужен слой UI-тестов, которые проверят, что всё приложение в целом работает. Без них можно обойтись только в сравнительно маленьких проектах, которые легко прокликать руками после каждого изменения.

P.S. Кстати, вы путаете одну вещь. Конкретно вот это утверждение неверно:
> Не эмулируйте сервисы вообще, обходитесь в тестах без них.
Без них в тестах нельзя. Даже в юнит-тестах всё равно нужно делать эмуляторы зависимостей (моки, стабы и т.п.), просто они делаются по-другому. И гораздо дешевле.

P.P.S. Описанный кейс с платёжным агрегатором разумный, но в моей практике это происходит по-другому. Обычно, когда агрегатор падает в тестовой среде, нам говорят «да, в тестовой среде мы его обновляем, это займёт неделю. Но в продакшине всё точно работает.» Или «на тестовом сервере просто железо слабоватое, и там сейчас другая команда нагрузку запустила на несколько часов». А ты не можешь ждать, тебе надо релизиться. Вот в такой ситуации разумно свой функционал тестировать на эмуляторах, а с реальным сервисом как-то отдельно потом проверить (да хоть даже вручную), когда все свои ошибки уже точно исправлены.
Без них в тестах нельзя. Даже в юнит-тестах всё равно нужно делать эмуляторы зависимостей (моки, стабы и т.п.), просто они делаются по-другому. И гораздо дешевле.

конечно! это приёмные тесты. Просто часто делают перекос в эту сторону и становится "1000 тестов на селениуме и 1000 юнит-тестов".


Без них в тестах нельзя. Даже в юнит-тестах всё равно нужно делать эмуляторы зависимостей (моки, стабы и т.п.), просто они делаются по-другому. И гораздо дешевле.

Ну моки и эмуляторы, всё-таки, разные вещи :) Я имел в виду именно эмуляторы в низкоуровневых тестах


Обычно, когда агрегатор падает в тестовой среде, нам говорят «да, в тестовой среде мы его обновляем, это займёт неделю.

Если у вас релиз, который не затрагивает интеграцию с агрегатором, то всё верно, согласен с вами, так и делается. А если переделана вся интеграция, то на ооооочень не хочется складывать все яйца в одну корзину "мы тут и интерацию написали, а ещё и пару багов в собственном эмуляторе пэйпала поправили". Ага. Так я и поверим им, что пару багов не добавили.

А поясните, плиз, чем мок от эмулятора отличается?

Кто пользуется селенидом — подскажите, что имеется ввиду под умными ожиданиями до 4-ёх секунд. Это как-то отличается от implicit wait?
Да, это сильно отличается от implicit wait. На SeleniumCamp 2018 был целый доклад об этом: seleniumcamp.com/talk/deep-dive-into-selenium-waits

Если вкратце — implicit wait умеет ждать только наступления одного события: что элемент появится в DOM. Селенидовские ожидания могут ждать чего угодно (например, что элемент исчезнет из DOM).
Но этого тогда уже не implicit получается? В селениуме явные ожидания и тоже ждать чего угодно, просто у selenide для этого уже есть api?

PS Спасибо за доклад — интересно )

Селенидрвские ожидания — и не implicit, и не explicit. Можно сказать, они взяли лучшее от обоих видов. На implicit wait они похоже тем, что их не надо как-то специально вызывать — они срабатывают автоматически всегда. А на explicit wait похожи тем, что ждут именно того, что тебе нужно.


И да, api для их вызова в селениде гораздо компактнее.

Хех, а как же они понимают чего мне надо? )
Я видео посмотрел )
Это просто тогдя явные получаются. Ну, я концепт понял, спасибо )
Ждём очередные доклады )
Да, в некотором роде явные: ты явно указываешь условие.
Но качественное отличие от селениумовских «explicit waits» в том, что ты не должен писать какой-то дополнительный код для этого. А главное — ты не можешь ЗАБЫТЬ прописать wait. Ты не должен тратить мыслетопливо на то, чтобы решать каждый раз: а нужно ли ожидание в каждой конкретной строчке? Ведь как известно, именно мыслетопливо — самый главный ограничительный ресурс в наше деле.
Этот код обычно каждый пишет сам куда-то в хелперы или в уровень компонентов. Когда он есть из коробки и работает, то это +
Вообще подход интересный.
Полностью согласен про мыслетопливо )

Отличная статья! По примеру 4: есть аналогичная фишка в Python (разница между time.time() и timeit.default_timer() — такая же, и мы это видели отнюдь не в UI тестах, мы железо тестируем), ещё там же заметил опечатку в коде: в первом куске long en (должно быть long end).

Опечатку поправили, спасибо!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий