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

Мы рассмотрели несколько различных вариантов (например, Nightwatch) и решили использовать Cypress после того, как они недавно открыли исходный код своего фреймворка. Cypress не использует Selenium, поэтому настроить его очень просто и быстро (в отличие от Nightwatch):

  • Первый: npm install cypress --save-dev
  • Затем: ./node_modules/.bin/cypress open

Вот и все. Эти две команды создают все необходимое для начала работы с Cypress, и это здорово.

Что произошло, когда мы попробовали тестирование в CI

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

Возможно, будет полезно понять наш технологический стек фронтенда: React (настройка с помощью create-react-app) и GraphQL-клиент Apollo.

Прежде чем тесты будут запущены в CI, вам нужно сделать пару вещей:

  1. Добавьте любые переменные среды, которые у вас есть в вашем cypress.env.json, на вашу платформу CI, которые все должны начинаться с CYPRESS_, например. CYPRESS_AUTH_TOKEN
  2. Если вы хотите настроить запись своих тестов в Cypress Dashboard, вам необходимо следовать инструкциям здесь. Получив ключ записи, обязательно добавьте его в переменные среды CI, назвав его CYPRESS_RECORD_KEY.

После выполнения этих двух шагов вы готовы приступить к настройке конфигурации для работы на платформе CI по вашему выбору. Я расскажу, как мы настроили Travis, а затем Circle.

Трэвис

Сначала мы настроили наши тесты для запуска на Travis. В travis.yml необходимо добавить две команды:

  1. Команда для запуска теста E2E — $(npm bin)/cypress run --record
  2. Команда для запуска сервера в фоновом режиме — yarn start --silent &

(Примечание: вам нужно использовать амперсанд ‘&’ для запуска сервера в фоновом режиме, иначе он заблокирует выполнение и зависнет travis)

Наш travis.yml теперь выглядит так:

language: node_js
node_js:
  - 8
cache:
  directories:
    - node_modules
before_script:
  - yarn build
  - yarn start --silent &
script:
  # run unit tests:
  - yarn tests
  # run E2E tests:
  - $(npm bin)/cypress run --record

Это запустило наши тесты на Трэвисе 🎉

Но они проходили только около 20% времени, несмотря на то, что все проходили локально 🙁

Затем мы решили попробовать запустить наши тесты на Circle, чтобы посмотреть, будет ли выше процент прохождения. Это не так.

Выполнение тестов в CI, казалось, выявило гораздо больше проблем, которые делали наши тесты ненадежными. Позже мы решили эту проблему (посмотрите, как это сделать, если продолжите читать), но сначала вот как мы заставили Cypress работать на Circle.

Круг

Наши тесты в настоящее время настроены для работы на Circle 2.0, и, как и у Трэвиса, необходимо добавить те же две команды в .circleci/config.yml, но с одним небольшим отличием. Чтобы запустить сервер в фоновом режиме, не используйте амперсанд «&», вместо этого используйте background: true. Однако по мере того, как наша кодовая база становилась больше, мы все чаще и чаще стали замечать следующую ошибку в Circle:

Наши тесты E2E пытались запустить до завершения запуска сервера.

После некоторого поиска в Google мы нашли команду (when: on_success), которую мы могли добавить в нашу конфигурацию, что означало, что тесты будут ожидать запуска до тех пор, пока сервер не будет успешно запущен.

Наш .circleci/config.yml в итоге выглядел так:

version: 2
jobs:
  build:
    docker:
      - image: cypress/base:6
    working_directory: ~/app
    steps:
    - checkout
    - run: yarn install
    # run unit tests
    - run: yarn test
    - run:
        name: Background the app
        command: yarn start
        background: true
    - run:
        name: Run E2E tests 
        command: $(npm bin)/cypress run --record
        when: on_success

Как мы сделали наши тесты менее нестабильными в CI

Как я упоминал ранее, наш процент сдачи в CI составлял примерно 20%, и мы обнаружили, что это было результатом двух основных проблем:

Утверждения выполнялись до завершения запроса
Мы не имитируем никакие запросы к нашему внутреннему серверу, что означает, что иногда выполнение запроса занимало некоторое время. Мы обнаружили, что, поскольку CI не работал с локальным экземпляром нашего внутреннего сервера, запросы выполнялись дольше, а утверждения чаще терпели неудачу. Чтобы решить эту проблему, мы использовали команду Cypress cy.wait(), чтобы тест явно ждал завершения запроса, прежде чем двигаться дальше. Вот пример того, как мы это сделали:

beforeEach(function() {
  cy.route(
   "POST",
   `https://api.graph.cool/simple/v1/${Cypress.env("GRAPHCOOL_ID")}`
  ).as("graphqlQuery");
});
it("should load page correctly", function() {
  cy.wait("@graphqlQuery");
  cy.get("[data-cy=page-content]").should("be.visible");
});

Выборка не поддерживается
Наши cy.visit() команды не работали. Прочитав этот выпуск, мы обнаружили, что Cypress пока не поддерживает window.fetch.

Мы используем React Apollo, который использует выборку, так что это явно проблема. Пока выборка не будет поддерживаться Cypress, мы решили сделать резервные тесты для использования полифилла выборки, чтобы запросы выполнялись с использованием XHR вместо fetch.

Это означало, что мы по-прежнему могли использовать обычные инструменты захвата и имитации Cypress. Если вы хотите, чтобы это резервное поведение было только в конкретном тесте, вы можете использовать:

cy.visit("/path", {
  onBeforeLoad: win => {
    win.fetch = null;
  }
});

Или, если вы хотите, чтобы это поведение сохранялось во всех тестах, добавьте эту команду в support/index.js:

Cypress.on("window:before:load", win => {
  win.fetch = null;
});

Вы можете отслеживать ход поддержки fetch здесь. Альтернативные решения — заглушить или шпионить за window.fetch, и Cypress предоставил несколько хороших примеров того, как это сделать здесь.

Вывод

После того, как мы попробовали две платформы непрерывной интеграции и устранили проблемы, которые сделали наши тесты ненадежными, было здорово увидеть зеленую галочку успеха в нашем наборе тестов! 🎉✅✅✅

Первоначально опубликовано на https://www.personably.co 26 апреля 2018 г.