Как протестировать UI-компонент Toggle (переключатель)?

«Как протестировать UI-компонент Toggle (переключатель)?» — вопрос из категории Техники тест-дизайна, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Тестирование Toggle-компонента требует проверки функциональности, UI/UX, доступности и интеграции.

1. Функциональное тестирование

  • Базовое переключение: Изменение состояния с false на true и обратно по клику.
  • Управление с клавиатуры: Активация через Tab и переключение с помощью Space или Enter.
  • Связь с состоянием: Корректное обновление связанного значения в состоянии приложения (например, через React useState).
  • Контролируемый/неконтролируемый режим: Работа как с внешним пропсом checked, так и с внутренним состоянием.

2. Тестирование рендера и UI

  • Соответствие дизайну: Визуальная правильность в обоих состояниях (цвет, позиция ползунка, подписи).
  • Анимация: Плавность перехода (если есть) и её отсутствие при первоначальном рендере.
  • Состояния: Отображение disabled-состояния (opacity, курсор not-allowed).

3. Тестирование доступности (A11y)

  • Семантическая разметка: Использование правильного ARIA-роля (role="switch").
  • Атрибуты: Наличие aria-checked, aria-label или aria-labelledby.
  • Фокус: Видимый индикатор фокуса для клавиатурной навигации.
  • Screen Readers: Корректное озвучивание состояния ("on", "off").

4. Интеграционное и E2E-тестирование

  • Взаимодействие с бэкендом: При переключении должен отправляться корректный API-запрос (например, PATCH /settings).
  • Сохранение состояния: После перезагрузки страницы позиция тоггла должна восстанавливаться.

Пример теста на React + Jest + Testing Library:

import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Toggle from './Toggle';

describe('Toggle Component', () => {
  test('toggles state on click and updates aria-checked', () => {
    render(<Toggle aria-label="Enable notifications" />);
    const toggle = screen.getByRole('switch', { name: /enable notifications/i });

    // Начальное состояние
    expect(toggle).toHaveAttribute('aria-checked', 'false');

    // Клик мышью
    userEvent.click(toggle);
    expect(toggle).toHaveAttribute('aria-checked', 'true');

    // Переключение с клавиатуры
    fireEvent.keyDown(toggle, { key: ' ', code: 'Space' });
    expect(toggle).toHaveAttribute('aria-checked', 'false');
  });

  test('is disabled when disabled prop is passed', () => {
    render(<Toggle disabled />);
    const toggle = screen.getByRole('switch');
    expect(toggle).toBeDisabled();
    expect(toggle).toHaveStyle('cursor: not-allowed');
  });
});