Эта статья — перевод оригинальной статьи Ignacio Falk «Testing with Vitest«
Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.
Вступление
Vitest — это новая среда тестирования на базе Vite. Он все еще находится в разработке, и некоторые функции могут быть еще не готовы, но это хорошая альтернатива, которую можно попробовать и изучить.
Настройка
Давайте создадим новый проект Vite!
Примечание. Для работы Vitest требуется Vite >= v2.7.10 и Node >= v14.
npm init vite@latest ✔ Project name: · try-vitest ✔ Select a framework: · svelte ✔ Select a variant: · svelte-ts cd try-vitest npm install //use the package manager you prefer npm run dev
Теперь, когда наш проект создан, нам нужно установить все зависимости, необходимые для работы Vitest.
npm i -D vitest jsdom
Я добавил jsdom, чтобы иметь возможность мокать DOM API. По умолчанию Vitest будет использовать конфигурацию из vite.config.ts. Я добавлю в неё один плагин для svelte. Отключение hot module replacement при выполнении тестов.
Это должно выглядеть следующим образом:
import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' export default defineConfig({ plugins: [ svelte({ hot: !process.env.VITEST }), ], })
Я использую переменную env VITEST, чтобы разделить окружение тестов и разработки, но если ваша конфигурация слишком отличается, вы можете использовать другой файл конфигурации для тестов. Есть несколько вариантов сделать это.
-
Создайте файл конфигурации с именем vitest.config.ts: он будет иметь приоритет при запуске тестов.
-
Использование флага —config: используйте его как
npx vitest --config <path_to_file>
Написание тестов
Давайте напишем несколько тестов для компонента Counter, созданного по умолчанию в нашем проекте.
<script lang="ts"> let count: number = 0 const increment = () => { count += 1 } </script> <button on:click={increment}> Clicks: {count} </button> <style> button { font-family: inherit; font-size: inherit; padding: 1em 2em; color: #ff3e00; background-color: rgba(255, 62, 0, 0.1); border-radius: 2em; border: 2px solid rgba(255, 62, 0, 0); outline: none; width: 200px; font-variant-numeric: tabular-nums; cursor: pointer; } button:focus { border: 2px solid #ff3e00; } button:active { background-color: rgba(255, 62, 0, 0.2); } </style>
Чтобы написать наш первый набор тестов, давайте создадим файл с именем Counter.spec.ts рядом с нашим компонентом.
// @vitest-environment jsdom import { tick } from 'svelte'; import { describe, expect, it } from 'vitest'; import Counter from './Counter.svelte'; describe('Counter component', function () { it('creates an instance', function () { const host = document.createElement('div'); document.body.appendChild(host); const instance = new Counter({ target: host }); expect(instance).toBeTruthy(); }); it('renders', function () { const host = document.createElement('div'); document.body.appendChild(host); new Counter({ target: host }); expect(host.innerHTML).toContain('Clicks: 0'); }); it('updates count when clicking a button', async function () { const host = document.createElement('div'); document.body.appendChild(host); new Counter({ target: host }); expect(host.innerHTML).toContain('Clicks: 0'); const btn = host.getElementsByTagName('button')[0]; btn.click(); await tick(); expect(host.innerHTML).toContain('Clicks: 1'); }); });
Добавление строки комментария @vitest-environment jsdom вверху файла позволит нам мокать DOM API для всех тестов в файле. Этого можно избежать в каждом файле с помощью файла конфигурации. Мы также можем удостовериться, что мы импортируем describe, it, expect глобально. Делаем это тоже через конфигурационный файл. Также нам нужно сделать типы доступными, добавив типы vitest/globals в ваш файл tsconfig.json (вы можете пропустить это, если не используете TypeScript).
import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' export default defineConfig({ plugins: [svelte({ hot: !process.env.VITEST })], test: { globals: true, environment: 'jsdom', }, });
{ "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "baseUrl": ".", "allowJs": true, "checkJs": true, /** *Add the next line if using globals */ "types": ["vitest/globals"] }, "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] }
Теперь нашим тестовым файлам не нужно импортировать глобальные переменные, и мы можем удалить настройку среды jsdom.
import { tick } from 'svelte'; import Counter from './Counter.svelte'; describe('Counter component', function () { // tests are the same });
Команды
Есть четыре команды для запуска из cli:
-
dev: запустить vitest в режиме разработки -
related: запускает тесты для списка исходных файлов -
run: запустить тесты один раз -
watch: режим по умолчанию, такой же, как при запуске vitest. Наблюдает за изменениями, а затем повторно запускает тесты.
Модификаторы тестов
Существуют модификаторы для тестов, которые изменят способ выполнения ваших тестов.
-
.only сосредоточится на одном или нескольких тестах, пропустив остальные
-
.skip пропустит указанный тест
-
.todo пометит тест, которq будtn реализован позже
-
.concurrently будет запускать непрерывные тесты, помеченные как concurrent параллельно. Этот модификатор можно комбинировать с предыдущими. Например:
it.concurrently.todo("сделать что-то асинхронное")
Assertions
Vitest поставляется с assertions, совместимыми с chai и jest
expect(true).toBeTruthy() //ok expect(1).toBe(Math.sqrt(4)) // false
Список доступных assertions см. в документации по API.
Покрытие
Для отчетов о покрытии нам нужно будет установить c8 и запустить тесты с флагом --coverage.
npm i -D c8 npx vitest --coverage
Это даст нам хороший отчет о покрытии.

Папка coverage будет создана в корне проекта. Вы можете указать желаемый тип вывода в файле конфигурации.
import { defineConfig } from 'vite'; import { svelte } from '@sveltejs/vite-plugin-svelte'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [svelte({ hot: !process.env.VITEST })], test: { globals: true, environment: 'jsdom', coverage:{ reporter:['text', 'json', 'html'] // change this property to the desired output } }, });
UI
Вы также можете запустить vitest с помощью пользовательского интерфейса, который поможет вам визуализировать выполняемые тесты и их результаты. Давайте установим необходимый пакет и запустим его с флагом —ui.
npm i -D @vitest/ui npx vitest --ui
Мне нравится этот интерфейс. Он даже позволяет вам прочитать код тестов и открыть его в редакторе.

Больше возможностей
Vitest поставляется со многими другими функциями, такими как тестирование снепшотами, мокинг, фальшивые таймеры и многое другое, что вы можете знать из других библиотек тестирования.
Переход на Vitest (из проекта Vite с использованием jest)
Если вы работаете над небольшим проектом или только начинаете его, вам может потребоваться адаптировать файл конфигурации, и на этом все. Если вы используете мокинг функции, Vitest использует TinySpy, а для фальшивых таймеров — @sinonjs/fake-timers. Проверьте совместимость. Кроме того, не забудьте импортировать {vi} из vitest, если вы будете его использовать. Еще одна вещь, которую вам может понадобиться настроить, — это установочный файл. Например, чтобы использовать сопоставители jest-dom, мы можем создать установочный файл.
import '@testing-library/jest-dom'
и объявим его в нашем конфигурационном файле.
export default defineConfig(({ mode }) => ({ // ... test: { globals: true, environment: 'jsdom', setupFiles: ['<PATH_TO_SETUP_FILE>'] } }))
Вот пример миграции VitePress на Vitest. (Есть некоторые изменения в ts-config, но вы можете увидеть, где добавлен vitest, и файл vitest.config.ts)
Последние мысли
Несмотря на то, что Vitest все еще находится в разработке, он выглядит очень многообещающе, и тот факт, что они сохранили API, очень похожий на Jest, делает миграцию очень плавной. Он также поставляется с поддержкой TypeScript (без пакета внешних типов). Использование одного и того же файла конфигурации (по умолчанию) позволяет очень быстро сосредоточиться на написании тестов. Я с нетерпением жду v1.0.0
ссылка на оригинал статьи https://habr.com/ru/post/664350/
Добавить комментарий