Пишем компоненты для легкого тестирования
Vue Test Utils помогает писать тесты для Vue компонентов. Однако, VTU может сделать не так уж много.
Ниже приведен список рекомендаций для написания кода, который проще тестировать и написать тесты, которые понятны по смыслу и просто поддерживать в будущем.
Список ниже предоставляет общие рекомендации, и он может пригодиться в распространенных сценариях.
Не тестируйте детали реализации
Думайте о входных и выходных данных с точки зрения пользователя. Грубо говоря, это все что тебе нужно принимать во внимание, чтобы написать тест для Vue компонента:
Входные данные | Примеры |
---|---|
Взаимодействия | Нажатие мыши, печать текста... любые "человеческие" взаимодействия |
Свойства компонента | Аргументы, которые получает компонент |
Потоки данных | Данные, приходящие от API вызовов, подписки на данные… |
Выходные данные | Примеры |
---|---|
DOM элементы | Любые наблюдаемые узлы, отрисованные в document |
События | Генерация событий (используя $emit ) |
Побочные эффекты | Такие как console.log или API вызовы |
Все остальное - это детали реализации.
Обратите внимание, что этот список не включает элементы такие, как внутренние методы, промежуточные состояния и даже данные.
Правило говорит о том, что тест не должен ломаться при рефакторинге, то есть, когда мы меняем его внутреннюю реализацию без изменения его поведения. Если это произойдет, тест может зависеть на детали реализации.
Например, давайте предположим простой Counter компонент, который содержит кнопку для увеличения счетчика:
<template>
<p class="paragraph">Times clicked: {{ count }}</p>
<button @click="increment">increment</button>
</template>
<script>
export default {
data() {
return { count: 0 }
},
methods: {
increment() {
this.count++
}
}
}
</script>
Мы могли бы написать следующий тест:
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
test('counter text updates', async () => {
const wrapper = mount(Counter)
const paragraph = wrapper.find('.paragraph')
expect(paragraph.text()).toBe('Times clicked: 0')
await wrapper.setData({ count: 2 })
expect(paragraph.text()).toBe('Times clicked: 2')
})
Обратите внимание как здесь мы обновляем его внутреннее состояние, мы также полагаемся на детали (с точки зрения пользователя) такие, как CSS классы.
TIP
Обратите внимание, что изменение либо состояния или CSS классов могло бы сломать тест. Хотя, компонент мог бы и сработать, как ожидалось. Это называется ложно положительным результатом.
Вместо этого, следующий тест пытается придерживаться концепции входных и выходных данных, описанных выше:
import { mount } from '@vue/test-utils'
test('text updates on clicking', async () => {
const wrapper = mount(Counter)
expect(wrapper.text()).toContain('Times clicked: 0')
const button = wrapper.find('button')
await button.trigger('click')
await button.trigger('click')
expect(wrapper.text()).toContain('Times clicked: 2')
})
Библиотека такая как Vue Testing Library построена на этих принципах. Если ты заинтересован в таком подходе, можете ознакомиться с ним.
Создавайте более маленькие и простые компоненты
Общее правило в том, что если компонент делает меньше, тогда его можно проще протестировать.
Создание более маленьких компонентов сделает их более компонуемыми и более простыми для понимания. Нижеперечисленный список предложений поможет сделать компоненты проще.
Извлечение API вызовов
Обычно, ты выполняешь несколько HTTP запросов в вашем приложении. С точки зрения тестирования, HTTP запросы предоставляют входные данные в компоненты, и компоненты могут также отправлять HTTP запросы.
TIP
Ознакомьтесь с Создание HTTP запросов руководством, если ты не знаком с тестированием API вызовов.
Извлечение сложных методов
Иногда компонент может содержать несколько сложных методов, выполняющих сложные вычисления или использующих несколько зависимостей.
Здесь предлагается извлекать метод и импортировать его в компонент. Таким образом, ты можешь протестировать метод изолированно, используя Jest или любую другую программу тестирования.
Он имеет дополнительные преимущества с компонентом, который легче для понимания, потому что сложная логика вынесена в другой файл.
А также, если сложный метод непросто настроить или он медленно работает, ты возможно хотел бы имитировать его, чтобы сделать тест более простых и быстрым. Создание HTTP запросов - хороший пример с вполне сложной библиотекой axios!
Пишите тесты перед созданием компонента
Ты не сможешь написать нетестируемый код, если ты напишешь тесты заранее!
Наш Ускоренный курс предлагает пример, как написание тестов до написания кода, приводит к созданию тестируемых компонентов. Он также поможет тебе обнаружить и протестировать крайние случаи.