Динамическая генерация тестов позволяет создавать тестовые сценарии на основе данных, получаемых во время выполнения, или заранее подготовленных наборов данных. В WebdriverIO это особенно полезно при тестировании веб-приложений с большим количеством вариаций форм, пользовательских ролей или сложных пользовательских потоков.
Ключевые принципы динамического тестирования:
В WebdriverIO поддерживается интеграция с тестовыми фреймворками,
такими как Mocha или Jasmine, что позволяет использовать массивы данных
для генерации тестов через циклы или методы forEach.
Пример создания динамических тестов на основе массива данных:
const testCases = [
{ username: 'user1', password: 'pass1', expected: true },
{ username: 'user2', password: 'wrong', expected: false },
{ username: 'admin', password: 'admin', expected: true },
];
describe('Авторизация пользователей', () => {
testCases.forEach(({ username, password, expected }) => {
it(`проверка логина для пользователя ${username}`, async () => {
await browser.url('/login');
const usernameInput = await $('#username');
const passwordInput = await $('#password');
const loginButton = await $('#loginBtn');
await usernameInput.setValue(username);
await passwordInput.setValue(password);
await loginButton.click();
const loginSuccess = await $('#welcome').isDisplayed();
expect(loginSuccess).toBe(expected);
});
});
});
В этом примере тесты создаются автоматически для каждого набора данных. Такой подход сокращает дублирование кода и упрощает поддержку тестов.
Часто данные для тестов хранятся во внешних файлах или базах данных. WebdriverIO позволяет загружать эти данные и динамически создавать тестовые сценарии.
Пример загрузки данных из JSON:
const fs = require('fs');
const testData = JSON.parse(fs.readFileSync('./testData.json', 'utf-8'));
describe('Динамические тесты из JSON', () => {
testData.forEach(({ input, expected }) => {
it(`проверка ввода: ${input}`, async () => {
await browser.url('/form');
const inputField = await $('#inputField');
const submitButton = await $('#submitBtn');
await inputField.setValue(input);
await submitButton.click();
const result = await $('#result').getText();
expect(result).toBe(expected);
});
});
});
Подход с JSON позволяет легко расширять тесты без изменения кода — достаточно добавить новые объекты с тестовыми данными.
Для сложных сценариев рекомендуется выделять повторяющиеся действия в функции-хелперы. Это упрощает динамическую генерацию тестов и делает код более читабельным.
Пример функции-хелпера:
async function login(username, password) {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#loginBtn').click();
}
describe('Авторизация с помощью хелперов', () => {
const users = [
{ username: 'user1', password: 'pass1' },
{ username: 'admin', password: 'admin' }
];
users.forEach(({ username, password }) => {
it(`логин для ${username}`, async () => {
await login(username, password);
const welcomeMessage = await $('#welcome').isDisplayed();
expect(welcomeMessage).toBe(true);
});
});
});
Функции-хелперы позволяют легко комбинировать шаги, создавая новые сценарии без дублирования кода.
it.each и параметризированных тестовДля Mocha и Jasmine можно применять пакеты вроде
mocha-each, которые упрощают синтаксис генерации тестов с
множеством данных:
const forEach = require('mocha-each');
forEach([
['user1', 'pass1', true],
['user2', 'wrong', false],
]).it('проверка логина %s', async (username, password, expected) => {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#loginBtn').click();
const loginSuccess = await $('#welcome').isDisplayed();
expect(loginSuccess).toBe(expected);
});
Такой подход уменьшает количество кода и делает тестовые сценарии более наглядными.
Иногда данные для тестов поступают из API или других асинхронных
источников. WebdriverIO позволяет использовать async/await
для загрузки данных перед генерацией тестов.
Пример:
let users;
before(async () => {
const response = await fetch('https://api.example.com/users');
users = await response.json();
});
describe('Тесты с данными из API', () => {
users.forEach(({ username, password }) => {
it(`логин для ${username}`, async () => {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#loginBtn').click();
const success = await $('#welcome').isDisplayed();
expect(success).toBe(true);
});
});
});
Асинхронная генерация тестов позволяет тестировать реальные данные и интеграции, повышая надежность тестового покрытия.
Для крупных проектов динамическая генерация тестов часто строится с использованием шаблонов и генераторов функций. Это особенно полезно при тестировании многошаговых процессов, где комбинации действий могут быть сотнями.
Пример генератора тестов:
function generateLoginTests(users) {
return users.map(({ username, password, expected }) => {
return async function() {
await browser.url('/login');
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#loginBtn').click();
const result = await $('#welcome').isDisplayed();
expect(result).toBe(expected);
};
});
}
const testCases = generateLoginTests([
{ username: 'user1', password: 'pass1', expected: true },
{ username: 'user2', password: 'wrong', expected: false },
]);
describe('Динамически сгенерированные тесты', () => {
testCases.forEach((testFunc, index) => {
it(`тест ${index + 1}`, testFunc);
});
});
Такой подход упрощает масштабирование тестовой инфраструктуры и автоматизацию генерации сценариев для больших приложений.
Динамическая генерация тестов в WebdriverIO позволяет:
При правильной организации данных и использовании функций-хелперов динамическая генерация становится мощным инструментом для тестирования сложных веб-приложений.