Поиск по сайту:

Как реализовать тестирование компонентов для приложений React с помощью Playwright


Автор выбрал программу Write for DOnations.

Введение

Тестирование имеет решающее значение для обеспечения того, чтобы программный продукт работал должным образом. Традиционно группы QA часто вручную выполняют много сквозных тестов для веб-приложений. Тем не менее, группы QA тратят значительные усилия на подготовку тестовых данных, внедрение тестов и их поддержку в течение долгого времени. Тесты также ненадежны, поскольку требуют интеграции между несколькими службами, сторонними зависимостями и базами данных. Именно по этим вопросам тестирование компонентов для веб-приложений важно и сейчас привлекает больше внимания как разработчиков программного обеспечения, так и QA-инженеров. Тестирование компонентов позволяет им заранее протестировать свой графический пользовательский интерфейс (GUI) и сокращает время и усилия, необходимые для реализации, создания, выполнения и поддержки тестов с течением времени.

Node.js для написания тестов в Playwright.

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

Предпосылки

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

  • Сервер Ubuntu 20.04 с пользователем без полномочий root с поддержкой sudo и не менее 2 ГБ ОЗУ. Чтобы начать работу, следуйте нашему Руководству по начальной настройке сервера для Ubuntu 20.04.
  • Как установить Node.js на Ubuntu 20.04, чтобы убедиться, что вы устанавливаете правильную версию.
  • Гит установлен на сервере. Прочтите наше руководство Как установить Git на Ubuntu 20.04, чтобы установить Git, если он еще не установлен.
  • Знакомство с фронтенд-разработкой на React.
  • Знание сквозного тестирования, тестирования API.

Шаг 1 — Развертывание приложения погоды с помощью React

На этом этапе вы развернете приложение погоды на основе React, которое вам понадобится для этого руководства. Приложение использует бесплатную версию API OpenWeather для доступа к текущим данным о погоде в любом городе.

Чтобы развернуть приложение на своем сервере, сначала создайте новый каталог для хранения кода приложения, а затем перейдите во вновь созданный каталог. Обязательно замените Projects предпочитаемым именем каталога:

mkdir Projects
cd Projects

Далее клонируем код приложения с GitHub:

git clone https://github.com/do-community/react-component-testing-demo.git

Затем перейдите в каталог react-component-testing-demo и используйте команду git checkout, чтобы проверить ветку app:

cd react-component-testing-demo
git checkout app

Далее устанавливаем зависимости для приложения погоды:

npm install

После завершения установки откройте приложение:

npm run start

Консоль отобразит следующий вывод:

Output
Compiled successfully! You can now view demo-playwright-component-testing in the browser. Local: http://localhost:3000/demo-playwright-component-testing On Your Network: http://192.168.1.7:3000/demo-playwright-component-testing Note that the development build is not optimized.

Примечание:

В новом терминале выполните следующую команду:

ssh -L 3000:localhost:3000 your_non_root_user@your_server_ip

После подключения к серверу перейдите по адресу http://localhost:3000/demo-playwright-component-testing в веб-браузере вашего локального компьютера. Держите второй терминал открытым на протяжении оставшейся части этого руководства.

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

Введите Hanoi (который находится во Вьетнаме) в поле поиска. Приложение отобразит текущую погоду в Ханое:

Согласно результатам, на момент поиска погода в Ханое (Вьетнам) была +27°C с рассеянной облачностью. Закат произошел в 17:38, влажность 70 процентов, скорость ветра 2,8 метра в секунду (м/с), атмосферное давление 1016 гектопаскалей (гПа).

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

Шаг 2 — Установка тестовых зависимостей

На этом шаге вы установите тестовые зависимости, чтобы позже на шаге 3 реализовать тестирование компонентов с помощью Playwright.

Для начала выполните следующую команду:

npm init playwright@latest -- --ct

Эта команда инициирует процесс генерации кода, который позволит вам писать тесты с помощью Playwright. В зависимости от вашего выбора, независимо от того, используете ли вы Vue framework для разработки, автоматически сгенерированный код будет другим.

Вы получите следующий вывод в консоли:

Output
Need to install the following packages: create-playwright@1.17.123 Ok to proceed? (y)

Нажмите Y, а затем Enter, чтобы продолжить. Затем вам будет предоставлена возможность выбрать, хотите ли вы использовать в своем проекте TypeScript или JavaScript:

Output
Getting started with writing end-to-end tests with Playwright: Initializing project in '.' ? Do you want to use TypeScript or JavaScript? … TypeScript ▸ JavaScript

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

Output
? Which framework do you use? (experimental) … ▸ react vue svelte

Выберите react, так как это то, что использует приложение погоды. Вывод спросит, хотите ли вы установить браузеры Playwright:

Output
? Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) ‣ true

Выберите Y, чтобы установить их, чтобы вам не пришлось устанавливать их вручную позже.

Далее вас спросят, хотите ли вы установить зависимости операционной системы:

Output
Install Playwright operating system dependencies (requires sudo / root - can be done manually via 'sudo npx playwright install-deps')? (y/N) ‣ yes

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

Теперь будут установлены все необходимые зависимости, а также три браузера: Chromium, Firefox и WebKit. Кроме того, создается новый каталог с именем playwright, который состоит из файлов index.html и index.js, необходимых для визуализации компонентов во время тестирование. Кроме того, для запуска тестирования компонентов создается новый файл конфигурации с именем playwright-ct.config.js. Вы можете настроить этот файл конфигурации, чтобы изменить поведение теста компонента, например, хотите ли вы, чтобы он запускался только в браузере Chromium.

Примечание. Сценарий test-ct должен быть автоматически сгенерирован в файле package.json, как показано ниже:

"scripts": {
    "start": "react-scripts start",
    "test-ct": "playwright test -c playwright-ct.config.js"
  },

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

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

Шаг 3 — Написание теста компонента для CityComponent

Приложение погоды состоит из двух компонентов: CityComponent и WeatherInfoComponent. На этом шаге вы напишете скрипт для тестирования компонента CityComponent. В этом коде вы будете писать два теста для CityComponent. Первый тест проверит, принимает ли поле ввода города текстовый ввод. Второй тест проверяет, выполняет ли кнопка Search метод fetchWeather после нажатия кнопки.

Для начала перейдите в каталог src:

cd src

Затем создайте каталог tests для хранения вашего теста:

mkdir tests

Затем перейдите во вновь созданный каталог:

cd tests

Теперь в каталоге tests создайте и откройте новый тестовый файл с именем CityComponent.spec.jsx, используя nano. или предпочитаемый вами редактор кода:

nano CityComponent.spec.jsx

Каждая тестовая среда поставляется с определенным синтаксисом для тестовых файлов, чтобы исполнитель знал, где искать файлы, когда он хочет собрать тестовые файлы и выполнить их. Для Playwright платформа будет искать файлы *.spec.* и рассматривать их как тестовые файлы.

Расширение .jsx расшифровывается как JavaScript XML, что позволяет добавлять теги HTML в ваш файл JavaScript. Файл .jsx позволяет вам монтировать CityComponent в ваш тест, и вы делаете это, добавляя тег CityComponent.

Теперь вы начнете создавать только что созданный файл CityComponent.spec.jsx. Добавьте следующий код в ваш файл:

import { test, expect } from '@playwright/experimental-ct-react';
import { CityComponent } from '../modules/CityComponent';

В этом коде вы импортируете библиотеку @playwright/experimental-ct-react, чтобы запустить тестирование компонентов в Playwright для вашего теста. Вы также импортируете CityComponent, чтобы позже смонтировать его в свой тест.

С помощью второй команды import вы помещаете файл CityComponent в каталог src/modules. Файл реализует код для страницы поиска, которая позволяет пользователям вводить название города и искать погоду в городе.

Затем добавьте следующий код в файл CityComponent.spec.jsx:

...

const cityLocator = '[placeholder="City"]'
const searchButtonLocator = '[type="submit"]'

const cityName = 'Hanoi'

В Playwright вам необходимо иметь локатор пользовательского интерфейса элемента, чтобы взаимодействовать с нужным элементом пользовательского интерфейса. Здесь вы определяете две переменные const с именами cityLocator и searchButtonLocator. Ключевое слово const указывает на постоянную переменную, что означает, что вы не можете изменить ее значение после присвоения ей начального значения. [placeholder=City] и [type=submit] – это локаторы CSS для кнопки ввода текста и поиска в CityComponent.

В третьей строке кода вы создаете новую переменную cityName для хранения названия города, который вы хотите найти, в данном случае Hanoi.

Затем вы добавите свой первый тестовый блок кода в файл CityComponent.spec.jsx, который проверит, принимает ли cityField текстовые значения. Добавьте следующий код в ваш файл:

...

test('cityField accepts text input', async ({ mount }) => {
    const cityComponent = await mount(<CityComponent /> );
    const cityField = cityComponent.locator(cityLocator)
    
    await cityField.fill(cityName)

    await expect(cityField).toHaveValue(cityName)
});

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

Добавляя ключевое слово async в тестовый блок test(cityField accept text input, async ({ mount }) => { ..}), вы указываете Playwright запустить этот тест асинхронно. При асинхронном подходе вам не нужно ждать последовательного выполнения каждой строки кода; вместо этого коды выполняются параллельно. Это поможет вашему тесту работать быстрее.

Затем вы определяете cityComponent, добавляя тег CityComponent в метод mount. Платформа React также запускает код асинхронно, поэтому при работе с компонентами React вам необходимо добавить ключевое слово await перед монтированием CityComponent. Используя ключевое слово await, Playwright будет ждать, пока смонтированный CityComponent завершит выполнение своего кода, прежде чем присвоить смонтированное значение переменной cityComponent.

Затем вы находите cityField с помощью его локатора, который вы создали как переменную cityLocator.

Наконец, вы заполняете cityField значением cityName и проверяете, имеет ли cityField то же значение, что и cityName. Используя здесь ключевые слова await, вы гарантируете, что cityField заполнено cityName, прежде чем проверять, соответствует ли cityField имеет значение cityName.

Теперь вы добавите второй тестовый блок кода в файл CityComponent.spec.jsx, который проверит, вызывает ли кнопка Search метод fetchWeather. . Добавьте следующий код в ваш файл:

...

test('Click on `Search` button executes fetchWeather prop', async ({ mount }) => {
    let isCalled = false
    const cityComponent = await mount(
        <CityComponent
        fetchWeather={() => isCalled = true}
        />
    );

    await cityComponent.locator(cityLocator).fill(cityName)
    await cityComponent.locator(searchButtonLocator).click()

    expect(isCalled).toBeTruthy()
});

Во втором тестовом блоке, как и в первом, вы добавляете метод mount в качестве параметра в функцию async. Добавив ключевое слово async в тестовый блок test(Нажмите кнопку «Поиск», чтобы выполнить свойство fetchWeather, async ({ mount }), вы указываете Playwright запустить этот тест асинхронно.

Внутри тестовой функции вы сначала создаете новую переменную с именем isCalled, чтобы позже можно было проверить, был ли вызван метод fetchWeather. Переменная let позволяет определить новую переменную и изменить значение переменной, в отличие от переменной const, которая не позволяет изменять значение переменной.

Затем вы определяете cityComponent и назначаете его методу mount для внедрения фактического CityComponent. В тег CityComponent вы добавляете строку fetchWeather={() => isCalled=true}. Это означает, что если вызывается метод fetchWeather, значение isCalled будет обновлено до true.

Затем вы заполняете ввод текста города с помощью cityName, а затем используете метод click для имитации действий пользователей, нажимающих кнопку Search на Страница пользовательского интерфейса.

Наконец, вы проверяете, является ли переменная isCalled true или нет, используя метод toBeTruthy.

На этом этапе ваш файл будет содержать следующий код:

import { test, expect } from '@playwright/experimental-ct-react';
import { CityComponent } from '../modules/CityComponent';

const cityLocator = '[placeholder="City"]'
const searchButtonLocator = '[type="submit"]'

const cityName = 'Hanoi'

test('cityField accepts text input', async ({ mount }) => {
    const cityComponent = await mount(<CityComponent /> );
    const cityField = cityComponent.locator(cityLocator)
    
    await cityField.fill(cityName)

    await expect(cityField).toHaveValue(cityName)
});

test('Click on `Search` button executes fetchWeather prop', async ({ mount }) => {
    let isCalled = false
    const cityComponent = await mount(
        <CityComponent
        fetchWeather={() => isCalled = true}
        />
    );

    await cityComponent.locator(cityLocator).fill(cityName)
    await cityComponent.locator(searchButtonLocator).click()

    expect(isCalled).toBeTruthy()
});

Сохраните и закройте файл. Если вы используете nano, сохраните и выйдите, нажав CTRL+X.

Вы написали сценарий для проверки компонента CityComponent, который содержит два тестовых блока: один для проверки того, принимает ли поле ввода города Hanoi в качестве входных данных, и один для проверки выполняет ли кнопка Search метод fetchWeather после нажатия кнопки. На следующем шаге вы напишете тест компонента для второго компонента приложения погоды, WeatherInfoComponent.

Шаг 4 — Написание теста компонента для WeatherInfoComponent

На этом шаге вы напишете тест для WeatherInfoComponent, второго компонента тестируемого приложения погоды. Тест проверяет, содержит ли weatherComponent текст Hanoi после получения Hanoi в качестве входных данных weatherInfo.

Сначала в каталоге tests создайте и откройте новый тестовый файл с именем WeatherInfoComponent.spec.jsx:

nano WeatherInfoComponent.spec.jsx

Добавьте следующее содержимое в файл WeatherInfoComponent.spec.jsx:

import { test, expect } from '@playwright/experimental-ct-react';
import { WeatherComponent } from '../modules/WeatherInfoComponent';

Здесь вы импортируете методы expect из библиотеки @playwright/experimental-ct-react, чтобы можно было запустить тест компонента в Playwright.

Затем вы монтируете WeatherComponent в свой тест, импортируя WeatherInfoComponent. Файл WeatherInfoComponent заполняет страницу результатов, которая показывает погоду в городе, предоставленную пользователями, и находится в каталоге src/modules.

Затем добавьте следующий блок кода в тестовый файл WeatherInfoComponent.spec.jsx:

...

test('WeatherInfo accepts name and value', async ({ mount }) => {
    const weatherInfo = {"coord":{"lon":105.8412,"lat":21.0245},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":302.15,"feels_like":301.35,"temp_min":302.15,"temp_max":302.15,"pressure":1003,"humidity":35,"sea_level":1003,"grnd_level":1002},"visibility":10000,"wind":{"speed":2.71,"deg":73,"gust":3.29},"clouds":{"all":0},"dt":1673694125,"sys":{"type":1,"id":9308,"country":"VN","sunrise":1673652961,"sunset":1673692464},"timezone":25200,"id":1581130,"name":"Hanoi","cod":200}
    const weatherComponent = await mount(<WeatherComponent
    weather={(weatherInfo)}
    /> );
    await expect(weatherComponent).toContainText('Hanoi')
});

Здесь вы определяете формат JSON.

Затем вы определяете другую const с именем weatherComponent, которая извлекает свое значение из WeatherComponent.

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

Наконец, в await expect(weatherComponent).toContainText(Hanoi) вы проверяете, содержит ли переменная weatherComponent текст Hanoi. Здесь вам нужно использовать await, потому что Playwright также выполняет код асинхронно, а с помощью await вы убедитесь, что переменная weatherComponent получает значение из WeatherComponent, прежде чем проверять, содержит ли weatherComponent текст Hanoi.

Ваш полный файл WeatherInfoComponent.spec.jsx будет содержать следующие строки кода:

import { test, expect } from '@playwright/experimental-ct-react';
import { WeatherComponent } from '../modules/WeatherInfoComponent';


test('WeatherInfo accepts name and value', async ({ mount }) => {
    const weatherInfo = {"coord":{"lon":105.8412,"lat":21.0245},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":302.15,"feels_like":301.35,"temp_min":302.15,"temp_max":302.15,"pressure":1003,"humidity":35,"sea_level":1003,"grnd_level":1002},"visibility":10000,"wind":{"speed":2.71,"deg":73,"gust":3.29},"clouds":{"all":0},"dt":1673694125,"sys":{"type":1,"id":9308,"country":"VN","sunrise":1673652961,"sunset":1673692464},"timezone":25200,"id":1581130,"name":"Hanoi","cod":200}
    const weatherComponent = await mount(<WeatherComponent
    weather={(weatherInfo)}
    /> );
    await expect(weatherComponent).toContainText('Hanoi')
});

Сохраните и закройте файл, нажав CTRL+X.

Вы закончили писать тест для WeatherInfoComponent. Затем вы запустите тесты CityComponent и WeatherInfoComponent для всех трех установленных браузеров.

Шаг 5 — Запуск тестов компонентов

На этом шаге вы запустите тесты CityComponent и WeatherInfoComponent для всех трех установленных браузеров — Chromium, Firefox и WebKit — чтобы убедиться, что эти два компонента правильно работают в этих браузерах. .

Сначала перейдите в корневой каталог проекта:

cd ../..

После запуска команды вы окажетесь в папке react-component-testing-demo. Затем выполните следующую команду для выполнения тестов:

npm run test-ct

Playwright запустит два тестовых файла для всех трех браузеров: Chromium, Firefox и WebKit. Вы получите результаты, аналогичные следующему выводу:

Running 9 tests using 2 workers

vite v3.2.5 building for production...
✓ 89 modules transformed.
playwright/.cache/playwright/index.html      0.32 KiB
playwright/.cache/assets/index.2b5442e2.js   313.68 KiB / gzip: 81.07 KiB

  9 passed (12s)

To open last HTML report run:

  npx playwright show-report

Чтобы просмотреть отчет в формате графического интерфейса, выполните следующую команду:

npx playwright show-report

Примечание:

В новом терминале выполните следующую команду:

ssh -L 9223:localhost:9223 your_non_root_user@your_server_ip

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

Обзор отчета о тестировании отобразится в вашем браузере:

Отчет о тестировании разделен на три разных теста: cityField принимает текстовый ввод, нажатие кнопки Search выполняет свойство fetchWeather, а WeatherInfo принимает имя и значение, где каждый тест отображает общее время, затраченное на выполнение теста. , а также время выполнения теста каждого браузера.

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

Результаты показывают, что тест CityComponent, проверяющий, принимает ли поле ввода «Город» текст в качестве ввода, успешно выполнялся на Chromium. В разделе подробностей этапы выполнения теста будут содержать этапы Before Hooks и After Hooks по умолчанию. Раздел Before Hooks часто используется для первоначальной настройки, такой как вход в консоль или чтение тестовых данных. После выполнения теста раздел After Hooks часто очищает тестовые данные в тестовой среде.

Строка locator.fill() показывает, как элемент расположен в тестовой реализации. В этом случае элемент находится с помощью селектора CSS со значением [placeholder=City].

Строка expect.toHaveValue показывает утверждение теста. В этом тесте вы ожидаете, что cityField будет иметь значение cityName.

Теперь вы полностью внедрили и запустили тесты CityComponent и WeatherInfoComponent для своего погодного приложения и просмотрели отчет о тестировании, чтобы убедиться, что эти два компонента работают на Chromium, Firefox и WebKit. Вы можете ознакомиться с полным исходным кодом как приложения, так и тестов в основной ветке репозитория GitHub.

Заключение

Теперь вы использовали Playwright для реализации тестирования компонентов в приложении погоды на основе React. Сначала вы установили необходимые тестовые зависимости для компонентов приложения погоды CityComponent и WeatherInfoComponent. Затем вы написали и запустили тесты компонентов для двух компонентов. Наконец, вы просмотрели отчет о тестировании в формате графического интерфейса, чтобы убедиться, что компоненты работают должным образом.

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