Перевод статьи Edd Yerburgh: Vue Test Utils and Jest: how to write simple unit tests for your front end.
В этой обучающей статье я покажу вам, как тестировать компоненты Vue.
Мы собираемся писать модульные тесты и тесты снимками с помощью Jest и Vue Test Utils. Всё это без использования Webpack.
Это руководство предназначено для пользователей, знакомых с модульным тестированием. Если вы новичок в модульном тестировании, ознакомьтесь с моёй статьей про модульное тестирование Vue-компонентов для новичков.
Я сделал простой проект для старта. Склонируйте его в свой каталог:
git clone https://github.com/eddyerburgh/vue-unit-test-starter.git
Примечание переводчика: со времени написания оригинальной статьи новая версия Vue Test Utils (всё ещё бета-версия), я сделал форк репозитория автора для использования актуальной на момент перевода версии Vue Test Utils , и если хотите использовать стартовый проект с последней версией Vue Test Utils, то можете склонировать этот репозиторий:
```sh
git clone [email protected]:lex111/jest-vue-example.git
```
В любом случае в статье будет использоваться синтаксис именно новой версии Vue Test Utils в целях придания актуальности переводимой статье.
Теперь перейдите в каталог с репозиторием и установите зависимости:
cd vue-unit-test-starter && npm install
Когда зависимости установлены, запустите сервер разработки:
npm run dev
Теперь мы можем вернуться к коду.
Единственное, что нужно обсудить — псевдонимы. Это способ использования сокращённой записи для импорта файла. Вместо длинных операторов импорта, как показано ниже:
import someModule from '../../../../../src/components/someModule'
Можно использовать сокращённую нотацию или псевдоним. Самый распространённый псевдоним — это символ @
, который указывает на каталог src
.
import someModule from '@/components/someModule'
Примечание: вы можете установить любой псевдоним, который захотите, но проекты vue-cli используют @
для ссылки на каталог src
.
В проектах vue-cli Webpack используется для добавления этого псевдонима. Это классно, но мы не используем Webpack для выполнения наших тестов. По этой причине нужен другой способ разрешения псевдонимов.
Вот тут-то и вступает в дело Babel. Есть плагин babel-plugin-module-resolver
, разрешающий псевдонимы в Babel. Вы можете увидеть его использование в файле .babelrc
. Он применяется только в тестовом окружении, поскольку вы запускаете создание сборки в окружении разработки или продакшена, Webpack разрешает данный псевдоним.
Взгляните на следующий файл:
https://gist.github.com/eddyerburgh/b569d23402611d14b40a2e4a1d534292
Итак, мы получили общее представление проекта, пришло время добавить Jest.
Jest — фреймворк для тестирования. Это один из самых быстрых фреймворков для тестирования однофайловых Vue-компонентов (SFC).
Помимо выполнение тестов, Jest поставляется с другими возможностями из коробки, такими как подставные (mock) объекты, покрытие кода и тестирование снимками.
Первое, что нужно сделать, это установить Jest:
npm install --save-dev jest
Для тестирования однофайловых компонентов, вам нужно скомпилировать их в JavaScript до выполнения тестов. Если вы попытаетесь запустить нескомпилированный однофайловый компонент, вы получите синтаксическую ошибку.
Jest не компилирует файлы с расширением .vue
из коробки. Вам нужно указать это для их компиляции. Это достигается путём добавления поля jest
в файл package.json
.
Добавьте код ниже в свой package.json
.
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
}
}
Вы видите поле moduleFileExtensions
. Это указывает Jest, чтобы он выполнял файлы с расширением .vue
, а также с расширениями .js
и .json
.
Также есть поле transform
. Оно указывает Jest, как компилировать файлы перед их выполнением. Он находит все файлы с расширением .js
и компилирует их с помощью babel-jest
. Все vue-файлы компилируются с использованием vue-jest
.
Это пользовательские преобразования, созданные для Jest: babel-jest
компилирует JavaScript, vue-jest
берёт файлы с расширением .vue
и компилирует их в JavaScript.
Учитывая написанное выше, необходимо установить два пакета:
npm install --save-dev babel-jest vue-jest
Хорошо, теперь нам нужно добавить тест «на дым» (smoke test), чтобы убедиться, что всё работает, как следует.
В src/components
создайте каталог __tests__
. Добавьте файл MessageToggle.spec.js
. Таким образом полный путь к тесту будет src/components/__tests__/MessageToggle.spec.js.
Скопируйте приведённый ниже код:
https://gist.github.com/eddyerburgh/d23aca65d764b2ae1a2484f07b7a8166
Jest автоматически запускает все JS-файлы в каталоге __tests__
. Он даже добавляет переменную тестового окружения, поэтому весь тестовый скрипт выполняется Jest.
В поле script
вашего package.json
добавьте скрипт unit
:
"unit": "jest"
Теперь запустите этот скрипт:
npm run unit
Отлично, первый тест пройдён 👌.
Теперь мы напишем более сложные тесты с помощью Vue Test Utils.
Vue Test Utils в данный момент находится в бета-версии, но прямо сейчас вы можете использовать его без особых проблем, т.к. работа над API в значительной степени завершена.
Установите его:
npm install --save-dev vue-test-utils
Теперь вы напишите аналогичный тест MessageToggle.spec.js
, используя Vue Test Utils.
Скопируйте код ниже в файл src/components/__tests__/MessageToggle.spec.js
.
https://gist.github.com/lex111/557c008cb593ee4f58c8cd77582b746f
Здесь мы можем использовать функцию shallowMount
для возврата объекта-обёртки. Обёртка содержит разные вспомогательные методы, например, text
, который помогает проверять утверждения компонентов. Вы можете посмотреть полный список методов обёртки здесь.
Итак, добавим более сложный тест, выполняющий действие на компоненте Messagetoggle
. Скопируйте код ниже в MessageToggle.spec.js
:
https://gist.github.com/lex111/c941675d90b101d26126a829554a98f5
В этот раз мы нажимаем на кнопку (с #toggle-message) в MessageToggle
и проверяем, что текст тега <p>
изменился правильно.
Теперь запустите скрипт для запуска тестов:
npm run unit
Опа, тесты проходят! 🙌
Vue Test Utils абстрагирует внутренности Vue. Поэтому что вам нужно сделать — изучить API Vue Test Utils.
Теперь напишем тест для компонента List. Компонент List принимает свойства, к счастью, предоставляет способ передать свойства при монтировании компонента.
Создайте файл /src/components/__tests__/List.spec.js
и вставьте код ниже:
https://gist.github.com/lex111/8e7d1b97ef413adaedaef6a9a8bed18e
На этот раз, как вы видите, мы используем функцию shallowMount
. Это то же самое, что и mount
, за исключением того, компонент отрисовывается только на один уровень. Как правило, лучше использовать shallowMount
.
Теперь, когда вы написали модульные тесты, пришло время взглянуть на тестирование снимками.
У Jest есть такая замечательная возможность, называемая тестированием снимками.
Тестирование снимками по сути берёт копию вашего дерева компонентов в виде строки, а затем при каждом выполнении тестов сравнивает с этим снимком. Если отрисованный компонент в виде HTML-кода изменился, тест не пройдёт.
Давайте добавить тест снимка в Message.spec.js
.
Вам нужно отрисовать компонент в строку с помощью vue-server-renderer
. Возвращаемая строка не очень читабельная, поэтому добавим ещё jest-serializer-vue
, чтобы придать красивый, читаемый вид вашим снимкам.
npm install --save-dev vue-server-renderer jest-serializer-vue
Также вам нужно сообщить Jest для использования сериализатора. Добавьте поле snapshotSerializers
внутри поля jest
в ваш файл package.json
:
"snapshotSerializers": [
"<rootDir>/node_modules/jest-serializer-vue"
]
Теперь обновите List.spec.js
для добавления теста снимка:
https://gist.github.com/lex111/ac60c7e2dbd87db214f0dc74f6172577
Этот тест неглубоко монтирует компонент и отрисовывает его в строку с HTML через использование vue-server-renderer
.
Теперь запустим выполнение тестов:
npm run unit
В терминале вы увидите уведомление о сохранении только что созданного снимка. Вы можете увидеть, если перейдите в файл src/components/__tests__/__snapshots__/List.spec.js.snap
:
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`List.vue has same HTML structure 1`] = `
<ul>
<li>
list item one
</li>
<li>
list item two
</li>
</ul>
`;
Круто, это и есть снимок. 📸
Теперь, если разметка List.vue
изменится, Jest предупредит вас об этом при выполнении тестов.
Итак, теперь вы создали модульные тесты и тесты снимками, используя Jest и Vue Test Utils.
Я пропустил ряд концепций. Вы можете посмотреть на готовый репозиторий на GitHub (или посмотреть на тот же самый форк этого репозитория с использованием последней версией Vue Test Utils.), если ваш проект некорректно работает.
В Jest имеется больше возможностей для облегчения тестирования.
А у Vue Test Utils в свою очередь также есть много методов — изучите документацию.
Из-за того, что русская документация по Vue Test Utils вышла совсем недавно после больших изменений, приветствуются различные исправления опечаток и неточностей. Пожалуйста, создайте PR с обновлениями в форк оригинального репозитория на Translation Gang, так как это сообщество переводит и поддерживает документации по продуктам Vue
Модульное тестирование Vue-компонентов ещё никогда не было таким простым, так что вперёд писать тесты!
Если вы узнали что-то интересное из этой статьи, поделитесь ею и не забывайте про 👏 для того, чтобы о ней узнали другие!
Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.