В одной из предыдущих статей было описано как использовать Cypress для e2e-тестов. Однако, чтобы протестировать побольше сценариев работы приложения удобно использовать тесты отдельных компонентов. С этим типом проверок, не придется загружать полную страницу ненужных в тесте компонентов. Это будет работать быстрее и более прицельно. В этой статье рассмотрим настройку компонентных тестов.
Содержание
- Базовый проект с Vuetify
- Первый запуск теста компонента
- Разбираемся что не так и вносим правки
- Запускаем тесты успешно
- Еще немного глобальных настроек
- Итоги
Базовый проект с Vuetify
Настройка компонентных тестов была сильно проще, если бы мы не использовали кроме Vue ничего дополнительного. Однако в реальные проекты включают много вещей. Это может быть и какой-то UI-фреймворк и реактивное хранилище.
Рассмотрим настойку тестов Cypress при использовании компонентов Vuetify. На этом примере будет понятно в чем основная проблема и как ее решать.
Создадим проект на базе Vuetify используя вариант с Vite.
В предыдущей статье упоминалось, что после запуска команды npx cypress open
мы увидим окно с выбором типа тестов: E2E Testing и Component Testing:
Если выбрать второй вариант и пройти через пару не хитрых шагов по генерированию конфигурационных файлов, то появится экран создания нового теста:
Первый запуск теста компонента
Здесь мы можем создать тест прямо из компонента. В стартовом наборе файлов проекта Vuetify есть компонент HelloWorld
. Выбрав его мы получим простейший тест. Однако запуск такого теста приведет к ошибке:
Разбираемся что не так и вносим правки
Происходит это потому, что для vue
в таком тесте не регистрируется плагин vuetify
. Ведь теперь мы не грузим все приложение, не загружается файл src/main.js
и все, что он подключает.
Тест сейчас выглядит так:
import HelloWorld from '@/components/HelloWorld.vue'
describe('<HelloWorld />', () => {
it('renders component', () => {
// see: https://on.cypress.io/mounting-vue
cy.mount(HelloWorld)
cy.contains('h2', 'Get started')
})
})
Чтобы плагин vuetify
загружался и был корректно настроен нам необходимо изменить команду mount
:
import './commands'
import _ from 'lodash'
import { mount } from 'cypress/vue';
import { createVuetify } from 'vuetify';
import 'vuetify/styles'; // Подключение стилей Vuetify
Cypress.Commands.add('mount', (component, options = {}) => {
const vuetify = createVuetify({
theme: {
defaultTheme: 'dark',
},
});
const defaultOptions = {
global: {
plugins: [vuetify],
},
};
const mergedOptions = _.merge({}, defaultOptions, options);
return mount(component, mergedOptions);
});
Здесь мы видим, что через createVuetify
настраивается vuetify
, передаются нужные опции. Также подключаются стили vuetify/styles
. И в итоге передаваемые извне опции mount
объединяются с defaultOptions
, в котором содержатся нужные нам глобальные настройки.
Если мы захотим также сделать доступным хранилище Pinia, к примеру, то можно будет и его добавить в global:
import { createPinia } from 'pinia'
// ....
const pinia = createPinia()
const defaultOptions = {
global: {
plugins: [vuetify, pinia],
},
};
// ....
Если в вашем приложении используются какие-то еще опции Vuetify, то и их тоже надо будет добавить в createVuetify
:
import {ru} from 'vuetify/locale'
// ....
const vuetify = createVuetify({
// ....
locale: {
locale: 'ru',
messages: { ru }
},
})
// ....
Хотя в тестах часто вместо этого используются различного рода заглушки (mocks).
Запускаем тесты успешно
Теперь наш тест будет успешно выполняться. Можем добавить еще один тест. Проверим как передается свойство в компонент:
import HelloWorld from '@/components/HelloWorld.vue'
describe('<HelloWorld />', () => {
it('renders component', () => {
// see: https://on.cypress.io/mounting-vue
cy.mount(HelloWorld)
cy.contains('h2', 'Get started')
})
it('displays property\'s value', () => {
const testValue = 'Test property text'
cy.mount(HelloWorld, {
props: {
word: testValue,
}
})
cy.contains('[data-test=property-value]', testValue)
})
})
Результат запуска выгляди так:
Еще немного глобальных настроек
По-умолчанию Cypress создал файл теста компонента рядом с ним, в его директории. Но, возможно, привычнее будет держать все тесты в одном месте. Для этого в файле cypress.config.js
нужно будет указать specPattern
и перенести наш тест в cypress/components
.
Также обратите внимание на другие опции:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
specPattern: "cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}",
baseUrl: "http://localhost:3000",
},
component: {
devServer: {
framework: "vue",
bundler: "vite",
},
specPattern: 'cypress/components/**/*.cy.{js,jsx,ts,tsx}', // Путь к компонентным тестам
},
viewportWidth: 1000,
viewportHeight: 900,
});
Итоги
В результате мы имеем возможность тестировать отдельные компоненты в Cypress. Мы сможем делать больше тестов и делать их быстрее. Вместе с e2e
тестами, которые рассматривались в одной из прошлых статей, приложение получит лучшее покрытие тестами.
Вы можете скачать репозиторий примера из статьи и ознакомиться с кодом поближе.
В следующих статьях я продолжу знакомство с Cypress. Будет разобран параллельный запуск тестов и Cypress Dashboard.