Всем привет!
Я бы хотел рассказать о том, как стал использовать генерацию функциональных сценариев, и показать, как это выглядит на реальном проекте.
Итак, в основном функциональное тестирование состоит из комбинаций действий (шагов), вроде таких:
Н-р такой сценарий:
- Launch browser chrome
- Open facebook page `https://facebook.com`
- Enter login `alex@gmail.com` to login field
- Enter password `alex123456` to submit field
- Click button `Enter`
- Check that user account page is opened
Число возможных комбинаций шагов - это факториал шагов n!, при условии что шаг встречается в тесте один раз. Для картинки выше это будет 8! = 40320. С одной стороны факториал дает неимоверно большое количество вариантов даже при небольшом количестве шагов, а с другой стороны не все последовательности шагов являются валидными, н-р:
Для генерации тестов и комбинирования шагов, помимо шагов, нужно учесть ограничивающие правила, чтобы избавиться от тестов с невалидными последовательностями шагов.
И вот как выглядит генерация и запуск тестов для фреймворка glace-js:
Пример с headless режимом:
И пример для glace-js плагина glace-proxy:
Безусловно, тесты из воздуха не появились. По-прежнему требуются затраты на написание кода шагов, а также декларирование правил взаимодействия шагов. Но теперь это стало занимать гораздо-гораздо меньше времени, чем если бы я попытался описать в коде все эти тесты, ломая голову над сценариями. Вместо этой рутины я теперь могу посвящать больше времени интересным задачам, доверим машине комплексное тестирование проекта.
И поскольку машина пытается создать как можно больше сценариев, еще один большой плюс, что я могу запустить и 100 и 1000 и 10000 уникальных тестов, всего лишь ослабив ограничения и сделав так:
Больше мне не приходится заниматься расширением тестов под новую функциональность. Все что мне нужно, это представить функциональность в виде шагов и задекларировать, чтобы генератор подхватил их.
Исходный код генератора GitHub - glacejs/glace-testgen: Documentation https://glacejs.github.io/glace-testgen.
Пример декларирования glace-js шагов, которые будут обработаны генератором:
https://github.com/glacejs/glace-js/blob/master/tests/e2e.steps.yaml.
Пояснения к ключевым словам декларирования:
-
income
- состояние системы, которое требуется для выполнения шага. Например, чтобы открыть веб-страницу, требуется чтобы браузер был запущен. -
outcome
- результат изменения системы после выполнения шага. Например после запуска браузера, состояние системы будет иметь запущенный браузер. -
incomplete
- список состояний системы, которые должны быть завершены в тесте, в противном случае тест будет исключен из результата генерации. Н-р в тесте, который включает запуск браузера, должен присутствовать шаг, чтобы закрыть браузер. -
complete
- список завершающих состояний системы дляincomplete
. Еслиincomplete
содержит несколько состояний в процессе генерации, н-рselenium server; launched browser
, то валидными будут тесты в которыхcomplete
будет иметь обратный порядокlaunched browser; selenium server
.
Некоторые используемые опции генератора:
-
--gen-steps-uniq
- Последовательность шагов, которая должна быть уникальной среди тестов. Н-р если--gen-steps-uniq=2
, то среди тестов:
Test #1:
- open https://yandex.ru
- open https://github.com
- open https://google.com
Test #2:
- open https://google.com
- open https://yandex.ru
- open https://github.com
Test #3:
- open https://github.com
- open https://google.com
- open https://yandex.ru
Test #3
будет исключен из результата, т.к. он содержит последовательности 2-х шагов, которые уже встречаются в предыдущих тестах:
- open https://github.com
- open https://google.com
- open https://google.com
- open https://yandex.ru
Но все эти 3 теста будут рассматриваться как уникальные при --gen-steps-uniq=3
или выше. По умолчанию этот параметр не ограничен. Это означает, что все шаги в тесте рассматриваются как уникальная последовательность. Практически достаточно задавать этот параметр в диапазоне от 1 до 5.
-
--gen-steps-limit
- Максимальное число шагов на один тест. По умолчанию не ограничено. Практически лучше настраивать после настройки--gen-tests-limit
и требуется редко. -
--gen-tests-limit
- Максимальное количество тестов, которые могут существовать на каждой итерации генерирования. Обычно конечный результат тестов включает меньшее количество после применения фильтров. Играя с этим параметром можно значительно сократить время генерации. Однако очень малое значение может привести к тому, что генератор не сможет построить граф шагов и вернет ошибку и список неиспользуемых шагов. -
--gen-steps-shuffle
- Перемешивать тесты во время генерации. Повышает рандомизацию последовательности шагов в тестах, но тесты будут отличаться от генерации к генерации. Практически вместе с этим флагом хорошо бы увеличить--gen-tests-limit
как минимум в 2 раза.
Несколько моментов, которые я понял, работая с генераторов автотестов:
- Это экономит мне кучу времени.
- Было достаточно использовать ключевые слова
income
,outcome
,incomplete
,complete
с простым описанием при декларировании, чтобы покрыть проект. - Не проблема задекларировать множество шагов, если они не имеют много зависимостей между собой.
- Я определенно доверяю сгенерированным автотестам, т.к. машина работает беспристрастно, надежно и помогла мне найти баги, которые я пропустил при ручном написании автотестов, в том числе баг в хроме (или в хромдрайвере).
Подводя итог, генератор тестов не может полностью заменить ручную работу в тестовом дизайне. Но это очень быстрый помощник, который может выполнять рутинную работу и дает мне возможность работать над творческими задачами.
Оригинал статьи Integration Tests Generating — Production Usage | by Sergei | Medium
P.S.
Быстрая генерация большого количества уникальных сценариев
21:07:23 user@comp ~/vega/projects/glace/glace-js (git::master)
;) ./node_modules/glace-testgen/bin/test-gen ./tests/e2e.steps.yaml --gen-steps-uniq 5 --gen-tests-limit 10000 --gen-output-file result
Generating tests from steps...
6260 tests are generated during 1m 28.9s
А так выглядит лог сгенерированного и выполненного автотеста:
2018-04-02T16:32:18.423Z - info: Selenium drivers are installed already
2018-04-02T16:32:18.424Z - info: Starting Xvfb...
2018-04-02T16:32:18.451Z - info: Xvfb is started
2018-04-02T16:32:18.452Z - info: Starting http proxy...
2018-04-02T16:32:18.452Z - info: Http proxy is started
2018-04-02T16:32:18.453Z - info: Starting global proxy...
2018-04-02T16:32:18.460Z - info: Global proxy is started
2018-04-02T16:32:18.460Z - info: Starting selenium server...
2018-04-02T16:32:19.382Z - info: Selenium server is started with PID 17627
2018-04-02T16:32:19.383Z - warn: Sleep 0.1 sec, reason: small sleep
2018-04-02T16:32:19.485Z - info: Launching browser via selenium...
2018-04-02T16:32:20.609Z - info: Setting browser viewport to [width=1066, height=600]...
2018-04-02T16:32:20.755Z - info: Browser viewport size is set
2018-04-02T16:32:20.755Z - info: Browser is launched
2018-04-02T16:32:20.761Z - info: Making screenshot with selenium...
2018-04-02T16:32:20.943Z - info: Screenshot is saved to /home/user/vega/projects/glace/glace-js/reports/test-case-3/screenshots/a7e60a04-ef82-49e3-ad87-61c554f1c122.png
2018-04-02T16:32:20.984Z - info: Enabling proxy cache...
2018-04-02T16:32:20.984Z - info: Proxy cache is enabled
2018-04-02T16:32:20.984Z - info: Openning URL https://github.com in browser...
2018-04-02T16:32:21.560Z - debug: Compare current URL https://github.com/ with expected https://github.com
2018-04-02T16:32:21.560Z - info: URL is opened
2018-04-02T16:32:21.561Z - info: Openning page 'index' in browser...
2018-04-02T16:32:21.562Z - info: Openning URL http://comp:38355/ in browser...
2018-04-02T16:32:21.582Z - debug: [cache] <<<< GET_comp:38355/
2018-04-02T16:32:21.616Z - debug: [cache] <<<< GET_yastatic.net/jquery/2.1.4/jquery.min.js
2018-04-02T16:32:21.627Z - debug: [cache] <<<< GET_yastatic.net/www/_/W/t/N_5RN5c2xfl3ktRMJTYZskdzU.js
2018-04-02T16:32:21.658Z - debug: [cache] <<<< GET_yastatic.net/lego/_/La6qi18Z8LwgnZdsAr1qy1GwCwo.gif
2018-04-02T16:32:21.663Z - debug: [cache] <<<< GET_yastatic.net/www/_/G/z/X-Uf2Fe6_qA9fD12e9Xz0ccTk.js
2018-04-02T16:32:21.665Z - debug: [cache] <<<< GET_yastatic.net/www/_/o/p/gUBBX8WZqmSesz-PjnRuK7msk.svg
2018-04-02T16:32:21.666Z - debug: [cache] <<<< GET_yastatic.net/islands/_/nJL92_8XGrQ8WN7LePOnzmpHzd4.svg
2018-04-02T16:32:21.666Z - debug: [cache] <<<< GET_yastatic.net/www/_/x/Q/xk8YidkhGjIGOrFm_dL5781YA.svg
2018-04-02T16:32:21.673Z - debug: [cache] <<<< GET_yastatic.net/www/_/k/8/gsSjWTalZ0Zl-yefsGisz0YJA.svg
2018-04-02T16:32:21.739Z - debug: [cache] <<<< GET_yastatic.net/s3/home/fonts/ys/1/text-regular.woff2
2018-04-02T16:32:21.746Z - debug: [cache] <<<< GET_yastatic.net/s3/home/fonts/ys/1/text-medium.woff2
2018-04-02T16:32:21.753Z - debug: [cache] <<<< GET_yastatic.net/s3/home/fonts/ys/1/text-bold.woff2
2018-04-02T16:32:21.762Z - debug: [cache] <<<< GET_yastatic.net/www/_/U/1/o7ckruVIskZcRWhFoDDc5rung.svg
2018-04-02T16:32:21.763Z - debug: [cache] <<<< GET_yastatic.net/www/_/I/D/GmxoaNBGBwZJQ_L6OxNu-vPTM.svg
2018-04-02T16:32:22.119Z - debug: [cache] <<<< GET_yastatic.net/www/_/j/N/Ot_3Gd2XFXa_hgeO0hMJKeGJk.css
2018-04-02T16:32:22.134Z - debug: [cache] <<<< GET_www.tns-counter.ru/V13a**9fb9b58fefe1406df3f42e73a0b740ba**yandex_ru/ru/CP1251/tmsec=yandex_main/0
2018-04-02T16:32:22.149Z - debug: [cache] <<<< GET_yastatic.net/www/_/B/c/up8XzIL8p_yNYKn2dSBPcPw3I.css
2018-04-02T16:32:22.219Z - debug: [cache] <<<< GET_kiks.yandex.ru/system/fc07.swf
2018-04-02T16:32:22.235Z - debug: Compare current URL http://comp:38355/ with expected http://comp:38355/
2018-04-02T16:32:22.235Z - info: URL is opened
2018-04-02T16:32:22.235Z - info: Page is opened
2018-04-02T16:32:22.236Z - info: Disabling proxy cache...
2018-04-02T16:32:22.236Z - info: Proxy cache is disabled
2018-04-02T16:32:22.238Z - info: Starting video recording...
2018-04-02T16:32:22.270Z - warn: Sleep 1 sec, reason: it needs a time to start recording
2018-04-02T16:32:23.272Z - info: Video recording is started
2018-04-02T16:32:23.273Z - info: Setting browser viewport to [width=1066, height=600]...
2018-04-02T16:32:23.415Z - info: Browser viewport size is set
2018-04-02T16:32:23.425Z - info: Starting to measure proxy responses...
2018-04-02T16:32:23.425Z - info: Proxy responses are measuring
2018-04-02T16:32:23.426Z - info: Stopping to measure proxy responses...
2018-04-02T16:32:23.426Z - info: Proxy responses are not measured
2018-04-02T16:32:23.426Z - info: Closing browser...
2018-04-02T16:32:23.481Z - warn: Sleep 1 sec, reason: webdriver process will be stopped
2018-04-02T16:32:24.483Z - info: Browser is closed
2018-04-02T16:32:24.483Z - info: Launching browser via selenium...
2018-04-02T16:32:24.836Z - info: Setting browser viewport to [width=1066, height=600]...
2018-04-02T16:32:24.973Z - info: Browser viewport size is set
2018-04-02T16:32:24.974Z - info: Browser is launched
2018-04-02T16:32:24.974Z - info: Stopping video recording...
2018-04-02T16:32:24.975Z - warn: Sleep 1 sec, reason: it needs a time to gather latest frames
2018-04-02T16:32:26.106Z - debug: avconv was stopped with code 255 and signal null
2018-04-02T16:32:26.107Z - info: Video recording is stopped
2018-04-02T16:32:26.107Z - info: Limiting proxy speed to 512 ...
2018-04-02T16:32:26.108Z - info: Proxy speed is limited
2018-04-02T16:32:26.108Z - info: Openning URL http://comp:38355 in browser...
2018-04-02T16:32:36.582Z - debug: Compare current URL http://comp:38355/ with expected http://comp:38355
2018-04-02T16:32:36.582Z - info: URL is opened
2018-04-02T16:32:36.584Z - info: Removing recorded video file...
2018-04-02T16:32:36.584Z - info: Recorded video file is removed
2018-04-02T16:32:36.585Z - info: Unlimiting proxy speed...
2018-04-02T16:32:36.586Z - info: Proxy speed is unlimited
2018-04-02T16:32:36.587Z - info: Closing browser...
2018-04-02T16:32:36.642Z - warn: Sleep 1 sec, reason: webdriver process will be stopped
2018-04-02T16:32:37.644Z - info: Browser is closed
2018-04-02T16:32:37.644Z - info: Stopping selenium server...
2018-04-02T16:32:37.974Z - debug: Selenium server was stopped with code 130 and signal null
2018-04-02T16:32:37.974Z - info: Selenium server is stopped
2018-04-02T16:32:37.976Z - info: Stopping global proxy...
2018-04-02T16:32:37.977Z - info: Global proxy is stopped
2018-04-02T16:32:37.978Z - info: Stopping http proxy...
2018-04-02T16:32:37.979Z - info: Http proxy is stopped
2018-04-02T16:32:37.981Z - info: Stopping Xvfb...
2018-04-02T16:32:37.989Z - info: Xvfb is stopped