Стабильная доставка продукта с использованием Cypress

Fei Han

February 7, 2021

Ecosystem

Apache APISIX Dashboard разработан для максимального упрощения работы пользователей с Apache APISIX через интерфейс. С момента запуска проекта было сделано 552 коммита и выпущено 10 релизов. При такой быстрой итерации продукта важно обеспечить его качество. Для этого мы внедрили модуль E2E-тестирования, чтобы гарантировать стабильную поставку продукта.

Что такое Front-End E2E?

E2E, что означает "End to End", можно перевести как "сквозное" тестирование. Оно имитирует поведение пользователя, начиная с точки входа и выполняя действия шаг за шагом до завершения задачи. Качественное тестирование предотвращает нарушение исходной логики при изменениях в коде.

Почему Cypress?

В период исследования мы использовали Taiko, Puppeteer, TestCafe и Cypress для написания тестовых сценариев создания маршрутов. Каждый из этих фреймворков был опробован, чтобы оценить их особенности.

Taiko отличается умным селектором, который может интеллектуально находить элементы на основе текстового содержимого и расположения. Он имеет низкий порог входа, что позволяет быстро создавать тестовые сценарии. Однако он неудобен при написании тестов: если пользователь случайно закрывает терминал, все написанные тесты теряются. Для запуска полного тестового сценария требуется использование других инструментов, что увеличивает сложность обучения.

Puppeteer обладает лучшей производительностью, но его основное применение — веб-скрапинг, а не тестирование. Наш проект начался с Puppeteer, рекомендованного ANTD, но мы обнаружили, что он неудобен для разработчиков, не связанных с фронтендом. Отсутствие интеллектуального поиска элементов делает его сложным для освоения.

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

После тщательного сравнения мы выбрали Cypress в качестве нашего E2E-фреймворка по четырем основным причинам:

  1. Простой синтаксис
    Синтаксис Cypress прост и интуитивно понятен, что позволяет быстро освоить написание тестов. Это важно для открытых проектов, так как позволяет сообществу участвовать в написании тестов с минимальными затратами на обучение.

  2. Удобная отладка
    Cypress предоставляет Test Runner, который отображает многомерные данные, помогая быстро находить проблемы. Он показывает статус выполнения тестов, общее время выполнения, встроенный инструмент для поиска элементов и формирует снимки каждого шага выполнения.

  3. Активное сообщество
    У Cypress большое сообщество пользователей, где активно обсуждаются проблемы и идеи. Это помогает быстро находить решения и участвовать в развитии фреймворка.

  4. Четкая документация
    Документация Cypress структурирована и подробна. На начальном этапе мы смогли быстро внедрить Cypress в проект и написать первые тесты, следуя официальным руководствам.

Cypress и APISIX Dashboard

В настоящее время для APISIX Dashboard написано 49 тестовых сценариев. Мы настроили CI в GitHub Action, чтобы гарантировать, что код проходит проверку перед каждым слиянием. Мы делимся опытом использования Cypress в APISIX Dashboard, следуя лучшим практикам и адаптируя их под наш проект.

image

  1. Часто используемые функции инкапсулированы в команды
    Например, вход в систему — это обязательная часть, поэтому мы инкапсулировали его в команду, чтобы вызывать её перед каждым тестом.
Cypress.Commands.add("login", () => { cy.request( "POST", 'http://127.0.0.1/apisix/admin/user/login', { username: "user", password: "user", } ).then((res) => { expect(res.body.code).to.equal(0); localStorage.setItem("token", res.body.data.token); }); });
beforeEach(() => { // init login cy.login(); })
  1. Селекторы и данные вынесены в публичные переменные
    Для улучшения читаемости кода мы вынесли селекторы и данные в отдельные переменные.
  const data = {     name: 'hmac-auth',     deleteSuccess: 'Delete Plugin Successfully',   };   const domSelector = {     tableCell: '.ant-table-cell',     empty: '.ant-empty-normal',     refresh: '.anticon-reload',     codemirror: '.CodeMirror',     switch: '#disable',     deleteBtn: '.ant-btn-dangerous',   };
  1. Устранение cy.wait(someTime)
    В начале мы использовали cy.wait(someTime), но обнаружили, что это зависит от сетевого окружения и производительности машины. Рекомендуется использовать cy.intercept() для явного указания ожидаемых сетевых ресурсов.
cy.intercept("https://apisix.apache.org/").as("fetchURL"); cy.wait("@fetchURL");

Заключение

В настоящее время в APISIX Dashboard написано 49 тестовых сценариев. В будущем мы планируем увеличить покрытие E2E-тестирования и требовать от сообщества написания тестов для каждого нового функционала или исправления ошибок, чтобы обеспечить стабильность продукта.

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

Адрес проекта: https://github.com/apache/apisix-dashboard

Tags: