Примерно через неделю после того, как я присоединился к Fundbox в качестве инженера по автоматизации, ко мне с беспрецедентным энтузиазмом подошел старший фронтенд-разработчик. Он сказал: Вам стоит попробовать « Кипарис ! Похоже, отличная альтернатива Selenium! » Проведя небольшое исследование, я подошел к своему менеджеру, и мы начали планировать небольшой Proof of Concept (POC). Это превратилось в нашу текущую инфраструктуру тестирования в Fundbox. Поездка прошла не так гладко, как я надеялся, но оно того стоило!

Наша прежняя среда тестирования была написана на Python и использовала Selenium. Мы использовали SauceLabs в качестве нашей тестовой платформы для параллельного запуска тестов на разных машинах. У нас были сотни сложных тестов E2E.

Это была моя первая неделя, и я еще не был знаком с этим бизнесом. Мои навыки JavaScript были очень плохими, так как мой опыт был в основном с Python / Ruby, а я работал только с Selenium.

Год спустя мы достигли следующего:

  • Работающая инфраструктура Cypress с десятками тестов
  • Конвейер CI / CD с использованием TeamCity и Docker
  • Уменьшение времени выполнения тестов на работоспособность в 3 раза

Этот пост прольет свет на Cypress. Я также расскажу, как мы преодолели трудности, с которыми столкнулись на этом пути.

Фреймворк Cypress

Cypress - это новый фреймворк для тестирования, который недавно вышел из стадии бета-тестирования. Это среда для сквозного тестирования JavaScript, позволяющая писать тесты простым и удобным способом. Он также позволяет вам взаимодействовать с вашим веб-приложением, выполнять отладку, как любое другое собственное веб-приложение, и имеет множество возможностей, которые помогут вам легко писать и тестировать.

Почему Кипарис

Cypress имеет уникальную архитектуру, отличную от той, которую использует Selenium. Cypress добился успеха за относительно короткое время, регулярно выпуская новые функции и исправления. Он был разработан, чтобы преодолеть старую, медленную и нестабильную структуру Selenium. Короче говоря, процитируем страницу о: Вы устали от плохого поведения тестов? Мы были .

Cypress имеет отличную документацию, примеры и видеоуроки на своем веб-сайте. Они показывают, как установить и написать свой первый тест за пару минут.

Сделать скачок

После нескольких месяцев знакомства с бизнесом и некоторого рефакторинга кода Selenium мы решили: пора!

JavaScript стал моим новым другом. Моей главной задачей было прочитать, как работают Node.js и JavaScript. Чтение Cypress стало моей навязчивой идеей. Было проведено множество встреч с разработчиками внешнего интерфейса, чтобы понять их потребности и облегчить им написание тестов.

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

Решение проблем

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

Всплывающие окна

Одно из основных ограничений Cypress - невозможность управлять новыми окнами, вкладками и окнами iframe. В то время как Selenium предлагает контроль над ними из коробки.

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

export function stubOpenWindow({ path, url }) {
  cy.url().should("contain", path)
    .then((currentUrl) => {
      url = (url === undefined) ? currentUrl : url;
      cy.visit(url, {
        onBeforeLoad(win) {
          cy.stub(win, "open").as("windowOpen").returns(win);
        },
      });
    });
}

Проблема с iframe

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

Cypress.Commands.add("getElementInIframe", ({ iframe, findBy }) => {
  const maxRetries = 3;
  const sleep = 5000;
  let numOfRetries = 0;
  let app;

  function isModalLoaded() {
    if (numOfRetries < maxRetries) {
      numOfRetries++;
      cy.get(iframe)
        .then(($iFrame) => {
          app = $iFrame.contents().find(findBy);
          const resp = !!app.length;
          if (resp === true) {
            expect(resp).to.eq(true);
            return cy.wrap(app);
          } else {
            cy.wait(sleep);
            isModalLoaded();
          }
        });
    } else {
      assert.isNotOk(true, `Failed to get Iframe '${iframe}' after ${maxRetries} retries`);
    }
  }

  isModalLoaded();
});

Использование support / index.js

Этот файл запускается перед каждым файлом спецификации. Он служит местом для запуска многоразового поведения, такого как пользовательские команды или глобальные переопределения, что предотвращает повторение вашего кода. Вы можете определить свое поведение в функциях before / beforeEach в файле поддержки. Следующие примеры выполняются перед каждым тестом:

  1. Установка значения по умолчанию Приоритет селектора, возвращаемого для каждого элемента.
  2. Создание уникального тестового электронного письма и присвоение baseURL в соответствии с продуктом Fundbox.
  3. Вход в приложения нашего бэк-офиса для имитации различных состояний пользователя.
  4. Использование как cy.server (), так и cy.route () для проверки каждого HTTP-запроса.
  5. Функция afterEach (): сбой всего набора тестов и завершение работы Cypress, если какой-либо шаг не удался. Поскольку наши тесты являются E2E, каждый шаг `it` зависит от предыдущего. Нет причин продолжать тестовый запуск и тратить драгоценное время на тестирование.
afterEach(function() {
  if (this.currentTest.state === "failed") {
    Cypress.env("FAILED_PREV_TEST", true);
    logoutAndSuspendUser.call(this);
    cy.waitForAllAjaxResponder();
    if (Cypress.env("FAIL_FAST")) {
      Cypress.runner.stop();
    }
  }
});

6. after () функция: c изучение среды путем выхода из системы. Удаление всех файлов cookie, очистка локального хранилища и приостановка действия пользователя.

Использование пользовательских команд

Общие функции, такие как login () и logout (), выполняются с помощью Команд Cypress. .

Механизм повтора

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

Команда выхода с механизмом повтора:

Cypress.Commands.add("logout", () => {
  const maxRetries = 3;
  const sleep = 3000;
  let numOfRetries = 0;

  function logoutFromDashboard() {
    if (numOfRetries < maxRetries) {
      numOfRetries++;
      cy.window()
        .then((win) => win.location = "/logout")
        .then(() => cy.url())
        .then((url) => {
          if (url.includes("/login")) {
            expect(url).to.include("/login");
            cy.clearCookie("csrftoken_local");
          } else {
            cy.wait(sleep);
            logoutFromDashboard();
          }
        });
    } else {
      assert.isNotOk(true, `Failed to logout after ${maxRetries} retries`);
    }
  }

  logoutFromDashboard();
});

CI/CD

Часть миграции с Selenium на Cypress включала собственное решение для запуска наших тестов и прекращения использования SauceLabs. Этот шаг экономит время и деньги.

Контейнеры Docker были выбраны из-за их простой интеграции и того факта, что Cypress предоставляет базовые изображения докеров. Параллелизм был достигнут с помощью пакета Python concurrent.futures.

  • Для этого мы создали задание TeamCity, которое запускает Packer.
  • Задание создает образ докера и помещает его в AWS ECR. Планируется запускать раз в неделю.
  • После запуска задания Cypress код сначала извлечет последний образ из репозитория ECR, а затем запустит сборку докеров, чтобы обновить контейнер с последними изменениями.
  • После того, как контейнер готов, мы используем пакет Python concurrent.futures для открытия потоков и запуска контейнера в каждом из них.
  • Количество потоков для разветвления - это конфигурация задания TeamCity.

Последние мысли

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

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

Поскольку Cypress - это продвинутая, оригинальная и надежная среда с множеством функций, она может помочь вам протестировать ваш продукт от А до Я. Попробуйте!