JavaRush /Курсы /Модуль 3: React /Типизация тестов в Cypress и работа с интерфейсами

Типизация тестов в Cypress и работа с интерфейсами

Модуль 3: React
18 уровень , 3 лекция
Открыта

Настройка TypeScript в Cypress

Если у вас уже есть проект на TypeScript, вы на шаг впереди! Если нет — вот подробная инструкция:

  1. Установим TypeScript и необходимые зависимости для Cypress:

    npm install typescript @types/node @types/cypress --save-dev
    
  2. Создадим конфигурационный файл tsconfig.json в корне проекта:

    {
        "compilerOptions": {
            "target": "es6",
            "module": "commonjs",
            "strict": true,
            "esModuleInterop": true,
            "types": ["cypress"]
        },
        "include": ["cypress/**/*.ts"]
    }
    
  3. Переименуем тестовые файлы с .js на .ts. Например, переименуем example.cy.js в example.cy.ts.

Поздравляю, вы только что стали ближе к типизированным тестам!

Обзор типизации в Cypress

После настройки TypeScript начнется магия автозаполнения. Например, если вы начнете писать:

cy.get('.button').

TypeScript предложит автодополнение методов, таких как .click() или .should().

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

Типизация интерфейсов

Интерфейсы в TypeScript — это способ описания структуры объектов. Они помогают явно показывать, какие свойства и типы ожидаются у объекта. В тестах это особенно полезно для работы с mock-данными и проверкой форматов данных.

Рассмотрим пример. Допустим, мы тестируем форму, где нужно отправить данные пользователя. Вот простая структура данных:

interface User {
    id: number;
    name: string;
    email: string;
    isAdmin: boolean;
}

С помощью интерфейсов мы можем задавать строгую типизацию данных:

const user: User = {
    id: 1,
    name: "Иван Иванов",
    email: "ivan@example.com",
    isAdmin: false,
};

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

Использование интерфейсов в тестах

Добавим проверку формы на наличие данных:

cy.get('input[name="name"]').type(user.name);
cy.get('input[name="email"]').type(user.email);
cy.get('button[type="submit"]').click();

cy.get('.user-info')
  .should('contain.text', `User: ${user.name}`);

 

Если что-то изменится в структуре User, мы сразу получим ошибку в местах, где используется этот интерфейс. Это спасает нас от того, чтобы вручную пробегать весь код при изменении структуры данных.

Работа с интерфейсами в тестах

Давайте рассмотрим пример использования интерфейсов для API-ответов. Допустим, у нас есть API-запрос, который возвращает список задач:

interface Task {
    id: number;
    title: string;
    completed: boolean;
}

// Фикстура API-ответа
const mockTasks: Task[] = [
    { id: 1, title: "Купить молоко", completed: false },
    { id: 2, title: "Прочитать книгу", completed: true },
];

Добавляем тест на проверку полученных данных:

cy.intercept('GET', '/api/tasks', mockTasks).as('getTasks');

cy.visit('/tasks');
cy.wait('@getTasks');

cy.get('.task')
  .should('have.length', mockTasks.length)
  .each(($el, index) =< {
    expect($el).to.contain(mockTasks[index].title);
  });

Интерфейс Task помогает нам задать структуру данных, которую возвращает сервер. Если структура ответа API изменится, мы сразу узнаем об этом благодаря TypeScript.

Интерфейсы для параметров маршрутов

Представим, что у нас есть динамический маршрут /user/:id, где параметр id — это число. Создадим интерфейс для параметров:

interface RouteParams {
    id: number;
}

Теперь используем этот интерфейс для проверки маршрутов:

const params: RouteParams = { id: 123 };

cy.visit(`/user/${params.id}`);
cy.get('.user-profile').should('contain', `User ID: ${params.id}`);

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

Примеры практических сценариев использования типизированных тестов

1. Проверка таблицы с данными

Интерфейс для строки таблицы:

interface TableRow {
    id: number;
    name: string;
    age: number;
}

Проверка:

const mockRows: TableRow[] = [
    { id: 1, name: "Алексей", age: 30 },
    { id: 2, name: "Мария", age: 25 },
];

cy.intercept('GET', '/api/users', mockRows).as('getUsers');

cy.visit('/users');
cy.wait('@getUsers');

cy.get('table tr').should('have.length', mockRows.length + 1); // +1 для заголовка таблицы
cy.get('table tr').each(($row, index) =< {
    if (index === 0) return; // Пропускаем заголовок
    const rowIndex = index - 1;
    cy.wrap($row).should('contain', mockRows[rowIndex].name);
    cy.wrap($row).should('contain', mockRows[rowIndex].age.toString());
});

2. Проверка валидации форм

Интерфейс для сообщений об ошибках:

interface ValidationError {
    field: string;
    message: string;
}

const mockErrors: ValidationError[] = [
    { field: "email", message: "Email обязательно" },
];

Тест:

cy.get('button[type="submit"]').click();

mockErrors.forEach((error) =< {
    cy.get(`.error-${error.field}`).should('contain.text', error.message);
});
2
Задача
Модуль 3: React, 18 уровень, 3 лекция
Недоступна
Типизация параметров маршрута с интерфейсами
Типизация параметров маршрута с интерфейсами
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ