Что такое Keyword-Driven тестирование?
Keyword-driven тестирование (также table-driven или action-word testing) отделяет дизайн тестов от реализации, определяя тесты как последовательности keywords — человекочитаемых слов-действий, соответствующих коду автоматизации.
Таблица keywords выглядит так:
| Шаг | Keyword | Аргумент 1 | Аргумент 2 |
|---|---|---|---|
| 1 | Open Browser | https://app.example.com | Chrome |
| 2 | Enter Text | admin@test.com | |
| 3 | Enter Text | #password | secret123 |
| 4 | Click Button | #login-btn | |
| 5 | Verify Text | .welcome | Welcome, Admin |
| 6 | Close Browser |
Нетехнические члены команды могут читать, писать и поддерживать эти таблицы без понимания кода автоматизации.
Архитектура
Keyword-driven тестирование имеет три уровня:
┌─────────────────────┐
│ Тест-кейсы │ Таблицы keywords (что тестировать)
│ (Keywords + Данные)│
├─────────────────────┤
│ Библиотека Keywords│ Отображение keywords на код
│ (Определения) │
├─────────────────────┤
│ Движок автоматиз. │ Selenium, Playwright, API-клиенты
│ (Реализация) │
└─────────────────────┘
Уровень 1: Тест-кейсы (Таблицы keywords)
Пишутся в таблицах, CSV-файлах или специализированных инструментах:
Test Case: Валидный логин
Open Browser ${BASE_URL}
Login admin@test.com secret123
Verify Page Dashboard
Logout
Close Browser
Уровень 2: Библиотека keywords
Определения, отображающие keywords на код:
const keywords = {
'Open Browser': async (url) => {
browser = await chromium.launch();
page = await browser.newPage();
await page.goto(url);
},
'Login': async (email, password) => {
await page.fill('#email', email);
await page.fill('#password', password);
await page.click('#login-btn');
},
'Verify Page': async (pageName) => {
const titles = { Dashboard: 'Dashboard - MyApp', Profile: 'Profile - MyApp' };
await expect(page).toHaveTitle(titles[pageName]);
},
'Close Browser': async () => {
await browser.close();
}
};
Уровень 3: Движок автоматизации
Фактическая автоматизация браузера, API-вызовы и ассерты через Playwright или Selenium.
Robot Framework: Стандарт индустрии
Robot Framework — самый популярный инструмент keyword-driven тестирования с табличным синтаксисом в .robot файлах.
Базовый тест в Robot Framework
*** Settings ***
Library Browser
*** Test Cases ***
Валидный логин
New Browser chromium headless=false
New Page https://app.example.com/login
Fill Text #email admin@test.com
Fill Text #password secret123
Click #login-btn
Get Title == Dashboard - MyApp
Невалидный логин показывает ошибку
New Browser chromium headless=false
New Page https://app.example.com/login
Fill Text #email wrong@test.com
Fill Text #password wrongpass
Click #login-btn
Get Text .error == Неверные учётные данные
Пользовательские keywords в Robot Framework
*** Keywords ***
Логин с учётными данными
[Arguments] ${email} ${password}
Fill Text #email ${email}
Fill Text #password ${password}
Click #login-btn
Проверить загрузку дашборда
Get Title == Dashboard - MyApp
Get Text .welcome contains Добро пожаловать
*** Test Cases ***
Админ может открыть дашборд
New Browser chromium headless=false
New Page https://app.example.com/login
Логин с учётными данными admin@test.com secret123
Проверить загрузку дашборда
Создание собственного движка keywords
Если Robot Framework не подходит вашему стеку, можно создать лёгкий движок:
class KeywordEngine {
constructor() {
this.keywords = new Map();
}
register(name, implementation) {
this.keywords.set(name.toLowerCase(), implementation);
}
async execute(keyword, ...args) {
const impl = this.keywords.get(keyword.toLowerCase());
if (!impl) throw new Error(`Неизвестный keyword: ${keyword}`);
await impl(...args);
}
async runTestCase(steps) {
for (const step of steps) {
const [keyword, ...args] = step;
console.log(` Выполняю: ${keyword} ${args.join(' ')}`);
await this.execute(keyword, ...args);
}
}
}
Продвинутые паттерны keywords
Составные keywords
Строим сложные keywords из простых:
engine.register('полный checkout', async (product, card) => {
await engine.execute('добавить в корзину', product);
await engine.execute('перейти к оплате');
await engine.execute('ввести данные оплаты', card);
await engine.execute('подтвердить заказ');
});
Data-Driven keywords
Комбинация keyword-driven с data-driven подходом:
Шаблон теста: Тест логина
[Аргументы] ${email} ${password} ${expected}
Open Browser ${BASE_URL}
Login ${email} ${password}
Verify Result ${expected}
Данные:
| admin@test.com | AdminPass1 | success |
| wrong@test.com | wrong | error |
| "" | "" | error |
Когда использовать Keyword-Driven тестирование
| Сценарий | Keyword-Driven? |
|---|---|
| Нетехнические сотрудники пишут тесты | Да |
| Строго регулируемая отрасль | Да |
| Маленькая команда, все программисты | Скорее нет |
| Сложная логика, требующая гибкости | Нет |
| Интеграция с существующим фреймворком | Гибридный подход |
Преимущества
- Доступен для непрограммистов
- Тесты служат документацией
- Разделение дизайна тестов и реализации
- Легко создавать новые тест-кейсы из существующих keywords
Недостатки
- Дополнительный уровень абстракции добавляет сложность
- Отладка может быть сложнее
- Ограниченная гибкость по сравнению с кодовыми тестами
- Поддержка библиотеки требует помощи разработчиков
Упражнение: Спроектируйте Keyword-Driven suite
Создайте библиотеку keywords и тест-кейсы для e-commerce:
- Определите 10 keywords: OpenBrowser, Login, SearchProduct, AddToCart, ViewCart, UpdateQuantity, RemoveItem, Checkout, VerifyOrderTotal, CloseBrowser
- Напишите 3 тест-кейса с этими keywords
- Создайте 2 составных keyword из нескольких базовых
- Добавьте data-driven тест для 5 разных поисков товаров
- Реализуйте определения keywords на Playwright
Ключевые выводы
- Keyword-driven тестирование использует читаемые keywords для абстракции сложности
- Три уровня: тест-кейсы (keywords), библиотека (определения), движок (автоматизация)
- Robot Framework — стандарт индустрии
- Лучше всего подходит для команд с нетехническими дизайнерами тестов
- Составные keywords строят сложные тесты из простых блоков
- Можно комбинировать с data-driven тестированием для максимальной гибкости