DRY принцип в тестах

DRY (Don’t Repeat Yourself) — фундаментальный принцип разработки, направленный на минимизацию повторения кода. В контексте тестирования Vue-компонентов применение DRY позволяет создавать поддерживаемые, читаемые и масштабируемые тесты, сокращая дублирование логики и конфигураций.

Настройка общего окружения для тестов

Vue Test Utils предоставляет инструменты для монтирования компонентов (mount, shallowMount) и взаимодействия с ними. Повторяющиеся конфигурации компонентов можно вынести в отдельные функции:

import { mount } from '@vue/test-utils';
import MyComponent from '@/components/MyComponent.vue';

function createWrapper(props = {}, options = {}) {
  return mount(MyComponent, {
    props,
    ...options
  });
}

Такой подход позволяет:

  • Централизовать конфигурацию компонента.
  • Избегать дублирования при изменении базовых параметров.
  • Сократить объем тестового кода при добавлении новых сценариев.

Использование фабрик и утилит

Для сложных компонентов с множеством зависимостей целесообразно создавать фабрики данных и утилиты:

export function mockUser(overrides = {}) {
  return {
    id: 1,
    name: 'John Doe',
    role: 'admin',
    ...overrides
  };
}

export function mountWithUser(props = {}) {
  return mount(MyComponent, {
    props: {
      user: mockUser(),
      ...props
    }
  });
}

Такой подход облегчает:

  • Создание тестовых данных с минимальным дублированием.
  • Локализацию изменений, если структура данных компонента изменится.
  • Повышение читаемости тестов, поскольку конкретные данные вынесены в отдельные функции.

Общие хуки и методы

Повторяющиеся действия, такие как клик по кнопке, ввод текста, проверка вывода, удобно оформлять как функции:

export function clickButton(wrapper, selector) {
  const button = wrapper.find(selector);
  button.trigger('click');
}

export function setInputValue(wrapper, selector, value) {
  const input = wrapper.find(selector);
  input.setValue(value);
}

Использование таких функций позволяет:

  • Сократить дублирование действий в тестах.
  • Упростить изменение селекторов или логики взаимодействия.
  • Повысить читаемость тестовых сценариев.

Параметризация тестов

Для проверки одного сценария с различными наборами данных эффективна параметризация через test.each или циклы:

const roles = ['admin', 'editor', 'guest'];

roles.forEach(role => {
  test(`отображение кнопки для роли ${role}`, () => {
    const wrapper = mountWithUser({ role });
    expect(wrapper.find('button').exists()).toBe(role === 'admin');
  });
});

Преимущества:

  • Уменьшение числа повторяющихся тестов.
  • Сохранение единого тестового сценария для разных условий.
  • Повышение покрытия при меньшем объеме кода.

Общие конфигурации Vue Test Utils

Vue Test Utils позволяет задавать глобальные конфигурации для всех тестов через global:

import { config } from '@vue/test-utils';

config.global.stubs = ['router-link', 'font-awesome-icon'];
config.global.mocks = {
  $t: (msg) => msg
};

Это позволяет:

  • Избавиться от повторного объявления заглушек и моков в каждом тесте.
  • Упростить поддержку тестового окружения при изменении зависимостей.
  • Сократить boilerplate код.

Примеры реального применения DRY

  1. Тестирование формы с разными сценариями ошибок:
const errorScenarios = [
  { field: 'email', message: 'Invalid email' },
  { field: 'password', message: 'Too short' }
];

errorScenarios.forEach(({ field, message }) => {
  test(`отображает ошибку для поля ${field}`, async () => {
    const wrapper = createWrapper();
    await setInputValue(wrapper, `input[name="${field}"]`, '');
    clickButton(wrapper, 'button.submit');
    expect(wrapper.text()).toContain(message);
  });
});
  1. Мок глобальных зависимостей для всех тестов:
beforeEach(() => {
  jest.clearAllMocks();
});

const wrapper = createWrapper({}, {
  global: {
    mocks: {
      $store: { dispatch: jest.fn() }
    }
  }
});

В таких подходах минимизация повторения достигается через:

  • Общие фабрики компонентов.
  • Параметризацию сценариев.
  • Вынесение повторяющихся действий в утилиты.
  • Централизованные конфигурации глобальных зависимостей.

Принципы применения DRY в тестах Vue

  • Выделять общие шаблоны: фабрики компонентов, данные, функции взаимодействия.
  • Использовать параметризацию для схожих сценариев.
  • Централизовать конфигурации и заглушки.
  • Сокращать boilerplate, не теряя читаемости.
  • Поддерживать баланс: избегать чрезмерной абстракции, которая усложняет понимание тестов.

Такой подход обеспечивает гибкость, поддержку больших проектов и снижает затраты на изменение тестов при развитии приложения.