Que Es el Testing Keyword-Driven?
El testing keyword-driven (tambien llamado table-driven o action-word testing) separa el diseno de la implementacion definiendo tests como secuencias de keywords — palabras de accion legibles que mapean a codigo de automatizacion.
Una tabla de keywords se ve asi:
| Paso | Keyword | Argumento 1 | Argumento 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 |
Miembros no tecnicos del equipo pueden leer, escribir y mantener estas tablas sin entender el codigo subyacente.
Arquitectura
El testing keyword-driven tiene tres capas:
┌─────────────────────┐
│ Test Cases │ Tablas de keywords (que probar)
│ (Keywords + Datos) │
├─────────────────────┤
│ Libreria Keywords │ Mapeo de keywords a codigo
│ (Definiciones) │
├─────────────────────┤
│ Motor Automatizac. │ Selenium, Playwright, clientes API
│ (Implementacion) │
└─────────────────────┘
Capa 1: Test Cases (Tablas de Keywords)
Escritos en hojas de calculo, archivos CSV o herramientas especializadas:
Test Case: Login Valido
Open Browser ${BASE_URL}
Login admin@test.com secret123
Verify Page Dashboard
Logout
Close Browser
Capa 2: Libreria de Keywords
Definiciones que mapean keywords a codigo:
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();
}
};
Capa 3: Motor de Automatizacion
La automatizacion real del browser, llamadas API y aserciones manejadas por herramientas como Playwright o Selenium.
Robot Framework: El Estandar
Robot Framework es la herramienta keyword-driven mas popular. Usa sintaxis tabular con archivos .robot.
Test Basico en Robot Framework
*** Settings ***
Library Browser
*** Test Cases ***
Login Valido
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
Login Invalido Muestra Error
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 == Credenciales invalidas
Keywords Personalizados en Robot Framework
*** Keywords ***
Login Con Credenciales
[Arguments] ${email} ${password}
Fill Text #email ${email}
Fill Text #password ${password}
Click #login-btn
Verificar Dashboard Cargado
Get Title == Dashboard - MyApp
Get Text .welcome contains Bienvenido
*** Test Cases ***
Admin Puede Acceder al Dashboard
New Browser chromium headless=false
New Page https://app.example.com/login
Login Con Credenciales admin@test.com secret123
Verificar Dashboard Cargado
Construyendo un Motor de Keywords Personalizado
Si Robot Framework no encaja en tu stack, puedes construir un motor ligero:
class KeywordEngine {
constructor() {
this.keywords = new Map();
this.variables = 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 desconocido: ${keyword}`);
await impl(...args);
}
async runTestCase(steps) {
for (const step of steps) {
const [keyword, ...args] = step;
console.log(` Ejecutando: ${keyword} ${args.join(' ')}`);
await this.execute(keyword, ...args);
}
}
}
Patrones Avanzados de Keywords
Keywords Compuestos
Construye keywords complejos desde mas simples:
engine.register('checkout completo', async (product, card) => {
await engine.execute('agregar al carrito', product);
await engine.execute('ir al checkout');
await engine.execute('ingresar pago', card);
await engine.execute('confirmar orden');
});
Keywords Data-Driven
Combina keyword-driven con enfoques data-driven:
Test Template: Test de Login
[Arguments] ${email} ${password} ${expected}
Open Browser ${BASE_URL}
Login ${email} ${password}
Verify Result ${expected}
Test Data:
| admin@test.com | AdminPass1 | success |
| wrong@test.com | wrong | error |
| "" | "" | error |
Cuando Usar Testing Keyword-Driven
| Escenario | Keyword-Driven? |
|---|---|
| Miembros no tecnicos escriben tests | Si |
| Industria altamente regulada | Si |
| Equipo pequeno, todos programadores | Probablemente no |
| Logica compleja que requiere flexibilidad | No |
| Integracion con framework existente | Enfoque hibrido |
Ventajas
- Accesible para no-programadores
- Los tests sirven como documentacion
- Separacion del diseno de la implementacion
- Facil crear nuevos test cases desde keywords existentes
Desventajas
- La capa adicional agrega complejidad
- Debugging puede ser mas dificil
- Flexibilidad limitada comparada con tests basados en codigo
- Mantener la libreria requiere soporte de desarrolladores
Ejercicio: Disena un Suite Keyword-Driven
Crea una libreria de keywords y test cases para un e-commerce:
- Define 10 keywords: OpenBrowser, Login, SearchProduct, AddToCart, ViewCart, UpdateQuantity, RemoveItem, Checkout, VerifyOrderTotal, CloseBrowser
- Escribe 3 test cases usando estos keywords
- Crea 2 keywords compuestos combinando multiples keywords basicos
- Agrega un test data-driven que pruebe 5 busquedas de productos diferentes
- Implementa las definiciones de keywords usando Playwright
Puntos Clave
- Testing keyword-driven usa keywords legibles para abstraer complejidad
- Tres capas: test cases (keywords), libreria (definiciones), motor (automatizacion)
- Robot Framework es el estandar de la industria
- Mejor para equipos con disenadores de tests no tecnicos
- Keywords compuestos construyen tests complejos desde bloques simples
- Se puede combinar con testing data-driven para maxima flexibilidad