Подход Divido к сквозному тестированию

Cypress - это фреймворк для сквозного тестирования с открытым исходным кодом, который очень пригодился Divido за последние несколько месяцев. Как и в любой начинающей компании, наш процесс разработки должен быть быстрым и плавным. Для того, чтобы это было достижимо, ключевым значением является надежность. В этом нам может помочь Cypress, предоставляя дополнительный уровень, гарантирующий, что вновь разработанные функции не окажут негативного влияния на существующую кодовую базу.

Итак, почему Cypress?

В Divido было несколько вещей, которые мы искали от фреймворка для сквозного тестирования:

  • Легко установить
  • Хорошая документация
  • Не много зависимостей, но в то же время модульная
  • Быстро бежать
  • Легко отлаживать

Мы быстро поняли, что Cypress ставит галочки по всем пунктам для того, что мы искали. Его действительно легко установить, он готов к работе через пару минут, поскольку не требует обширной настройки и поставляется с действительно хорошей документацией; полно видео и примеров.

Что касается зависимостей, мы используем только дополнительную внешнюю библиотеку, чтобы помочь нам имитировать наш слой GraphQL, так как все остальные наши потребности полностью предоставляются Cypress. И последнее, но не менее важное: отладка с Cypress действительно проста, так как очень легко увидеть, в чем проблема и что ее вызывает.

Как мы это используем?

Для начала установите Cypress.

$ yarn add -D cypress

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

$ ./node_modules/.bin/cypress open

Все тесты находятся в пределах ./cypress/integration, поэтому любой файл .spec, созданный внутри этого маршрута, будет выбран Cypress. Создать тест очень просто, и, если вы знакомы с Mocha и Chai, Cypress принял синтаксис Mocha и способ написания утверждений Chai.

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

./cypress/integration/demo.spec.js

Теперь осталось написать простой тест.

describe('Demo test', () => {
beforeEach(() => {
  cy.mockGraphqlServer({
    // This is where we will be mocking all the GraphQL requests
    // this test needs to pass.
  });
});
it('should change label text when button is clicked', () => {
  cy.get('demo-test-label').should('eq', 'Select all');
    cy.get('demo-test-button').click();
    cy.get('demo-test-label').should('eq', 'Clear all');
  });
});

Чтобы запустить тест, мы вызываем наши настроенные сценарии в package.json файле.

"scripts": {
  "cy:open": "./node_modules/.bin/cypress open",
  "cy:run": "./node_modules/.bin/cypress run"
}

Чтобы сделать вещи более наглядными, мы можем запустить следующую команду:

$ yarn cy:open

Откроется Cypress Test Runner, где вы увидите список всех доступных тестов. Щелчок по желаемому тесту откроет его в браузере, установленном в вашей системе. Мы также можем запустить его в безголовом режиме в командной строке с cy:run.

Непрерывная интеграция

В наш конвейер включены Cypress-тесты, чтобы гарантировать, что новый добавленный код не нарушит ни одну из существующих функций. Когда мы начали создавать наши сквозные тесты, мы использовали CircleCI для наших сборок. Мы начали исследовать другие возможности, чтобы сократить время, необходимое для завершения нормальной сборки, и нашли Действия GitHub.

GitHub Actions - это система для автоматизации всех ваших рабочих процессов по созданию, развертыванию и тестированию кода прямо из GitHub. Способ интеграции Cypress с рабочими процессами GitHub Actions делает процесс действительно быстрым, поскольку Cypress настроен для работы на нескольких машинах для ускорения работы. Он работает довольно умно: Cypress проанализирует результаты своих тестов, чтобы узнать, какие из них будут выполняться дольше, и распределит их по разным серверам, чтобы машины были сбалансированы.

Что мы узнали?

Сквозные тесты не являются модульными, поэтому важно стараться не думать обо всех тестах одинаково. Короткие модульные тесты и одно утверждение в большинстве случаев работает очень хорошо, но это не относится к сквозным тестам. Сквозная цель - проверить, поток приложения от начала до конца ведет себя так, как ожидалось, поэтому принцип единой ответственности здесь не применим.

Мы разделили наши тесты на уровне страниц, чтобы помочь распределить тесты по разным машинам, упомянутым выше. И для каждой страницы мы задаем себе следующий вопрос: «Что может делать пользователь на этой странице?». Ответ на этот вопрос будет способствовать написанию тестов.

На примере страницы с формой простое, но ошибочное распределение тестов может выглядеть так:

describe("Form page", () => {
it("should open the page without errors", () => {
    ...
  });
it("should show validation error when input is incorrect", () => {
    ...
  });
it("should show validation success when input is correct", () => {
    ...
  });
it("should not be able to submit if form is unchanged", () => {
    ...
  });
it("should be able to submit when all values are correct", () => {
    ...
  });
});

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

describe("Form page", () => {
it("should be able to submit form successfully", () => {
    ...
  });
});

Каковы причины этого?

  • Это быстрее - в приведенном выше примере мы могли бы говорить примерно на десять секунд быстрее
  • Он отвечает на вопрос: «Что может делать пользователь на этой странице?»
  • При запуске легко увидеть, где находится ошибка, поэтому нет проблем с более длительными тестами.
  • Он подходит для сквозного тестирования, поскольку мы проверяем поток формы от начала до конца.

Заключение

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

Cypress помог нам в этом, и мы настоятельно рекомендуем его, учитывая, насколько легко его настроить. Тот факт, что его синтаксис похож на некоторые из наиболее распространенных инструментов тестирования Javascript, просто упрощает начало работы. Я рекомендую вам ознакомиться с официальной документацией, чтобы узнать об этом больше.