Всем привет, меня зовут Виталий, я являюсь 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

Зачем?

  1. Ытобы не писать боилерплеит из проекта в проект для автоматизации(например, часто на проектах перед взаимоействием с элементом пишут функцию доскроливания до взаиводействующего элемента).

  2. Чтобы “не кодеры” моги разобраться в автоматизации без привязки к конкретному ЯП.

  3. Чтобы не настраивать интеграции для каждого проекта по новой(хотелось бы сделать интеграции из коробки, но пока это в планах)

  4. Чтобы легко можно было стартануть автоматизацию на проекте, где нет автоматизаторов.

  5. Чтобы Визуализировать прогресс автоматизации для не инженеров(проект менеджера например).

Что решает sqrt.app?

  1. ЯП независимое решение.

  2. Освоить yaml и/или визуальный графический интерфейс проще чем ЯП со всеми его конструкциями(с развитием проекта это может изменится)

  3. Запуск автоматизации всего 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

Перед тем как показать скриншоты самой программы, давайте немного поговорим про сущности.

Существует 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

После написания сценария, его можно запустить либо через режим “отладки”, либо через запуск конфигурации. Это очень удобно при необходимости прогнать только что написанный тест.

Запуск в режиме "отладки"
Запуск в режиме "отладки"

После того как ваш тест готов - вы можете запустить его в режиме "отладки" и затем увидеть прогресс на текущем шаге и скриншоты напротив каждого шага.

Запуск сценария в режиме "отладки"
Запуск сценария в режиме "отладки"

Также тесты можно запускать через конфигурации.

Configurations viewer
Configurations viewer

После выбора файлов сценария и(или) групп можно также задавать специфичные настройки, такие как разрешение экрана, геолокация, и т.д.

Configurations viewer. Settings
Configurations viewer. Settings

Вот и все, что хотелось бы показать/рассказать в данной обзорной статье.

В преддверии вопросов в комментариях сразу отвечу:

  • Продукт пока сырой и есть ооочень много проблем. Начиная от установки и заканчивая запуском сценария.

  • Много из мира веба не реализовано (например работа с диалоговыми окнами), но это пока что.

  • Переменные можно создать только внутри сценария, “извне”(например 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. Мы в поисках кампаний, кому потенциально интересно внедрить автоматизацию тестирования у себя. С нас приоритетная поддержка при секретном слове: «от Хабра»:)

Комментарии (4)


  1. ivanokunev
    00.00.0000 00:00

    Идея отличная, но мне было бы интересно еще несколько деталей
    1) Предусловия - например юзер авторизован/ юзер авторизован как админ / юзер не авторизован (на геркине есть возможность условно обработать это в Given)
    2) Так как делаются скриншоты - можно ли их сравнить с предыдущими и дать оценку отличий?

    p.s. репо пуст


    1. Vitalics Автор
      00.00.0000 00:00

      Спасибо за комментарий.

      1) работа с предусловиями скорее всего будет реализована как система “компонентов”. Т.е. пользователь 1 раз проходит по, например логину. А затем будет возможность объеденить в “компонент логин”. Тут много пограничных случаев надо продумывать, поэтому только мысли.

      2) Работает условно - page.screenshot() . Возможности сравнивать скриншоты пока что нет между собой.

      3) Репо не пуст. Поскольку участники данного проекта не готовы выставить код на всеобщее обозрение в опен сорс, то ссылка ведет на публичный issue tracker.


      1. ivanokunev
        00.00.0000 00:00

        По п.3 - понял, думал "публичный репо" это какая-то коммьюнити версия, а это issue-tracker


        1. Vitalics Автор
          00.00.0000 00:00

          извиняюсь что ввел в заблуждение, исправил это в статье