Переиспользование кода между проектами

В процессе разработки автоматизированных тестов часто возникает потребность в повторном использовании уже написанного кода. WebdriverIO предоставляет несколько механизмов для того, чтобы тесты были гибкими, масштабируемыми и удобными для переиспользования на разных проектах. Использование модульности и правильной архитектуры тестов позволяет избежать дублирования кода и существенно повысить его поддержку.

Модули и библиотеки

Одним из самых простых способов переиспользования кода между проектами является создание собственных модулей и библиотек. В JavaScript существует множество инструментов для организации кода в виде модулей, среди которых наиболее распространённым является механизм импорта/экспорта, доступный с версии ES6. Для организации структуры тестов и кода WebdriverIO можно использовать общие модули, которые будут включать функции для:

  • Ожиданий
  • Взаимодействий с элементами
  • Вспомогательных утилит (например, логирования, работы с данными)

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

Пример:

// utils/waitForElement.js
export const waitForElement = (element, timeout = 5000) => {
    browser.waitUntil(() => element.isDisplayed(), {
        timeout: timeout,
        timeoutMsg: 'Ожидание элемента не выполнено в пределах времени',
    });
};

// в другом проекте
import { waitForElement } from './utils/waitForElement';

const myElement = $('#my-element');
waitForElement(myElement);

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

Создание кастомных команд

WebdriverIO позволяет расширять стандартный функционал с помощью кастомных команд. Это удобный способ переиспользования кода, поскольку команды можно хранить в отдельных файлах и подключать в проекты при необходимости. Для этого используются методы addCommand() или browser.addCommand(). Команды могут быть связаны с общими действиями, которые часто повторяются в тестах, например:

  • Взаимодействие с определёнными типами элементов.
  • Специальные проверки на состояние страницы или данных.
  • Логирование и отчётность.

Пример:

// commands/login.js
browser.addCommand('login', function(username, password) {
    $('#username').setValue(username);
    $('#password').setValue(password);
    $('#login-button').click();
    browser.waitUntil(() => $('#dashboard').isDisplayed(), {
        timeout: 5000,
        timeoutMsg: 'Не удалось зайти на страницу после логина',
    });
});

// В другом проекте
import './commands/login';

browser.login('user', 'password123');

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

Использование Page Object Model (POM)

Page Object Model (POM) — это один из самых популярных паттернов проектирования для автоматизации тестирования веб-приложений. Он позволяет разделить логику взаимодействия с веб-страницей и тесты, делая код более удобным для повторного использования. Основная идея заключается в том, чтобы для каждой страницы (или компонента) приложения создать отдельный объект, который будет инкапсулировать взаимодействие с элементами на этой странице.

При использовании POM структура проекта становится гибкой, и каждый объект-страница может быть переиспользован в разных тестах и проектах.

Пример:

// pageObjects/LoginPage.js
class LoginPage {
    get usernameField() {
        return $('#username');
    }

    get passwordField() {
        return $('#password');
    }

    get loginButton() {
        return $('#login-button');
    }

    open() {
        browser.url('/login');
    }

    login(username, password) {
        this.usernameField.setValue(username);
        this.passwordField.setValue(password);
        this.loginButton.click();
    }
}

export default new LoginPage();

// В другом проекте
import LoginPage from './pageObjects/LoginPage';

LoginPage.open();
LoginPage.login('user', 'password123');

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

Библиотеки и фреймворки для тестирования

Кроме стандартных возможностей WebdriverIO для переиспользования кода, можно использовать различные библиотеки и фреймворки, которые ещё больше упрощают организацию кода. Например, для работы с базами данных, API или внешними сервисами можно использовать дополнительные библиотеки, которые могут быть подключены через npm или yarn. Создание абстракций для работы с внешними системами также улучшает переиспользование кода между проектами.

Некоторые популярные библиотеки для интеграции с WebdriverIO:

  • Cucumber — для использования BDD-подхода и написания тестов в виде сценариев.
  • Chai — для написания утверждений и ассершенов.
  • Allure — для генерации отчетов о выполнении тестов.

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

Публикация и управление зависимостями

Для того чтобы использовать один и тот же код в разных проектах, можно оформить его как отдельные пакеты и публиковать их на таких сервисах, как npm или GitHub Packages. Это позволяет централизованно управлять версиями и обновлениями кода.

Создание собственного пакета с часто используемыми функциями или командами даёт возможность быстро интегрировать изменения в несколько проектов, контролируя зависимости и версии.

Пример структуры пакета:

my-webdriver-utils/
├── src/
│   ├── commands/
│   ├── utils/
│   └── pageObjects/
├── package.json
└── README.md

После публикации такого пакета его можно установить в любой проект с помощью команды:

npm install my-webdriver-utils

И использовать в тестах:

import { waitForElement } from 'my-webdriver-utils';
import LoginPage from 'my-webdriver-utils/pageObjects/LoginPage';

LoginPage.open();
LoginPage.login('user', 'password123');

Версионирование и управление зависимостями

Очень важно управлять версиями переиспользуемого кода, особенно когда проект развивается, и с течением времени появляются новые требования. Использование семантического версионирования (semver) позволяет контролировать изменения в зависимости от типа обновлений: минорные, мажорные или патч-версии.

Для этого важно регулярно обновлять версии пакетов, публикуя новые релизы с необходимыми изменениями. В случае использования таких инструментов, как npm или yarn, управление зависимостями и версионирование происходит автоматически, что делает поддержку таких решений проще.

Использование Docker и CI/CD

Для ещё большего удобства и переиспользования кода можно применять контейнеризацию с Docker. Создание Docker-образов с преднастроенными тестовыми окружениями позволяет использовать одну и ту же конфигурацию на разных проектах, а также легко воспроизводить окружение для тестирования.

Интеграция с системами непрерывной интеграции (CI/CD), такими как Jenkins, GitLab CI или GitHub Actions, даёт возможность автоматически запускать тесты с переиспользуемыми модулями, гарантируя, что код будет работать одинаково во всех окружениях.

Заключение

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