Тестирование с помощью Vitest

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Эта статья — перевод оригинальной статьи 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/


Интересные статьи

Интересные статьи

Недавно перед командой аналитики подбора преподавателей встала задача усовершенствования модели матчинга учеников преподавателей. Перед вами статья о том, как мы это делали.
Защита приложений от обратной разработки - сложный процесс, который может отнимать много сил и нервов. Статья расскажет о нескольких подходах защиты приложений под операционную систему iOS с использов...
Программа GNU Image Manipulation Program (GIMP) – моё решение проблемы редактирования изображений. Набор инструментов у этого редактора очень мощный и удобный, за исключением инструме...
Справедливое моделирование — это область искусственного интеллекта, которая гарантирует, что на результат машинного моделирования не влияют такие защищённые атрибуты, как пол, раса, религ...
Разработчиками из Эдинбургского Университета представлен новый алгоритм для создания реалистичных движений персонажей в играх. Обученная на Motion Capture траекториях нейросеть пытается копир...