Тестирование приложений Next.js с использованием Playwright
Усовершенствуйте тестирование приложений Next.js с помощью Playwright — инструмента для автоматизации браузеров Chromium, Firefox и WebKit. Готовитесь ли вы к сквозным (E2E) или интеграционным тестам, Playwright предлагает безупречную работу на всех платформах. В этом руководстве я расскажу вам, как настроить и запустить первый тест Playwright E2E для приложения Next.js.
Быстрый старт
Если вы хотите сразу же приступить к делу, самый быстрый способ начать — использовать на create-next-app
примере with-playwright
:
npx create-next-app@latest --example with-playwright with-playwright-app
Затем запустите тесты npm run test:e2e
. Продолжайте читать, чтобы узнать, как настроить Playwright в существующем проекте Next.js.
Ручная настройка
Для тех из вас, у кого уже есть проект NPM и кто предпочитает ручную настройку, не беспокойтесь, все готово! Начните с установки пакета @playwright/test
:
npm install --save-dev @playwright/test
Теперь обновите скрипты package.json
, включив в них Playwright:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test:e2e": "playwright test"
}
}
Как составить свой первый E2E-тест Playwright
Представьте, что у вас есть две страницы Next.js, настроенные, как показано:
import Link from 'next/link'
export default function Home() {
return (
<nav>
<Link href="/about">About</Link>
</nav>
)
}
// pages/about.js
export default function About() {
return (
<div>
<h1>About Page</h1>
</div>
)
}
Пришло время убедиться, что ваша навигация работает безупречно. Вот как составить для нее тест:
import { test, expect } from '@playwright/test'
test('navigates to the about page', async ({ page }) => {
await page.goto('/')
await page.getByRole('link', { name: /About/ }).click();
await expect(page).toHaveURL('/about')
await expect(page.getByRole('heading', { level: 1 })).toContainText('About Page');
})
Примечание: Используйтеpage.goto('/')
и"baseURL": "http://ray.run"
установите вplaywright.config.ts
файле краткий код.
Запуск тестов Playwright
Помните, что Playwright тестирует настоящее приложение Next.js, поэтому сервер должен быть запущен и работать. Также неплохо протестировать производственную сборку, чтобы имитировать поведение в реальном мире.
Запустите сервер Next.js:
npm run build
npm run start
Затем в другом терминале запустите тесты Playwright:
npm run test:e2e
Используйте webServerдля запуска сервера разработки
С помощью функции webServer Playwright вы можете позволить ему запустить сервер разработки и убедиться, что он готов к работе.
Просто добавьте эту конфигурацию в свой playwright.config.ts
файл:
import { type PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
webServer: {
command: 'npm run dev',
port: 3000,
reuseExistingServer: !process.env.CI,
},
};
export default config;
Теперь вы можете запускать тесты без необходимости запуска сервера разработки вручную:
npm run test:e2e
Playwright c непрерывной интеграцией (CI)
При работе на CI Playwright по умолчанию переходит в безголовый режим. Чтобы иметь все зависимости, выполните:
npx playwright install-deps
Использование экспериментального тестового режима для Playwright
Документации по этому поводу пока не так много, но команда Vercel работает над экспериментальным тестовым режимом для Playwright. Этот режим позволит вам перехватывать запросы и имитировать ответы. Это полезно для тестирования маршрутов API и другого серверного кода.
Предположим, у вас есть маршрут API по адресу /api/hello
:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ name: 'Foo' });
}
Этот маршрут вызывается с помощью getServerSideProps
:
import { GetServerSideProps } from 'next'
export default function Home({ name }) {
return <div data-testid="message">Hello {name}</div>
}
export const getServerSideProps: GetServerSideProps = async () => {
const res = await fetch('http://localhost:3000/api/hello')
const data = await res.json();
return {
props: {
name: data.name,
},
}
}
Теперь вы хотите написать тест, который проверяет, отображает ли страница имя, возвращаемое API.
import { test, expect } from '@playwright/test';
test('prints name retrieved from the API', async ({ page, msw }) => {
await page.goto('/');
await expect(page.getByTestId('message')).toHaveText('Hello Foo');
});
Последний утверждает, что страница отображает имя, возвращаемое API. Однако, используя экспериментальный тестовый прокси, вы можете перехватить запрос /api/hello
и имитировать ответ.
Имитация ответов API
Во-первых, вам нужно установить msw, чтобы имитировать ответы.
npm install -D msw
Затем вам нужно изменить импорт на next/experimental/testmode/playwright/msw
:
import { test, expect } from 'next/experimental/testmode/playwright/msw'
Теперь вы можете имитировать ответ:
import { test, expect, rest } from 'next/experimental/testmode/playwright/msw';
test('prints name retrieved from the API', async ({ page, msw }) => {
msw.use(
rest.get('http://localhost:3000/api/hello', (req, res, ctx) => {
return res.once(
ctx.status(200),
ctx.json({
name: 'Bar',
})
)
})
);
await page.goto('/');
await expect(page.getByTestId('message')).toHaveText('Hello Bar');
});
Маршрутизатор приложений
Вы также можете использовать экспериментальный тестовый режим для тестирования приложения/маршрутизатора Next.js.
Определите маршрут:
export async function GET() {
return Response.json({ name: 'Foo' })
}
Получите данные на своей странице:
const getData = async () => {
const res = await fetch('http://localhost:3000/api/hello')
const data = await res.json();
return {
name: data.name,
}
};
export default async () => {
const { name } = await getData();
return <div data-testid="message">Hello {name}</div>
}
Теперь вы можете протестировать страницу:
import { test, expect, rest } from 'next/experimental/testmode/playwright/msw';
test('prints name retrieved from the API', async ({ page, msw }) => {
msw.use(
rest.get('http://localhost:3000/api/hello', (req, res, ctx) => {
return res.once(
ctx.status(200),
ctx.json({
name: 'Bar',
})
)
})
);
await page.goto('/');
await expect(page.getByTestId('message')).toHaveText('Hello Bar');
});
Ошибка: нет информации о тесте
Похоже, что при запуске тестов в экспериментальном режиме тестирования может возникнуть следующая ошибка:
Error: No test info
Это происходит, когда вы пытаетесь получить доступ к веб-серверу напрямую, вне теста. Насколько я могу судить, нет возможности получить прямой доступ к веб-серверу Next.js при работе в экспериментальном тестовом режиме. Вы можете получить к нему доступ, только пройдя тест Playwright.
Заключение
В заключение отметим, что интеграция Playwright в рабочий процесс Next.js обеспечивает проверенное и надежное приложение. Если вы впервые используете Playwright, вам следует ознакомиться с программой просмотра трассировки, поскольку она поможет вам отлаживать тесты. А теперь приступайте к созданию тестов, которые не оставят равнодушным ни одного камня. Приятного тестирования!