Привет! Меня зовут Евгений Константинов. Я занимаюсь разработкой инструментов автоматического тестирования в Яндексе. В этой статье хочу рассказать про историю создания инструмента Testplane, который предназначен для тестирования пользовательских сценариев во фронтенде и теперь доступен в опенсорсе.

Testplane поможет вам:

  • протестировать разные сценарии в любом браузере; 

  • проверить вёрстку с помощью скриншотного тестирования; 

  • выполнить тестирование ваших React-компонентов;

  • запустить клиентские unit-тесты в контексте браузера. 

Как всё начиналось

Всё началось в далёком 2014 году, когда внутри Яндекса развивалась библиотека общих компонентов под названием «Лего», а снаружи — библиотека компонентов БЭМ. И там, и там реализовывались готовые блоки с вёрсткой, которые каким-то образом нужно было тестировать. Самый подходящий для этого способ — сделать скриншот компонента и сравнить его в формате «было/стало». Но после долгих поисков в интернете мы не нашли готового решения, с помощью которого можно было бы легко и быстро написать тесты на JavaScript, выполнить их в браузере и посмотреть результаты в отчёте.

В этот момент и появилась Gemini — утилита для регрессионного тестирования внешнего вида веб-страниц. У инструмента были максимально простой (но в то же время ограниченный) API, собственная реализация скриншотного сравнения (в том числе и патент на способ тестирования) и отчёт для анализа результатов. Этого с головой хватило, чтобы покрыть все основные кейсы при тестировании интерфейсов.

Но время шло, и требования к тестированию менялись. Одних скриншотов стало не хватать — хотелось большего. А именно — тестировать реальные пользовательские сценарии. Да, большинство сценариев можно проверить с помощью скриншотов (например, что в поля вставили нужные данные), но очевидно, что такое тестирование избыточно и не всегда удобно. Поэтому в 2016 году мы опубликовали новый инструмент Hermione. 

Этот инструмент представлял из себя композицию из трёх инструментов: Gemini, Webdriverio и Mocha. В этой связке от Gemini мы получили скриншотное тестирование со всеми нашими наработками, от Webdriverio — богатый API по взаимодействию с браузером, а от Mocha — привычный для пользователей интерфейс написания тестов.

Почему выходим в опенсорс

Долгое время основными пользователями Hermione были внутренние сервисы, и его продвижением снаружи мы никогда особо не занимались, хоть инструмент и был в опенсорсе с 2016 года. Для новых разработчиков, приходящих снаружи, это был совершенно новый инструмент. К тому же поиск по слову Hermione чаще всего выдаёт в основном только историю героини книг Джоан Роулинг.

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

Подробно про то, как правильно выходить в опенсорс, я описывать не буду. Вместо этого просто приглашаю всех заинтересовавшихся смотреть трансляцию Yandex Open Source Jam, на которой вы сможете узнать в том числе нашу историю. Однако скажу, что в результате ребрендинга появился новый продукт под названием Testplane.

Кто такой этот ваш Testplane и в чём его особенность?

На данный момент наш инструмент позволяет решать сразу несколько задач тестирования — проверять пользовательские сценарии в браузере, находить баги в верстке с помощью скриншотного тестирования, писать тесты на компоненты (например, на React) или запускать обычные unit-тесты в браузере.

Сами тесты можно писать в знакомом для многих синтаксисе. Например, так выглядит простой тест:

describe("test", () => {
    it("example", async ({browser}) => {
        await browser.url("https://github.com/gemini-testing/testplane"); // Открываем тестируемый урл
        const aboutSection = await browser.$(".f4.my-3"); // Ищем нужный элемент на странице
        await expect(aboutSection).toHaveText("Browser test runner based on mocha and wdio"); // Библиотека ассертов доступна из коробки
        await aboutSection.assertView('plain-view'); // С помощью скриншота проверяем вёрстку
    });
});

Плагинная система

Для нашего инструмента довольно просто написать свой плагин, в котором можно реализовать свою кастомную логику. Это может быть свой репортер, поднятие dev-сервера перед началом теста или отправка статистики результатов тестов. Подробнее про доступные события можно почитать в документации. Кроме того, с помощью плагинов вы можете добавлять даже кастомные CLI-команды и опции. Например, так будет выглядеть мини-плагин, который будет в рантайме отключать нестабильные тесты при их падении:

export default (testplane: Testplane) => {
    const someStatStorage = require('your-stat-storage-client');

    // Перехватываем событие, чтобы отключить нестабильный тест
    testplane.intercept(testplane.events.TEST_FAIL, ({event, data: test}) => {
  // Проверяем, является ли тест нестабильным
        const isFlaky = someStatStorage.getTestStat(test.fullTitle());        if (isFlaky) {
		// Отключаем тест и указываем причину отключения
            test.skip({reason: 'This test was disabled automatically'});             

            // Вместо события FAIL бросаем событие PENDING (), на которое могут подписаться другие плагины 
            return { event: testplane.events.TEST_PENDING, data: test };
        }

  // Если перехватывать событие не нужно, достаточно вернуть любое falsey-значение
        return; 
    });
};

Масштабируемость

На данный момент с помощью нашего инструмента внутренние сервисы в Яндексе запускают десятки тысяч тестов, которые выполняются менее чем за 10 минут. Это достигается как за счёт параллельности выполнения тестов в рамках одного запуска, так и за счёт того, что пак тестов можно разбить на любое количество чанков, которые могут быть запущены на разных машинах в CI. При этом на выходе пользователь анализирует единый HTML-отчёт, в котором будут отображены тесты из всех чанков.

Скриншотное тестирование + UI для работы со скриншотами

Скриншотное тестирование — неотъемлемая часть при тестировании вёрстки сервиса. Соответственно, этому типу тестирования мы уделяем особое внимание: у нас реализована своя библиотека сравнения looks-same с широкими возможностями, удобный UI для работы со скриншотами (сравнение, поиск дифов, обновление скриншотов) и автоматическое тестирование Storybook-компонентов (тесты генерируются автоматически в рантайме, а вам нужно будет только принять эталонные скриншоты в UI):

Пошаговое выполнение тестов с помощью REPL-режима

Для удобства написания тестов (а также их дебага) в нашем инструменте есть REPL-режим. С его помощью пользователь может пошагово (построчно) выполнять код теста, чтобы проверить его работоспособность или найти проблемное место. В таком режиме пользователь в рантайме видит процесс выполнения своего теста в локально поднятом браузере или даже в удалённом браузере через VNC. Главная особенность заключается в том, что такой вариант тестирования доступен абсолютно для любого браузера: и для Chrome, и даже для удалённо поднятого iOS-устройства.

Как попробовать

Чтобы настроить Testplane у себя в проекте или просто собрать тестовый проект, достаточно выполнить команду в терминале:

npm init testplane some-project 
// Если не указать директорию, то проект будет развёрнут в текущей директории

После её выполнения в указанной директории установятся все необходимые npm-зависимости, сгенерируется конфиг для запуска тестов с предустановленными плагинами и добавится пробный тест.

Запустить тесты можно с помощью CLI-команды npx testplane или через UI, который можно открыть командой npx testplane gui.


Пробуйте Testplane, приносите фидбек в issues и свои PR. А ещё смотрите трансляцию Yandex Open Source Jam, чтобы узнать больше про опенсорс — ждём вас!

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