Провести ручное тестирование на лету может оказаться довольно сложным делом даже при наличии happy path.

Независимо от ваших предпочтений, использовать любой тестовый фреймворк, возможно, лучше, чем вообще не проводить тесты.

Выбор и смешение тестовых фреймворков

О Jest или Cypress написано уже много статей, поэтому я хочу упомянуть о Codecept. Он бывает двух типов: Codeception для PHP и CodeceptJS для JavaScript, который мы будем использовать в этой статье.

Testomat.io — это программное обеспечение для управления автоматическими тестами, предназначенное для мониторинга управления качеством.

Импорт практически любого существующего тестового сценария в Testomat.io

Мы можем импортировать почти любой имеющийся у нас тест. Jasmine, jest, mocha, cucumber и другая классика; или Cypress, Codecept и Codeception из последних проектов. (Если у вас еще нет тестов, переходите к той части статьи, где я рассказываю о способах улучшения (не)существующих тестов, что может стать хорошим началом для первого простого сценария).

Импорт кода настроит первый тест в Testomat.io. Никаких файлов загружать не потребуется, так как проекты можно синхронизировать с помощью ключа API. Давайте зарегистрируемся и запустим первый проект в качестве практического примера.

Импорт тестов из исходного кода

TESTOMATIO=__$APIKEY__ npx check-tests@latest CodeceptJS "**/*{.,_}{test,spec}.js"

После выполнения приведенного выше выражения в командной строке (заменив $APIKEY нашим фактическим секретным ключом API, который мы только что получили от Testomat.io), импортер обработает данные и выведет результат:

Обновление тестов из исходного кода

Для обновления запустите тот же скрипт снова.

Настройка отчетов

В настройках можно включить уведомления об отчетах на основе наборов правил. Например, о каких результатах тестов (на основе названий тестов или групп) следует сообщать в каком случае («ошибка», «успех», «всегда»), и в каком канале (например, Slack, Jira, Teams или электронная почта).

Testomat.io можно использовать для мониторинга сайтов и приложений, что поможет:

  • выявлять положительные тенденции, подтверждающие прогресс в исправлении багов, 

  • проверять возможные тенденции, которые подтверждают увеличение покрытия тестами legacy приложения, 

  • своевременно получать предупреждение о том, что что-то не работает так, как ожидалось, что может привести к неожиданному отрицательному результату теста.

Визуальное тестирование

Использование CodeceptJS для сравнения скриншотов

Codecept сохраняет скриншоты в случае ошибки.

В случае необходимости скриншоты можно сохранять и сравнивать их с предыдущей версией. Затем можно безопасно обновить SASS или PostCSS, не беспокоясь о том, что какая-то разница, условно, в 5 байтов в результирующем 1000-строчном CSS-файле сломает что-либо во фронтенде.

И это действительно можно сделать. Использование скриншотов, называемое «Визуальным тестированием», может быть еще одним средством тестирования. Мы можем использовать Resemble.js, который является отличным инструментом для сравнения и анализа изображений, после добавления его в проект codeceptjs-resemblehelper:

npm install codeceptjs-resemblehelper --save

Этот вспомогательный класс нужно добавить в конфигурационный файл codecept.conf.js, чтобы определить папки для хранения скриншотов.

  "helpers": {
      "ResembleHelper" : {
        "require": "codeceptjs-resemblehelper",
        "screenshotFolder" : "./codecept/output/",
        "baseFolder": "./codecept/screenshots/base/",
        "diffFolder": "./codecept/screenshots/diff/"
      }
   }

Теперь можно делать скриншоты в тестах и сравнивать их.

 I.saveScreenshot('Homepage_Screenshot.png');
  I.seeVisualDiff('Homepage_Screenshot.png', {
    tolerance: 2,
    prepareBaseImage: false
  });

Если мы не можем предоставить изначальное изображение снимка экрана, мы можем дать CodeceptJS подготовить первоначальный «базовый образ» при первом запуске или после преднамеренного визуального изменения, временно установив prepareBaseImage: true.

Сгенерированные скриншоты следует поместить в git-репозиторий.

Теперь давайте посмотрим, что произойдет в случае, если скриншоты различаются.

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

Сохраняю скриншот "Homepage Screenshot.png"`
Вижу разницу "Homepage Screenshot.png",`
{"tolerance":2,"prepareBaseImage":false}`
✖ Ошибка произошла на 2604 мс

–- ОШИБКИ:

1) Домашняя страница
Тестирование контента и навигации сайта:
Размер базового изображения: 1200 X 1600, 
размер фактического изображения: 900 X 1200. 
Пожалуйста, используйте изображения одного размера, 
чтобы избежать некорректных результатов.

Если это намеренное изменение, я могу задать prepareBaseImage: true, чтобы воссоздать новое базовое изображение при следующем запуске. После этого тесты пройдут и мы получим статус «пройдено», если не будет обнаружено другое новое изменение.

Скриншот-тестирование — это лишь один из аспектов, с которым было трудно справиться при написании тестов в прошлом. Поскольку CodeceptJS основан на Playwright, мы можем тестировать iframe, а также загрузку и выгрузку файлов нативно. И (в отличие от Cypress) у CodeceptJS есть параллельный режим работы.

Расширение и улучшение локальных тестов

Проверка кода на ложные предположения

Забавная часть: я попытался добавить утверждение, что ошибки «404 не найдено» нет, начиная с одного наивного подхода.

I.dontSee('404');

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

Используйте хуки оnpm pre- и post-test 

Если у вас еще нет localhost preview server, его можно добавить с помощью пакета http-server и таргета "serve" в package.json (см. пример кода ниже).

Для локального тестового запуска мы можем объединить наш процесс линтинга и сборки с автоматизацией тестирования, используя встроенную функцию пре- и пост-скриптов npm. Разделив задачи на предварительные, тестовые и посттестовые, мы не будем беспокоиться о том, что dev-сервер заблокирует терминал, или что нам придется вечно ждать незавершенного теста или о том, как заставить Codecept ждать сервер, если скрипты выполнялись параллельно.

Интеграция линтинга, сборки и тестирования

Прежде чем приступить к сборке и тестированию, давайте также убедимся, что наш исходный код проходит статический контроль качества путем добавления популярных инструментов линтинга (eslint для JavaScript и stylelint для CSS) в начале нашей тестовой цепочки инструментов:

  1. Проверьте исходный код, используя eslint и stylelint.

  2. Соберите исходный код (в моем случае с помощью eleventy и postCSS, вы можете взять инструменты по вашему выбору).

  3. Запустите localhost development server.

  4. Запустите тестовые шаги CodeceptJS (в реальном браузере).

  5. Остановите dev-сервер (с помощью pkill, как это предлагается на StackOverflow).

Локальная настройка. Сводка

Вы можете проверить, скопировать и вставить соответствующие фрагменты кода ниже. Я упустил некоторые детали проекта, чтобы сосредоточиться на тестовой настройке. Исходный код можно найти на GitHub.

Скрипты и зависимости в package.json:

 "scripts": {
        "eslint": "eslint src",
        "stylelint": "stylelint src/*.css",
        "build": "npm run eslint && npm run stylelint && ... your own build steps ...",
        "codeceptjs": "codeceptjs run --steps",
        "serve": "npx http-server dist -p 1974 --cors &",
        "pretest": "npm run build && npm run serve",
        "test": "npm run codeceptjs",
        "posttest": "pkill -f http-server"
    },
    "devDependencies": {
        "@codeceptjs/configure": "^0.8.0",
        "codeceptjs": "^3.3.4",
        "eslint": "^8.6.0",
        "http-server": "^14.1.1",
        "playwright": "^1.25.0",
        "puppeteer": "^16.1.0",
        "stylelint": "^14.10.0",
        "stylelint-config-html": "^1.1.0",
        "stylelint-config-standard": "^27.0.0"
    }
}

Конфигурационный файл Codecept ./codecept.conf.js. Примечание: чтобы узнать правильный синтаксис, воспользуйтесь последней версией документации codecept.

Это всего лишь простой образец конфигурации, используемый с CodeceptJS 3.3.4, который, вероятно, уже устарел на момент прочтения.

const { setHeadlessWhen, setWindowSize } = require('@codeceptjs/configure');

// включить headless режим при работе с переменной окружения HEADLESS=true
// экспорт HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);

setWindowSize(1600, 1200);

exports.config = {
  tests: './codecept/*_test.js',
  output: './codecept/output',
  helpers: {
    Puppeteer: {
      url: 'http://localhost:1974',
      show: true,
      windowSize: '1200x900'
    }
  },
  include: {
    I: './codecept/steps_file.js'
  },
  bootstrap: null,
  mocha: {},
  name: 'ingo-steinke.de',
  plugins: {
    pauseOnFail: {},
    retryFailedStep: {
      enabled: true
    },
    tryTo: {
      enabled: true
    },
    screenshotOnFail: {
      enabled: true
    }
  }
}

Поскольку я создал альтернативные конфигурации для использования в разных средах, я переместил общие параметры конфигурации в ./codecept.common.conf.js, которые включил в определенные файлы конфигурации. Это поможет избежать избыточности кода.

Здесь я просто использую другой URL-адрес для тестирования сайта, развернутого на общедоступном рабочем URL-адресе:

./codecept.ci.conf.js:
const { setHeadlessWhen, setWindowSize } = require('@codeceptjs/configure');
exports.config = require ('./codecept.common.conf.js');
exports.config.helpers.Puppeteer.url = 'https://www.ingo-steinke.de';

// включить headless режим при работе с переменной окружения HEADLESS=true 
// экспорт HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);

Добавление тестовых шагов в тестовый сценарий

И последнее, но не менее важное: нам нужны тестовые утверждения. Можно использовать общий файл steps_file.js и специальные сценарии тестирования, такие, как функция «Домашняя страница», определенная в homepage_tests.js.

Здесь мы делаем несколько простых вещей:

Откройте домашнюю страницу («Я на странице /») и убедитесь, что ожидаемый контент виден. Можно указать текст, определенные элементы и при необходимости использовать селекторы XPath.

Хотя мы можем указать размер экрана в конфигурации, в явной прокрутке нет необходимости. Наши утверждения  работают со всем документом, как если бы мы использовали функцию поиска на странице в браузере.

Используя описание как ключ, ищем определенную кнопку, нажимаем ее и убеждаемся, что стал виден определенный абзац, который изначально был скрыт.

Feature('Homepage');

Scenario('Test website content and navigation', ({ I }) => {

  I.amOnPage('/');
  I.see('Ingo Steinke', 'h1');
  I.see('Creative Web Developer');
  I.seeElement('//a[contains(., "privacy")]');

  // найти кнопку по тексту подписи, нажать на нее...
  I.click('privacy');
  // ... и убедиться, что она открывает скрытый абзац.
  I.see('Your legal rights');

  // Мы можем гарантировать, что НЕ увидим что-то:
  I.dontSeeElement('.error');
  // I.dontSee('404');

  // поэтому следующее вызовет ошибку:
  // I.dontSee('Ingo');
});

Итак, это простой тестовый сценарий с использованием npm и CodeceptJS. Мы можем его расширить, используя более сложные тестовые сценарии и добавляя альтернативные тестовые конфигурации.

Поскольку мы используем Testomat.io для управления автоматизацией тестирования, давайте не будем забывать обновлять тестовые утверждения после совершенных изменений.

Это запустит пайплайн проверка + сборка + тест, и, если он завершится успешно, это приведет к обновлению наборов тестов на сервере Testomat.io. И отправка в git (или, точнее, слияние с основной веткой) вызовет сборку и развертывание, поэтому в конце у нас будет обновленная сборка веб-страницы и обновленные тестовые утверждения для тестирования активной страницы на продакшене.

npm run test && \
TESTOMATIO=__$APIKEY__ npx check-tests@latest CodeceptJS "**/*{.,_}{test,spec}.js && \
git push"

Приглашаем всех желающих на открытое занятие онлайн-курса "JavaScript QA Engineer", на котором мы разберём основы HTML/JS и напишем пару e2e-тестов с помощью cypress. Регистрация открыта по ссылке.

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