Привет 👋, я Дэвид Пенг.
Прошло некоторое время с моей последней записи в блоге.
За последние два месяца я добавил 100+ юнит/компонент/ e2e тестов в свой проект Svelte (да, я не делал TDD, потому что не был достаточно знаком с тестированием 😅).
Я экспериментировал с различными тест-бегунками, постоянно измерял DX и пытался найти свой идеальный набор инструментов для тестирования. Я бы с удовольствием поделился здесь некоторыми своими знаниями и мыслями.
В этой статье я остановлюсь на базовой настройке Vitest & Playwright для тестирования наших компонентов Svelte. Вы можете ознакомиться с демо-репозиторием здесь: Демо-репозиторий для тестирования компонентов Svelte
В следующей статье блога я также напишу о расширенном тестировании компонентов и мокинге (модуль времени выполнения Svelte & networking). Оставайтесь с нами!
- Различные типы тестов
- Исполнители тестов
- Vitest: Vite-нативный фреймворк для модульного тестирования. (альтернатива: Jest, uvu)
- Playwright: Фреймворк для веб-тестирования и автоматизации. (альтернатива: Cypress)
- Когда использовать каждую программу тестирования?
- Vitest + @testing-library/svelte
- Возьмем для примера демонстрационное приложение Svelte (TypeScript)
- Экспериментальное тестирование компонентов Playwright
- Возьмем для примера демонстрационное приложение Svelte (TypeScript)
- Vitest (как прогонщик тестов) + Playwright
- Подведение итогов
- Ресурсы
- Обсуждение
- Проблемы
- Статьи
- Видео
Различные типы тестов
Вот краткое введение в каждый тип (моя точка зрения):
- Юнит-тест: Тестирование наименьшей части кода, например, простой функции.
- Интеграционный тест: Тестирование группы функций, например, получение и преобразование данных.
- Компонентный тест: Тестирование поведения/перехода компонента пользовательского интерфейса, например, взаимодействие с формой, открытие модального окна.
- Конечный тест (E2E): Полное путешествие пользователя, например, вход на сайт и ряд операций.
Исполнители тестов
Vitest: Vite-нативный фреймворк для модульного тестирования. (альтернатива: Jest, uvu)
За последние несколько месяцев вы могли слышать, как разработчики Svelte переносят свои тесты с Jest на Vitest.
Vitest намного быстрее, чем Jest, благодаря использованию Vite, и он отлично сочетается с SvelteKit (использование vite под капотом). Еще один плюс — вы можете удалить весь конфиг jest/ babel 🎊.
Отличная статья здесь: Тестирование приложения Svelte с помощью Vitest
Playwright: Фреймворк для веб-тестирования и автоматизации. (альтернатива: Cypress)
Playwright является рекомендуемым E2E-тестировщиком в сообществе Svelte. Вы также можете найти Playwright в качестве опции в create-svelte
.
Когда использовать каждую программу тестирования?
Несмотря на то, что Vitest и Playwright являются обеими программами тестирования, у них разная направленность и сценарии тестирования.
Vitest невероятно быстр благодаря мгновенной горячей перезагрузке модуля; он перезапускает тест только при каждом изменении теста, исходного кода или зависимостей, поэтому он подходит для модульных и интеграционных тестов.
Хотя Playwright был создан специально для E2E-тестирования, вам нужно собрать приложение Svelte и запустить сервер для тестирования вашего приложения, что во многом похоже на производство.
Но когда дело доходит до компонентного тестирования, у нас есть несколько вариантов:
- Бегунки для модульного тестирования, такие как Vitest, Jest или uvu + Библиотека тестирования
- Playwright/ Cypress component test (оба на базе Vite)
- Storybook (я его не пробовал 😁)
Юнит-тест | ✨ Тест компонентов ✨ | E2E тест |
---|---|---|
Vitest | Playwright |
Давайте посмотрим, как протестировать компонент Svelte с помощью Vitest & Playwright.
Поскольку мы собираемся поговорить о тестировании компонента, я хочу поделиться этим роликом с JS Party, вы также можете послушать эпизод #233
![]()
![]()
JS Party 🎉@jspartyfm
✨ @_jessicasachs о том, что она имеет в виду, когда говорит, что любит код, который «случайно поддается тестированию» ✨ ✨14:08 PM — 26 Jul 2022![]()
![]()
![]()
Vitest + @testing-library/svelte
Вы можете выполнить следующие шаги для установки Vitest или использовать Svelte Adder: svelte-add-vitest
Возьмем для примера демонстрационное приложение Svelte (TypeScript)
npm install -D vitest jsdom @testing-library/svelte
- Настройте Vitest в
vite.config.js
:
import { sveltekit } from '@sveltejs/kit/vite';
/** @type {import('vite').UserConfig} */
const config = {
plugins: [sveltekit()],
/** Add below settings */
test: {
// Jest like globals
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.ts'],
// Extend jest-dom matchers
setupFiles: ['./setupTest.js']
}
};
export default config;
- Создайте
setupTest.js
и расширьтеjest-dom
assertions/ matchers в Vitest:
import matchers from '@testing-library/jest-dom/matchers';
import { expect, vi } from 'vitest';
expect.extend(matchers);
Причину использования утверждений
jest-dom
можно найти здесь: Общие ошибки при работе с библиотекой тестирования React #Использование неправильного утверждения
- Добавьте
types
вtsconfig.json
:
{
"compilerOptions": {
"types": ["vitest/globals", "@testing-library/jest-dom"]
}
}
- Создайте
src/lib/Counter.test.ts
:
import { render, fireEvent, screen } from '@testing-library/svelte';
import Counter from './Counter.svelte';
describe('Test Counter.svelte', async () => {
it('Initial counter should be 0', async () => {
render(Counter);
expect(screen.getByText('0')).toBeInTheDocument();
});
it('Test decrease', async () => {
render(Counter);
const decreaseButton = screen.getByLabelText('Decrease the counter by one');
// Decrease by two
await fireEvent.click(decreaseButton);
await fireEvent.click(decreaseButton);
// Wait for animation
const counter = await screen.findByText('-2');
expect(counter).toBeInTheDocument();
});
it('Test increase', async () => {
render(Counter);
const increaseButton = screen.getByLabelText('Increase the counter by one');
// Increase by one
await fireEvent.click(increaseButton);
// Wait for animation
const counter = await screen.findByText('1');
expect(counter).toBeInTheDocument();
});
});
Преимущество использования
screen
в том, что вам больше не нужно обновлять структуру вызова рендеринга по мере добавления/удаления нужных вам запросов. Вам нужно только набрать screen. И пусть волшебный автозаполнитель вашего редактора позаботится обо всем остальном. (ссылка: Распространенные ошибки при использовании библиотеки тестирования React #Неиспользованиеscreen
)
- Добавьте скрипт
test
вpackage.json
:
{
"scripts": {
"test": "vitest"
}
}
Экспериментальное тестирование компонентов Playwright
Этот экспериментальный тест компонента работает на базе Vite. Для получения более подробной информации, пожалуйста, ознакомьтесь с документацией и обзорным видео от Playwright:
-
Экспериментальный: компоненты
Возьмем для примера демонстрационное приложение Svelte (TypeScript)
npm install -D @playwright/experimental-ct-svelte
- Создайте
playwright-ct.config.ts
.
import type { PlaywrightTestConfig } from '@playwright/experimental-ct-svelte';
import { resolve } from 'node:path';
const config: PlaywrightTestConfig = {
testDir: 'tests/component',
use: {
ctViteConfig: {
resolve: {
alias: {
// Setup the built-in $lib alias in SvelteKit
$lib: resolve('src/lib')
}
}
}
}
};
export default config;
- Создайте несколько файлов в рабочей области проекта Svelte:
playwright/index.html
<html lang="en">
<body>
<div id="root"></div>
<script type="module" src="/playwright/index.js"></script>
</body>
</html>
playwright/index.js
// Apply theme here, add anything your component needs at runtime here.
// Here, we import the demo project's css file
import '../src/app.css';
- Создайте
tests/component/Counter.test.ts
.
@playwright/experimental-ct-svelte
оберните @playwright/test
, чтобы обеспечить дополнительное встроенное приспособление для тестирования компонентов под названием mount
.
import { test, expect } from '@playwright/experimental-ct-svelte';
import Counter from '$lib/Counter.svelte';
test('Test Counter.svelte', async ({ mount }) => {
const component = await mount(Counter);
// Initial counter is "0"
await expect(component).toContainText("0");
// Decrease the counter
await component.locator('[aria-label="Decrease the counter by one"]').dblclick();
await expect(component).toContainText('-2');
// Increase the counter
await component.locator('[aria-label="Increase the counter by one"]').click();
await expect(component).toContainText('-1');
});
Ваш VS Code может показать ошибку, подобную этой:
Мы можем решить это, добавив include
в ваш tsconfig.json
:
{
"include": ["tests/**/*.ts"]
}
- Добавьте скрипт
test:com
вpackage.json
.
{
"scripts": {
"test:com": "playwright test -c playwright-ct.config.ts"
}
}
Vitest (как прогонщик тестов) + Playwright
Я не пробовал эту комбинацию в своих проектах, но вы можете посмотреть пример из репозитория Vitest на GitHub: Использование Playwright с Vitest в качестве тестовой машины
Подведение итогов
Я потратил значительное количество времени на написание компонентных тестов, используя как Vitest, так и Playwright. Вот некоторые из моих мыслей и отражение DX (опыт разработчика):
- Vitest + Библиотека тестирования: Настройка среды тестирования требует больше шагов и зависимостей. Мне также потребовалось некоторое время, чтобы понять концепцию и лучшие практики библиотеки тестирования и правильно использовать запросы/утверждения, но как только вы станете более уверенным, вы получите приятное удовольствие от DX.
- Экспериментальный тест компонентов Playwright: Вы можете напрямую использовать большинство преимуществ Playwright, таких как фикстуры, перехват сети, в своем тесте компонентов, а его синтаксис интуитивно понятен и довольно удобен. Пока он все еще находится в экспериментальной фазе, для того, чтобы стать более стабильным, может потребоваться некоторое время.
На мой взгляд, Vitest + Testing Library, вероятно, будет лучшим выбором на данный момент. Несмотря на то, что Vitest еще не достиг версии 1.0, мой личный опыт перехода с Jest довольно гладкий. Кроме того, Testing Library стабильна и используется многими компаниями.
Спасибо за ваше чтение.
Вы можете следить за мной в Twitter @davipon
Пожалуйста, оставьте свои мысли и опыт ниже. Буду рад услышать ваши отзывы!
Ресурсы
Обсуждение
sveltejs/kit: Vitest для модульного тестирования #5285
Проблемы
Shim SvelteKit runtime import aliases / Импортирование $app/* не работает #1485
Статьи
- Юнит-тестирование компонентов Svelte (Общество Svelte)
- Тестирование приложения Svelte с помощью Vitest
- Компонентно-ориентированные пользовательские интерфейсы
Видео