Стабильная доставка продукта с использованием Cypress
Fei Han
February 7, 2021
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-фреймворка по четырем основным причинам:
-
Простой синтаксис
Синтаксис Cypress прост и интуитивно понятен, что позволяет быстро освоить написание тестов. Это важно для открытых проектов, так как позволяет сообществу участвовать в написании тестов с минимальными затратами на обучение. -
Удобная отладка
Cypress предоставляет Test Runner, который отображает многомерные данные, помогая быстро находить проблемы. Он показывает статус выполнения тестов, общее время выполнения, встроенный инструмент для поиска элементов и формирует снимки каждого шага выполнения. -
Активное сообщество
У Cypress большое сообщество пользователей, где активно обсуждаются проблемы и идеи. Это помогает быстро находить решения и участвовать в развитии фреймворка. -
Четкая документация
Документация Cypress структурирована и подробна. На начальном этапе мы смогли быстро внедрить Cypress в проект и написать первые тесты, следуя официальным руководствам.
Cypress и APISIX Dashboard
В настоящее время для APISIX Dashboard написано 49 тестовых сценариев. Мы настроили CI в GitHub Action, чтобы гарантировать, что код проходит проверку перед каждым слиянием. Мы делимся опытом использования Cypress в APISIX Dashboard, следуя лучшим практикам и адаптируя их под наш проект.

- Часто используемые функции инкапсулированы в команды
Например, вход в систему — это обязательная часть, поэтому мы инкапсулировали его в команду, чтобы вызывать её перед каждым тестом.
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(); })
- Селекторы и данные вынесены в публичные переменные
Для улучшения читаемости кода мы вынесли селекторы и данные в отдельные переменные.
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', };
- Устранение 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