Всем привет, меня зовут Виталий, я являюсь Test automation engineer и по совместительству один из создателей библиотеки sqrt.app. В IT-сфере я около 6 лет и успел повидать много говна решений, но сегодня я бы хотел рассказать про то - почему любому инженеру будет полезно использовать данный тул.
Итак, для начала хотелось бы начать с вопроса: "а как и почему появилось данное решение?"
Ответ - решение родилось еще тогда, когда я пришел как test automation engineer на один из проектов и там была автоматизация тестирования на Node.js. Мне довелось принять участие в рефакторинге текущего решения и написание новых сценариев. После того проекта был еще один, а потом еше, и еще, и еще несколько. Как и любому инженеру, мне приходилось решать подобные задачи, но уже немного погружаясь в Java. И при изучении автоматизации для этого ЯП и пришел к тому, что мы имеем.
Конечно, вы можете сказать мне, что есть BDD решения, где пользователь пишет сценарии автомацизации на языке “бизнесса”. Однако, реальность немного разочаровывающая - ведь если вспомним, как пишутся сценарии на cucumber - то мы получим что-то такое:
Feature: User Login
As a registered user
I want to log in to the website
So that I can access my account
Scenario: Successful login
Given I am on the login page
When I enter valid credentials
And click the login button
Then I should be redirected to my account page
И JS код будет примерно таким:
const { Given, When, Then } = require('cucumber');
const { expect } = require('chai');
const LoginPage = require('../pages/login.page');
const DashboardPage = require('../pages/dashboard.page');
Given('I am on the login page', async function () {
await LoginPage.open();
});
When('I enter valid credentials', async function () {
await LoginPage.login('username', 'password');
});
When('click the login button', async function () {
await LoginPage.clickLoginButton();
});
Then('I should be redirected to my account page', async function () {
expect(await DashboardPage.isOnDashboardPage()).to.be.true;
});
И тут мы сталкиваемся с тем, что “бизнесс” язык типа gherkin не может существовать без описание “кодом”. Поэтому данную идею я отмел т.к. в идеале хотелось бы, чтобы кода было как можно меньше и при этом был понятным "не кодеру".
Также вспоминаем, что много фреимворков тестирования портированы на несколько языков(тот же selenium, playwright) и API у них всех похожее. И вот тут мне хотелось бы отойти в сторону и рассказать про развитие CI/CD паиплаинов, в которых запускаются тесты. Сейчас многие CI/CD вендоры используют платформо-независимый язык разметки YAML(Yet another markup language), например вот как выглядит github action.
Пример пайплайна в GitHub Actions
name: Node.js CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 15.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npm test
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
Надеюсь, что данный код объяснений не требует,
Так вот, я пришел к выводу, что steps в github actions подобны шагам в тестировании(один из принципов тестирования - наличие конечного и предсказуемого результата)
Поэтому я представляю вашему вниманию - sqrt.app
Зачем?
Ытобы не писать боилерплеит из проекта в проект для автоматизации(например, часто на проектах перед взаимоействием с элементом пишут функцию доскроливания до взаиводействующего элемента).
Чтобы “не кодеры” моги разобраться в автоматизации без привязки к конкретному ЯП.
Чтобы не настраивать интеграции для каждого проекта по новой(хотелось бы сделать интеграции из коробки, но пока это в планах)
Чтобы легко можно было стартануть автоматизацию на проекте, где нет автоматизаторов.
Чтобы Визуализировать прогресс автоматизации для не инженеров(проект менеджера например).
Что решает sqrt.app?
ЯП независимое решение.
Освоить yaml и/или визуальный графический интерфейс проще чем ЯП со всеми его конструкциями(с развитием проекта это может изменится)
Запуск автоматизации всего 1 консольной командой и без особых усилий (необходим только node.js)
Итак, sqrt.app - фреимворк или же готовое решение для вашей автоматизации тестирования.
Как установить?
npm install @sqrt.app/sqrt
Запустить можно как в “одно поточном” режиме, так и в демоне (докера пока нет, но мы работаем над этим:) )
#! однопоточный режим
sqrt start
#! "демон процесс"
sqrt start -d
Кстати, запуск через демон-процесс очень удобен на машине “заказчика” или ci/cd систем, таких как jenkins который работает 24/7.
Убить демон-процесс можно через команду:
sqrt down
Команда sqrt start
создаст папку .flows
в той директории, где и запущена у вас консоль. А если такой папки нет, то команда start
также создаст 2 конфигурации по умолчанию (для запуска одного сценария и для одной группы).
После выполнения команды start
можно открыть UI и создать сценарий.
![welcome screen welcome screen](https://habrastorage.org/getpro/habr/upload_files/283/d23/cbd/283d23cbddc609693826062c972bdfbe.png)
Перед тем как показать скриншоты самой программы, давайте немного поговорим про сущности.
Существует 3 сущности: конфигурации, группы и сценарии. О каждом мы сейчас и поговорим:
Конфигурации - это набор настроек: "что именно запускать" и "с какими параметрами запускать", например
headess: true
.
Пример YAML конфигурации:
# filename: .flows/configurations/configuration-example.yml
id: configuration-example
scenarios:
- "scenario-1"
- "scenario-2"
# ... и прочие сценарии
# также может быть здесь добавлена целая группа
# Важно: должно быть поле либо scenario либо groups, может быть и groups и scenario одновременно
groups:
- "group-1"
- "group-2"
name: Custom configuration for many groups at once
settings:
headless: true # запуск браузера "без головы"
locale: "ru-RU" # по имолчанию не задано
Группы - это набор сценариев объединенных по какому-то признаку. Хоть сценарий может быть без группы, однако такое может встречается редко - то данный сценарий не отобразится у пользователя на UI.
Группы для страницы логина могут выглядеть так:
# # filename: .flows/groups/group-login.yml
scenarios: # обязательное поля
- "scenario-login-success"
- "scenario-login-failure"
name: Login group
id: group-login
createdAt: 1670452907227 # эти поля вычесляются сами
updatedAt: 1670452907227 # эти поля вычесляются сами
Тест или сценарий - это шаги тестов: "что открыть", "куда кликнуть" и т.д.
# filename: .flows/scenarios/example-test.yml
name: Example test
description: The internet app for input
createdAt: 1670693418092
updatedAt: 1679482575603
steps:
# "name" у любого "степа" опционально, но желательно
# 1 открытие бразуерной "сессии"
- action: automation/web/session/new
# 2 открытие саита
- action: automation/web/navigation/goto
name: Open application
params:
url: https://the-internet.herokuapp.com
# 3 - кликаем по кнопке, которая откроет новую страницу
- action: automation/web/element/click
name: Navigate to the "Input challange" page
params:
selector: a[href="/inputs"]
waitForNavigation: true #если клик приводит к редиректу(открытию новой страницы), то краине рекомендуется ставить эту настройку
# Если не включать настройку - то в следующем шаге браузер МОЖЕТ искать элементы еще до того как страница загрузится
# 4 - сохраняем селектор инпута как переменную, пригодится :)
- action: automation/web/element/find
name: Get Input element
params:
selector: input[type="number"]
saveAs: ${{inputElement}}
# 5 - задаем инпуту значение 123
- action: automation/web/element/typeText
name: set Element value "123"
params:
value: 123
selector: input[type=number]
# 6 - запоминаем значение с инпута
- action: automation/web/element/getInputValue
name: Get input value
params:
saveAs: ${{inputValue}}
selector: input[type=number]
# 7 - проверяем что в инпуте сохранено значение 123
- action: automation/assert/equal
name: Expect that the input value is equal to "123"
params:
actual: ${{inputValue}}
expected: "123"
- action: automation/web/session/close
Давайте посмотрим, как данный сценарий будет выглядеть на UI. После выполнения команды sqrt start
можно открыть юай и посмотреть сценарий.
![Scenario viewer Scenario viewer](https://habrastorage.org/getpro/habr/upload_files/1d5/e3c/218/1d5e3c2184093ebb159fcda44e055011.png)
После написания сценария, его можно запустить либо через режим “отладки”, либо через запуск конфигурации. Это очень удобно при необходимости прогнать только что написанный тест.
![Запуск в режиме "отладки" Запуск в режиме "отладки"](https://habrastorage.org/getpro/habr/upload_files/56c/21b/2c6/56c21b2c672aa9f3be064ba0ebc0ac36.png)
После того как ваш тест готов - вы можете запустить его в режиме "отладки" и затем увидеть прогресс на текущем шаге и скриншоты напротив каждого шага.
![Запуск сценария в режиме "отладки" Запуск сценария в режиме "отладки"](https://habrastorage.org/getpro/habr/upload_files/c2e/255/92a/c2e25592ac8101eb36f80212911661cb.png)
Также тесты можно запускать через конфигурации.
![Configurations viewer Configurations viewer](https://habrastorage.org/getpro/habr/upload_files/112/455/3bd/1124553bddcaf2be6126abdd69ce87c1.png)
После выбора файлов сценария и(или) групп можно также задавать специфичные настройки, такие как разрешение экрана, геолокация, и т.д.
![Configurations viewer. Settings Configurations viewer. Settings](https://habrastorage.org/getpro/habr/upload_files/7e5/5c2/983/7e55c2983f179d0d1a1d48bf717d4664.png)
Вот и все, что хотелось бы показать/рассказать в данной обзорной статье.
В преддверии вопросов в комментариях сразу отвечу:
Продукт пока сырой и есть ооочень много проблем. Начиная от установки и заканчивая запуском сценария.
Много из мира веба не реализовано (например работа с диалоговыми окнами), но это пока что.
Переменные можно создать только внутри сценария, “извне”(например environment) не поддерживаются. Мы исправим это недоразумение с версией 0.2.
Докера пока что нету, надо смерится с этим, хоть в документации и есть установка через докер, однако, образ не задеплоен.
Хочется сделать импорт и экспорт "из" и "в" кодовую базу, но пока не представляем как это сделать. Если есть идеи как, хотя бы на бумаге, такое реализовать - милости прошу ко мне в личку telegram - @sqrtapp.
Yaml файлы не поддерживаются с расширением
yaml
(это пока что), только расширениеyml
.Сценарии можно писать как «кодом» (в yaml структуре), так и визуально.
Жду аргументированной критики в комментариях, а еще лучше - фича реквесты и баг репорты в нашем публичном issue tracker.
Документацию можно найти по ссылке: https://sqrt.app/docs/get-started/installation/.
P.S. пока планы наполеоновские и хочется много и всего, но увы в сутках всего 24 часа. Мы также не можем сосредоточится исключительно на баг фиксах и новом функционале из‑за того что, мы делаем продукт «по вечерам». Планируем выход в SAAS, чтобы можно было пощупать продукт без установки пакета.
P.P.S. Мы в поисках кампаний, кому потенциально интересно внедрить автоматизацию тестирования у себя. С нас приоритетная поддержка при секретном слове: «от Хабра»:)
ivanokunev
Идея отличная, но мне было бы интересно еще несколько деталей
1) Предусловия - например юзер авторизован/ юзер авторизован как админ / юзер не авторизован (на геркине есть возможность условно обработать это в Given)
2) Так как делаются скриншоты - можно ли их сравнить с предыдущими и дать оценку отличий?
p.s. репо пуст
Vitalics Автор
Спасибо за комментарий.
1) работа с предусловиями скорее всего будет реализована как система “компонентов”. Т.е. пользователь 1 раз проходит по, например логину. А затем будет возможность объеденить в “компонент логин”. Тут много пограничных случаев надо продумывать, поэтому только мысли.
2) Работает условно -
page.screenshot()
. Возможности сравнивать скриншоты пока что нет между собой.3) Репо не пуст. Поскольку участники данного проекта не готовы выставить код на всеобщее обозрение в опен сорс, то ссылка ведет на публичный issue tracker.
ivanokunev
По п.3 - понял, думал "публичный репо" это какая-то коммьюнити версия, а это issue-tracker
Vitalics Автор
извиняюсь что ввел в заблуждение, исправил это в статье