Как стать автором
Поиск
Написать публикацию
Обновить
34

Быстрый старт автотестирования с Playwright

Время на прочтение11 мин
Количество просмотров5.1K

Добрый день, уважаемые хабровчане! Меня зовут Евгений Иванов, и вот уже год я работаю на позиции QA-lead в компании FixPrice. В прошлом году руководство поставило передо мной задачу: наладить быстрый старт автотестирования и масштабирование решений на все проекты нашего отдела.

С чего мы начали

На момент моего прихода в компанию автотесты были написаны с использованием стека технологий PHP, Codeception+Selenium. А большинство наших проектов используют фреймворки для разработки, основным языком программирования которых является PHP.

Codeception — мощный инструмент для написания unit, acceptance и API-тестов на PHP. Он объединяет несколько популярных библиотек (например, PHPUnit, Symfony BrowserKit, Selenium WebDriver) в единый фреймворк с удобным синтаксисом.

С Codeception на тот момент я уже был знаком и писал acceptance-тесты на PHP в одной из компаний, где работал QA-инженером. Но на позицию QA-lead в FixPrice я пришел уже с бэкграундом и знаниями по другим фреймворкам автотестирования, таким как Selenide, Appium, Selenium. Ну и, конечно же, с опытом использования и внедрения Playwright+TS. 

Почему Playwright+TypeScript ?

С опытом использования фреймворков Codeception, Selenide, Appium, Selenium, Playwright, и зная их отличия в настройке и работе протоколов, я понимал, что быстрым решением будет именно Playwright. Но у коллег (разработчиков и тестировщиков) были сомнения, и в этом плане я очень понимал их, так как им предлагалось использовать стек технологий, кардинально отличающийся от привычного Codeception.

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

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

Сравнительная таблица

Характеристика

Codeception

Playwright

Основное назначение

Тестирование PHP-приложений (юнит, функциональное, приемочное)

Энд-ту-энд тестирование веб-приложений

Язык/Платформа

PHP

Node.js, Python, .NET, Java

Поддерживаемые языки

PHP

JavaScript/TypeScript, Python, C#, Java

Поддерживаемые браузеры

Поддержка через WebDriver

Непосредственно Chromium, Firefox, WebKit

Скрость выполнения UI автотестов в 10 действий

6-8 секунды

1-2 секунды

Подход к тестированию

UI-тестирование, API-тестирование, Unit-тестирование, функциональное тестирование

UI-тестирование, API-тестирование, функциональное тестирование

Уровень абстракции

Более высокий уровень абстракции с различными модулями

Более низкий уровень абстракции

Асинхронность

Синхронный подход, в основном PHP

Поддерживает асинхронное программирование

Безголовый режим

Да, через Selenium WebDriver

Да

Автоматическое ожидание

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

Встроенные механизмы автоматического ожидания элементов и событий

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

Использует Composer

Зависит от npm-пакетов

Документация

Обширная документация и учебные материалы

Хорошо структурированная документация

Сообщество и поддержка

Стабильное и активное сообщество PHP-разработчиков

Активно развивается Microsoft, быстро растущее сообщество

Мобильное тестирование

Ограниченная поддержка через Selenium и Appium

Поддержка эмуляции мобильных устройств

Сквозное тестирование

Поддерживает сквозное тестирование

Поддерживает сквозное тестирование

Анализ и отчеты

Расширенные возможности отчетов через интеграции

Стандартные возможности отчетов

Кросс-браузерное тестирование

Поддержка через WebDriver, но требует настройки

Встроенная поддержка с функцией автоматического определения и переключения между браузерами

Инструменты записи тестов

Не предоставляет встроенные инструменты, но можно использовать сторонние

Встроенные инструменты для записи действий и генерации тестов

Поддержка тестирования на локальных и удалённых устройствах

Возможно, через настройки драйвера

Легкая настройка для локальных и удаленных устройств

Тестирование производительности

Также может быть интегрирован с инструментами для производительных тестов

Ограниченные возможности, в основном UI и функциональное тестирование

Поддержка параллельного тестирования

Поддерживает параллельное выполнение через различные настройки

Встроенная поддержка для параллельного запуска тестов

Подход к тестированию API

Подробная поддержка тестирования API с возможностью проверки ответов

Поддержка тестирования API и взаимодействия с REST и GraphQL

Поддержка разных форматов отчетов

Расширенные возможности для генерации отчетов, поддержка различных форматов

Поддержка различных форматов для экспорта отчетов (HTML, JSON)

Модульная структура тестов

Поддерживает гибкую структуру для модульного тестирования и фреймворка

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

Интеграция с другими фреймворками

Широкая интеграция с другими тестовыми инструментами и библиотеками PHP

Легко интегрируется с Jest, Mocha и другими тестовыми фреймворками

Перехват http, https трафика

Возможно, через сторонние подключаемые модули

Возможно собственными средствами перехвата трафика и мокирования

Мокирование

Возможно, через сторонние подключаемые модули

Возможно собственными средствами перехвата трафика и мокирования

Интеграция с CI/CD

Легкая интеграция с популярными CI/CD инструментами

Легкая интеграция с Jenkins, GitLab CI/CD, GitHub Actions и другими инструментами

Лицензия

MIT

Apache 2.0

Кривая обучения

Низкая для PHP-разработчиков, особенно знакомых с PHPUnit

Низкая для знакомых с JS/TS, Python, C#, Java

Плагины и расширения

Имеет модули для интеграции с Symfony, Laravel, Yii и другими фреймворками

Расширяем через npm-пакеты, поддержка интеграций с другими инструментами

Последняя стабильная версия

Регулярные обновления, актуальную версию см. на официальном сайте

Регулярные обновления, актуальную версию см. на официальном сайте

Поддерживаемые протоколы

HTTP/HTTPS, SOAP, REST, поддержка тестирования API

HTTP/HTTPS, WebSockets, возможность работы с REST API

Кросс-платформенность

Windows, macOS, Linux

Windows, macOS, Linux

Преимущества

Все в одном, интеграция с PHP-фреймворками, гибкость конфигурации

Кросс-браузерность, мощные возможности автоматизации, гибкость, современные функции

Недостатки

Зависимость от сторонних инструментов, ограничения языка

Относительно новый инструмент, требования к среде

Рекомендации по выбору

Идеален для проектов на PHP с потребностью в комплексном тестировании

Подходит для проектов с разными языками и современными веб-технологиями

Параллельно мы выделили время QA-инженера и других разработчиков на изучение и прощупывание Playwright. Поскольку они использовали, писали и разрабатывали код автотестов на Codeception, очень полезно было получить от них обратную связь.

QA-инженеры были приятно удивлены быстротой, удобством настройки и фичами Playwright. И в течение рабочей недели было принято совместное решение о внедрении нового, современного фреймворка Playwright, но пока не отказываясь полностью от автотестов коллег, разработанных на Codeception, которые, однако, постепенно тоже будут переписаны на Playwright.

О хранении кода автотестов

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

Что для нас важно:

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

  2. Изначальное ревью кода автотестов при первоначальном развертывании разработчиками, обладающими экспертизой в TS.

  3. Дальнейшее встраивание кода автотестов в процессы CI/CD.

  4. Быстрое масштабирование кода автотестов в репозитории других проектов.

  5. Документация README.md в tests/ с правилами для команды.

  6. Поддержка legacy-проектов.

Настройка и масштабирование

Способов установки Playwright несколько, в том числе:

  1. Создание отдельного контейнера с установкой Playwright на него.

  2. Установка непосредственно на вашу хост-машину, с IDE или без IDE.

Если вы планируете не просто запускать тесты в «безголовом» режиме браузера, но писать тесты и смотреть выполнение в UI формате, то Docker-контейнером не обойтись, и нужно установить Playwright на компьютер. Как это сделать, описано тут.

Если же вы планируете редактировать и разрабатывать сценарии автотестов, то 

вам подойдет установка с помощью IDE. Как это сделать описано тут. Для установки Playwright необходимо выполнить так же установку Node.js

При создании проекта - шаблона автотестов, его внедрении и масштабировании в проекты ЦК ЕРОН мы придерживались следующих специфичных для нас пунктов инструкции:

  1. Для написания тестов такого типа используйте файлы .spec.ts.

  2. Создавайте файлы .spec.ts в папке tests/tests относительно корневого каталога основного проекта, а настройку производите в файле playwright.config.ts.

  3. Используйте test.beforeEach, чтобы создавать общие предусловия в начале .spec.ts.

  4. Старайтесь минимизировать обращения к БД и API. Приемочные тесты предполагают имитацию работы пользователя, поэтому все действия должны выполняться через UI. Возможны обращения к API методам для доведения до нужных состояний систем, выступающих в качестве предусловий и постусловий.

  5. Установите и настройте Allure.

  6. Каждый тестовый метод должен описываться allure аннотациями Title для описания теста.

  7. Используйте паттерн Page object. В идеале в тестах вообще не должны мелькать xpath и селекторы. Все они должны быть заданы константами или переменными в POM.

  8. Page Object может содержать селекторы и методы для работы со страницей. Но не должен содержать ассерты.

  9. Ассерты всегда должны быть в .spec.ts, не выносите их никуда без острой необходимости. В редких случаях можно создать отдельный хэлпер и выносить ассерты туда.

  10. Используйте https://playwright.dev/docs/mock для мока внешних сервисов.

Итак, стараясь придерживаться выше описанных пунктов, у нас получился следующий шаблон, для масштабирования и быстрого запуска UI-автотестов на проектах ЦК ЕРОН:

│   .env-example

│   .gitignore

│   eslint.config.mjs

│   Makefile

│   package-lock.json

│   package.json

│   playwright.config.ts

│   projects_tree.txt

│   README.MD

│   tsconfig.json

├───docker

│   │   docker-compose.playwright.yml

│   │   

│   └───playwright

│           Dockerfile

├───support

│   ├───.auth

│   │       storage.json

│   │       

│   ├───pages

│   │       LoginPage.ts

│   │       

│   └───utilities

│           EnvHelper.ts

│           

└───tests

        auth.setup.ts

        example.spec.ts

Основные директории проекта-шаблона и  конфиг-файлы, которые нас интересуют это:

docker - конфигурационные файлы для настройки и поднятия контейнера с Playwright, локально на хост-машине;

playwright.config.ts - конфигурационный файл, для настройки запуска и прогонов автотестов на Playwright;

support - директория для хранения pages(POM), utilities(helpers);

tests - директория тестовых сценариев .spec.ts. 

1. Конфигурационные файлы docker:

docker\playwright\Dockerfile:

FROM mcr.microsoft.com/playwright:v1.46.1


RUN apt-get update && \
    apt-get install -y default-jdk && \
    apt-get clean;


RUN npm install -g http-server
RUN npm install -g allure-commandline


WORKDIR /usr/src/app

docker\docker-compose.playwright.yml:

version: "3.4"


services:
  playwright:
    build:
      dockerfile: ./playwright/Dockerfile
      context: ./
    container_name: example_playwright
    volumes:
      - ../:/usr/src/app
    ports:
      - "4808:4808"
    command: bash -c "if [ ! -d node_modules/.playwright ]; then npm install && npx playwright install --with-deps; fi
      && tail -f /dev/null"

2. Конфигурационный файл playwright.config.ts:

import { defineConfig, devices } from '@playwright/test';


import * as dotenv from 'dotenv';
import * as path from 'node:path';
import { EnvHelper } from '@utilities/EnvHelper';
import * as process from 'node:process';


dotenv.config({
    path: path.resolve(__dirname, '.env')
});


/**
 * See https://playwright.dev/docs/test-configuration.
 */
export default defineConfig({
    timeout: 150000,
    testDir: './tests',
    /* Run tests in files in parallel */
    fullyParallel: true,
    /* Fail the build on CI if you
    accidentally left test.only in the source code. */
    forbidOnly: !!process.env.CI,
    /* Retry on CI only */
    retries: process.env.CI ? 2 : 1,
    /* Opt out of parallel tests on CI. */
    workers: 4,
    /* Reporter to use. */
    reporter: 'allure-playwright',
    /* Shared settings for all the projects below. */
    use: {
        ignoreHTTPSErrors: true,
        /* Base URL to use in actions like `await page.goto('/')`. */
        // baseURL: 'http://127.0.0.1:3000',
        baseURL: EnvHelper.baseUrl,
        /* Collect trace when retrying the failed test. */
        trace: 'retain-on-failure',
        screenshot: 'only-on-failure',
        actionTimeout: 20000,
        navigationTimeout: 30000,
    },
    expect: {
        timeout: 20000,
    },








    /* Configure projects for major browsers */
    projects: [
        { name: 'setup', testMatch: /.*\.setup\.ts/ },
        {
            name: 'chromium',
            use: { ...devices['Desktop Chrome'] },
            dependencies: ['setup'],
        },
    ],
});

Что означает каждая опция можно посмотреть тут.

3. Файл PageObject support\pages\LoginPage.ts:

import { Locator, Page } from '@playwright/test';


export default class LoginPage {
    readonly page: Page;
    readonly header: Locator;
    readonly inputLogin: Locator;
    readonly inputPass: Locator;
    readonly buttonSubmit: Locator;


    constructor(page: Page) {
        this.page = page;
        this.header = page.getByText('Вход');
        this.inputLogin = page.locator('#username');
        this.inputPass = page.locator('#password');
        this.buttonSubmit = page.locator('#kc-login');
    }


    async open() {
        await this.page.goto('/');
        await this.page.waitForLoadState();
    }
}

4. Класс - шаблон, для описания переменных окружения, адаптируемый для каждого проекта индивидуально support\utilities\EnvHelper.ts:

import * as process from 'node:process';


export class EnvHelper {
    static readonly nameApp: string = String(process.env.NAME_APP);
    static readonly baseUrl: string = String(process.env.BASE_URL);
    static readonly login: string = String(process.env.LOGIN);
    static readonly password: string = String(process.env.PASSWORD);


    static readonly testTimeout: number = Number(process.env.TEST_TIMEOUT);
    static readonly actionTimeout: number = Number(process.env.ACTION_TIMEOUT);
    static readonly navigationTimeout: number = Number(process.env.NAVIGATION_TIMEOUT);
    static readonly expectTimeout: number = Number(process.env.EXPECT_TIMEOUT);
}

5. Ну и сами файлы тестовых сценариев, в данном случае тест для проверки авторизации, он же setup файл, прописанный в настройках конфигурационного файла playwright.config.ts как зависимость tests\auth.setup.ts:

import { test as setup, expect } from '@playwright/test';
import { EnvHelper } from '@utilities/EnvHelper';
import LoginPage from '@pages/LoginPage';


const adminFile = './support/.auth/storage.json';


setup('Авторизация в KeyClock', async ({ page }) => {
    const loginPage = new LoginPage(page);
    await loginPage.open();


    await loginPage.inputLogin.fill(EnvHelper.login);
    await expect(loginPage.inputLogin).toHaveValue(EnvHelper.login);
    await loginPage.inputPass.fill(EnvHelper.password);
    await expect(loginPage.inputPass).toHaveValue(EnvHelper.password);
    const responseAuth = page.waitForResponse(response =>
        response.url().includes('login-actions/authenticate'));
    await loginPage.buttonSubmit.click();
    expect((await responseAuth).status()).toBe(302);


    await page.waitForLoadState();
    await expect(page.getByText(EnvHelper.nameApp)).toBeVisible();
    await page.context().storageState({ path: adminFile });
});

Итого.

Данный шаблон подойдет не для всех web-проектов, этот шаблон подойдет для тех проектов, где используется единый сервис авторизации Keycloak, что это такое можно узнать тут. Также хотелось бы уточнить, в файле проверки авторизации auth.setup.ts мы сохраняем файл с куками storage.json, который переиспользуется в следующих тестовых сценариях, ещё одна крутая фича от Playwright, дающая возможность забыть необходимость повторной авторизации в приложении, т.е. на страницы приложения в тестах мы приходим уже авторизованными. 

Итак, шаблон автотестов для быстрого внедрения и масштабирования на проекты с единым сервисом авторизации Keycloak готов, осталось склонировать репозиторий проекта, скопировать проект-шаблон автотестов в корень проекта в папку /tests, установить Node.js и зависимости согласно файлу  package.json и наш проект-шаблон готов адаптироваться и разрастаться в полноценный фреймворк под каждый проект разработки индивидуально.

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

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

Пусть баги боятся ваших сценариев, а релизы проходят гладко! 🚀

Осталось только начать — копируйте, настраивайте, расширяйте и тестируйте с удовольствием. Удачи в автоматизации!" 💻🔥

Теги:
Хабы:
+9
Комментарии5

Публикации

Информация

Сайт
tech.fix-price.com
Дата регистрации
Численность
свыше 10 000 человек
Местоположение
Россия