Параметризованные тесты позволяют запускать один и тот же тестовый сценарий с различными наборами данных, что повышает покрытие тестами и уменьшает дублирование кода. В WebdriverIO этот подход реализуется через комбинацию JavaScript, Mocha/Jasmine и встроенных возможностей тест-раннера.
Параметризация заключается в создании структуры данных (массивов или объектов), содержащих наборы тестовых данных, и использовании этих данных внутри цикла или функции, генерирующей тесты. Такой подход особенно эффективен при проверке форм, калькуляторов, фильтров, авторизации, и любых сценариев, где один и тот же процесс должен проверяться с разными значениями.
const testData = [
{ username: 'user1', password: 'pass1', expected: true },
{ username: 'user2', password: 'wrong', expected: false },
{ username: '', password: 'nopass', expected: false }
];
describe('Проверка авторизации', () => {
testData.forEach(({ username, password, expected }) => {
it(`Авторизация с логином: ${username} и паролем: ${password}`, async () => {
await browser.url('https://example.com/login');
const inputUsername = await $('#username');
const inputPassword = await $('#password');
const loginButton = await $('#login');
await inputUsername.setValue(username);
await inputPassword.setValue(password);
await loginButton.click();
const loginSuccess = await $('#welcome').isDisplayed();
expect(loginSuccess).toBe(expected);
});
});
});
В этом примере один тестовый сценарий повторяется для каждого набора
данных. Использование forEach или map
позволяет создавать отдельные it блоки динамически,
сохраняя читаемость отчётов тест-раннера.
it.each в JasmineJasmine и Jest поддерживают более декларативный способ параметризации
через функции вроде it.each:
const credentials = [
['user1', 'pass1', true],
['user2', 'wrong', false],
['', 'nopass', false]
];
describe('Авторизация с разными данными', () => {
credentials.forEach(([username, password, expected]) => {
it(`логин: ${username}, пароль: ${password}`, async () => {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#login').click();
const result = await $('#welcome').isDisplayed();
expect(result).toBe(expected);
});
});
});
Такой подход обеспечивает компактное определение тестов без
необходимости создавать множество одинаковых it блоков
вручную.
Для сложных тестов с большим количеством данных удобно хранить тестовые данные отдельно:
[
{ "username": "user1", "password": "pass1", "expected": true },
{ "username": "user2", "password": "wrong", "expected": false }
]
И использовать их в тестах:
import testData from './testData.json';
describe('Авторизация из JSON', () => {
testData.forEach(({ username, password, expected }) => {
it(`логин: ${username}, пароль: ${password}`, async () => {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#login').click();
const result = await $('#welcome').isDisplayed();
expect(result).toBe(expected);
});
});
});
Такой подход облегчает поддержку тестов и позволяет легко добавлять новые кейсы без изменения кода теста.
describe.eachДля ещё более структурированного подхода можно создавать группы параметризированных тестов:
const groups = [
{
feature: 'Авторизация',
tests: [
{ username: 'user1', password: 'pass1', expected: true },
{ username: 'user2', password: 'wrong', expected: false }
]
},
{
feature: 'Регистрация',
tests: [
{ username: 'newuser', password: 'newpass', expected: true },
{ username: '', password: '', expected: false }
]
}
];
groups.forEach(({ feature, tests }) => {
describe(feature, () => {
tests.forEach(({ username, password, expected }) => {
it(`логин: ${username}, пароль: ${password}`, async () => {
await browser.url(`/${feature.toLowerCase()}`);
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#submit').click();
const result = await $('#status').isDisplayed();
expect(result).toBe(expected);
});
});
});
});
Такой подход позволяет поддерживать модульность и читаемость тестов даже при большом объёме данных.
При использовании TypeScript можно добавить строгую типизацию:
interface AuthTestData {
username: string;
password: string;
expected: boolean;
}
const testData: AuthTestData[] = [
{ username: 'user1', password: 'pass1', expected: true },
{ username: 'user2', password: 'wrong', expected: false }
];
describe('Авторизация (TypeScript)', () => {
testData.forEach(({ username, password, expected }) => {
it(`логин: ${username}, пароль: ${password}`, async () => {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#login').click();
const result = await $('#welcome').isDisplayed();
expect(result).toBe(expected);
});
});
});
Типизация повышает надёжность тестов и снижает риск ошибок при расширении тестовых данных.
it:
лучше создавать отдельные it для каждого набора данных,
чтобы каждый тест запускался независимо.it блоки сохраняет корректное отображение статуса
каждого кейса в Allure, HTML- или JSON-отчетах.Параметризованные тесты в WebdriverIO позволяют эффективно масштабировать автоматизацию, повышают повторное использование сценариев и улучшают структуру тестового кода, особенно при большом количестве похожих проверок.