27. Тестирование
Надёжный проект без тестов — это не надёжный проект. Astro хорошо вписывается в современную экосистему тестирования: Vitest для юнит-тестов, Testing Library для React-островов и Playwright для end-to-end сценариев.
Vitest — юнит-тесты
Заголовок раздела «Vitest — юнит-тесты»Vitest — это быстрый тест-раннер, совместимый с Jest API. Устанавливаем:
npm install -D vitest @vitest/uiНастройка в astro.config.mjs:
import { defineConfig } from 'astro/config';
export default defineConfig({ vite: { test: { globals: true, // describe, it, expect без импорта environment: 'node', // или 'happy-dom' для DOM-тестов }, },});Пример юнит-теста для утилитарной функции:
import { describe, it, expect } from 'vitest';import { generateSlug, truncate, formatDate } from './helpers';
describe('generateSlug', () => { it('переводит в нижний регистр', () => { expect(generateSlug('Hello World')).toBe('hello-world'); });
it('заменяет пробелы на дефисы', () => { expect(generateSlug('astro web framework')).toBe('astro-web-framework'); });
it('удаляет специальные символы', () => { expect(generateSlug('TypeScript: глубокое погружение!')).toBe('typescript-glubokoe-pogruzhenie'); });});
describe('truncate', () => { it('обрезает текст до указанной длины', () => { expect(truncate('Long text here', 8)).toBe('Long tex...'); });
it('не обрезает короткий текст', () => { expect(truncate('Short', 100)).toBe('Short'); });});@astrojs/check для проверки типов
Заголовок раздела «@astrojs/check для проверки типов»Официальный инструмент для проверки TypeScript в .astro файлах:
npm install -D @astrojs/check typescriptДобавляем скрипт в package.json:
{ "scripts": { "check": "astro check", "test": "vitest run", "test:watch": "vitest", "test:ui": "vitest --ui", "test:coverage": "vitest run --coverage" }}Запуск: npm run check выведет все TypeScript ошибки в .astro файлах.
Тестирование React-островов с Testing Library
Заголовок раздела «Тестирование React-островов с Testing Library»npm install -D @testing-library/react @testing-library/jest-dom happy-domКонфигурируем среду для DOM-тестов:
import { defineConfig } from 'vitest/config';
export default defineConfig({ test: { environment: 'happy-dom', setupFiles: ['./src/test/setup.ts'], globals: true, },});import '@testing-library/jest-dom';Пишем тест для React-компонента:
import { render, screen, fireEvent } from '@testing-library/react';import { Counter } from './Counter';
describe('Counter', () => { it('отображает начальное значение', () => { render(<Counter initialValue={5} />); expect(screen.getByText('5')).toBeInTheDocument(); });
it('увеличивает счётчик при клике', () => { render(<Counter initialValue={0} />); fireEvent.click(screen.getByRole('button', { name: /увеличить/i })); expect(screen.getByText('1')).toBeInTheDocument(); });
it('не уходит ниже нуля', () => { render(<Counter initialValue={0} />); fireEvent.click(screen.getByRole('button', { name: /уменьшить/i })); expect(screen.getByText('0')).toBeInTheDocument(); });});E2E тестирование с Playwright
Заголовок раздела «E2E тестирование с Playwright»Playwright тестирует реальный браузер. Устанавливаем:
npm init playwright@latestПример e2e теста:
import { test, expect } from '@playwright/test';
test.describe('Страница блога', () => { test('показывает список статей', async ({ page }) => { await page.goto('/blog'); await expect(page.getByRole('heading', { level: 1 })).toBeVisible(); const articles = page.getByRole('article'); await expect(articles).toHaveCount(10); });
test('открывает статью по клику', async ({ page }) => { await page.goto('/blog'); const firstPost = page.getByRole('article').first(); const title = await firstPost.getByRole('heading').textContent(); await firstPost.getByRole('link').click(); await expect(page.getByRole('heading', { level: 1 })).toHaveText(title!); });
test('работает поиск', async ({ page }) => { await page.goto('/blog'); await page.getByRole('searchbox').fill('astro'); await expect(page.getByRole('article')).toHaveCount(3); });});CI/CD конвейер тестирования
Заголовок раздела «CI/CD конвейер тестирования»name: Testson: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - run: npm ci - run: npm run check # TypeScript - run: npm run test:coverage # Vitest - run: npm run build # Сборка - run: npx playwright install --with-deps - run: npx playwright test # E2E