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

Параметризация тестов — один из ключевых подходов к организации автоматизированного тестирования, позволяющий запускать один и тот же тест с различными входными данными. В WebdriverIO это особенно актуально при работе с большими наборами данных, где дублирование кода приводит к усложнению поддержки и снижению читаемости тестов.

Использование forEach и массивов данных

Один из самых простых способов параметризации — хранение наборов данных в массиве и использование цикла forEach для генерации тестов:

const users = [
    { username: 'user1', password: 'pass1' },
    { username: 'user2', password: 'pass2' },
    { username: 'user3', password: 'pass3' }
];

describe('Тестирование авторизации', () => {
    users.forEach(user => {
        it(`Авторизация для ${user.username}`, async () => {
            await browser.url('/login');
            await $('#username').setValue(user.username);
            await $('#password').setValue(user.password);
            await $('button[type="submit"]').click();
            await expect($('#welcome')).toBeDisplayed();
        });
    });
});

Ключевые моменты:

  • Массив объектов позволяет централизованно хранить тестовые данные.
  • forEach создает отдельный it для каждого набора данных, что делает отчеты по тестам более наглядными.
  • Такой подход прост в реализации, но при большом количестве наборов данных может быть менее эффективным.

Использование it.each или аналогов

Некоторые фреймворки для тестирования в связке с WebdriverIO, например Jest или Mocha с плагинами, поддерживают метод параметризации вроде it.each. В чистом Mocha можно реализовать аналог через цикл:

const testCases = [
    ['user1', 'pass1'],
    ['user2', 'pass2'],
    ['user3', 'pass3']
];

describe('Авторизация с разными пользователями', () => {
    testCases.forEach(([username, password]) => {
        it(`Авторизация для ${username}`, async () => {
            await browser.url('/login');
            await $('#username').setValue(username);
            await $('#password').setValue(password);
            await $('button[type="submit"]').click();
            await expect($('#welcome')).toBeDisplayed();
        });
    });
});

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

Параметризация с использованием JSON или внешних файлов

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

Пример структуры JSON:

[
    { "username": "user1", "password": "pass1" },
    { "username": "user2", "password": "pass2" },
    { "username": "user3", "password": "pass3" }
]

Загрузка данных в тест:

const users = require('./testData/users.json');

describe('Авторизация с JSON-данными', () => {
    users.forEach(user => {
        it(`Авторизация для ${user.username}`, async () => {
            await browser.url('/login');
            await $('#username').setValue(user.username);
            await $('#password').setValue(user.password);
            await $('button[type="submit"]').click();
            await expect($('#welcome')).toBeDisplayed();
        });
    });
});

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

  • Легко масштабировать.
  • Тесты остаются чистыми и читаемыми.
  • Поддержка внешних источников позволяет интегрировать данные из баз или CSV.

Параметризация через Data-driven Testing с использованием Mocha Hooks

Иногда требуется выполнить подготовительные действия перед каждым набором данных. Для этого можно использовать хуки beforeEach и динамически создавать контексты:

const users = [
    { username: 'user1', password: 'pass1' },
    { username: 'user2', password: 'pass2' }
];

describe('Авторизация с хуками', () => {
    users.forEach(user => {
        describe(`Тест для ${user.username}`, () => {
            beforeEach(async () => {
                await browser.url('/login');
            });

            it('Ввод данных и проверка успешного входа', async () => {
                await $('#username').setValue(user.username);
                await $('#password').setValue(user.password);
                await $('button[type="submit"]').click();
                await expect($('#welcome')).toBeDisplayed();
            });
        });
    });
});

Особенности такого подхода:

  • Позволяет выполнять общую подготовку для каждого набора данных.
  • Создает структурированные и изолированные блоки тестов.

Комбинирование параметризации с Page Object

Page Object значительно упрощает работу с тестовыми сценариями. При параметризации это особенно важно:

// login.page.js
class LoginPage {
    get username() { return $('#username'); }
    get password() { return $('#password'); }
    get submit() { return $('button[type="submit"]'); }
    
    async login(user, pass) {
        await this.username.setValue(user);
        await this.password.setValue(pass);
        await this.submit.click();
    }
}

module.exports = new LoginPage();
const users = require('./testData/users.json');
const LoginPage = require('./pages/login.page');

describe('Авторизация через Page Object', () => {
    users.forEach(user => {
        it(`Авторизация для ${user.username}`, async () => {
            await browser.url('/login');
            await LoginPage.login(user.username, user.password);
            await expect($('#welcome')).toBeDisplayed();
        });
    });
});

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

  • Повторное использование кода.
  • Минимизация изменений в тестах при изменении интерфейса.
  • Чистый и понятный синтаксис при параметризации.

Выводы по параметризации в WebdriverIO

Параметризация в WebdriverIO обеспечивает гибкость тестирования, снижает дублирование кода и облегчает поддержку больших наборов данных. Эффективно использовать комбинацию массивов, внешних файлов и Page Object для структурирования тестов, сохраняя при этом читаемость и масштабируемость. Использование циклов forEach, JSON-файлов и хуков Mocha позволяет строить надежные, легко расширяемые тестовые сценарии с разными комбинациями данных.