Introducción a Katalon Studio

Katalon Studio es una plataforma integral todo-en-uno para automatización de pruebas que combina la simplicidad de las pruebas sin código con el poder de la automatización scriptada. Construido sobre Selenium y Appium, Katalon proporciona una solución unificada para pruebas de aplicaciones web, API, móvil y escritorio sin requerir conocimientos extensos de programación.

A diferencia de los frameworks de pruebas tradicionales que requieren una configuración y setup significativos, Katalon Studio ofrece un entorno de desarrollo integrado (IDE) con características incorporadas para creación de pruebas, ejecución, reportes e integración — todo en un solo paquete.

¿Por Qué Elegir Katalon Studio?

Ventajas Clave:

  • Cero Setup Requerido: Listo para usar inmediatamente después de la instalación
  • Soporte Multiplataforma: Web, API, Móvil (iOS/Android), Escritorio (Windows)
  • Modo Dual: Grabar y reproducir para principiantes, scripting (Groovy) para usuarios avanzados
  • Repositorio de Objetos Integrado: Gestión inteligente y mantenimiento de objetos
  • Integraciones Nativas: Jira, Git, Jenkins, Azure DevOps, TestRail
  • Auto-reparación de Pruebas: Curación de localizadores de elementos potenciada por IA
  • Reportes Completos: Analytics integrados, screenshots, videos, logs

Comenzando con Katalon Studio

Instalación y Configuración

  1. Descargar Katalon Studio desde https://katalon.com/
  2. No se necesitan drivers o dependencias adicionales
  3. Activar tu cuenta (tier gratuito disponible)
  4. Comenzar a crear pruebas inmediatamente

Entendiendo la Interfaz

Componentes Principales:

ComponentePropósitoDescripción
Test ExplorerNavegación del proyectoOrganizar pruebas, suites, archivos de datos
Test Case EditorCreación de pruebasVistas Manual, Script y Keyword
Object RepositoryAlmacenamiento de elementosGestión centralizada de elementos web/móvil
Test Suite CollectionOrquestación de pruebasAgrupar y configurar ejecución de pruebas
ReportsAnálisis de resultadosReportes HTML integrados con screenshots
Script EditorScripting personalizadoKeywords y lógica personalizada basada en Groovy

Estructura del Proyecto

ProyectoKatalon/
├── Test Cases/
│   ├── Web/
│   │   ├── Login/
│   │   │   └── TC_Login_Valido.groovy
│   │   └── Checkout/
│   │       └── TC_Checkout_Exitoso.groovy
│   ├── API/
│   │   └── Pruebas_API_Usuario.groovy
│   └── Mobile/
│       └── Navegacion_App.groovy
├── Object Repository/
│   ├── Web/
│   │   ├── PaginaLogin/
│   │   └── PaginaDashboard/
│   └── Mobile/
│       └── PantallaInicio/
├── Test Suites/
│   ├── Suite_Pruebas_Smoke.ts
│   └── Suite_Regresion.ts
├── Test Listeners/
├── Keywords/
│   └── KeywordsPersonalizados.groovy
├── Data Files/
│   ├── datos_usuario.xlsx
│   └── config_prueba.csv
├── Checkpoints/
├── Reports/
└── Profiles/
    ├── default.glbl
    ├── staging.glbl
    └── produccion.glbl

Pruebas Web con Katalon

Grabar y Reproducir

El Grabador Web de Katalon es perfecto para creación rápida de pruebas:

Pasos:

  1. Hacer clic en el botón Record Web
  2. Ingresar URL de la aplicación
  3. Interactuar con la aplicación (Katalon graba todas las acciones)
  4. Detener la grabación
  5. Revisar y editar los pasos de prueba generados
  6. Ejecutar la prueba

Ejemplo de Prueba Grabada:

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

// Abrir navegador
WebUI.openBrowser('')

// Navegar a URL
WebUI.navigateToUrl('https://demo.ejemplo.com')

// Maximizar ventana
WebUI.maximizeWindow()

// Ingresar usuario
WebUI.setText(findTestObject('Object Repository/PaginaLogin/input_usuario'), 'usuarioprueba')

// Ingresar contraseña
WebUI.setEncryptedText(findTestObject('Object Repository/PaginaLogin/input_password'), 'contrasena_encriptada')

// Hacer clic en botón login
WebUI.click(findTestObject('Object Repository/PaginaLogin/btn_login'))

// Verificar que el dashboard se muestra
WebUI.verifyElementPresent(findTestObject('Object Repository/Dashboard/lbl_bienvenida'), 10)

// Cerrar navegador
WebUI.closeBrowser()

Modo de Scripting Manual

Para más control, usa el modo Manual con keywords integrados:

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.model.FailureHandling as FailureHandling

WebUI.comment('Caso de Prueba: Verificar Búsqueda y Filtrado de Productos')

// Configuración
WebUI.openBrowser('')
WebUI.navigateToUrl('https://tienda.ejemplo.com')
WebUI.maximizeWindow()
WebUI.waitForPageLoad(10)

// Buscar producto
WebUI.setText(findTestObject('Tienda/input_busqueda'), 'laptop')
WebUI.click(findTestObject('Tienda/btn_buscar'))

// Aplicar filtros
WebUI.waitForElementPresent(findTestObject('Tienda/filtro_precio'), 10)
WebUI.click(findTestObject('Tienda/filtro_precio_500_1000'))
WebUI.click(findTestObject('Tienda/filtro_marca_dell'))

// Verificar resultados
int cantidadProductos = WebUI.getNumberOfTotalOption(findTestObject('Tienda/tarjetas_producto'))
WebUI.verifyGreaterThan(cantidadProductos, 0)

// Verificar detalles de producto
WebUI.verifyElementText(findTestObject('Tienda/titulo_primer_producto'), 'Dell Laptop')
String precio = WebUI.getText(findTestObject('Tienda/precio_primer_producto'))
assert precio.contains('$') : 'El precio debe contener el signo de dólar'

// Screenshot
WebUI.takeScreenshot('screenshots/resultados_busqueda_productos.png')

// Limpieza
WebUI.closeBrowser()

Gestión del Repositorio de Objetos

El Object Repository de Katalon centraliza la gestión de elementos:

Propiedades del Objeto:

// Objeto: PaginaLogin/input_usuario
// Métodos de Selector (ordenados por prioridad):
1. Atributos: id = 'username'
2. XPath: //input[@id='username']
3. CSS: input#username

// Objeto: PaginaLogin/btn_submit
// Auto-reparación habilitada: Sí
// Métodos de Selector:
1. Atributos: id = 'submit-btn'
2. XPath: //button[@type='submit']
3. CSS: button[type='submit']
4. Texto: 'Ingresar'

Usando Object Spy:

  1. Lanzar herramienta Object Spy
  2. Capturar elementos web visualmente
  3. Revisar localizadores sugeridos
  4. Agregar al Object Repository
  5. Usar en casos de prueba via findTestObject()

Capacidades de Pruebas API

Pruebas de API RESTful

Katalon sobresale en pruebas de API sin plugins adicionales:

import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import groovy.json.JsonSlurper

// Caso de Prueba: Crear y Verificar Usuario
WebUI.comment('Prueba API: Crear Usuario y Verificar Respuesta')

// Crear usuario via POST
RequestObject createUserRequest = findTestObject('API/Usuarios/POST_CrearUsuario')

// Establecer cuerpo de la petición
def requestBody = [
    username: 'nuevousuario',
    email: 'nuevousuario@ejemplo.com',
    firstName: 'Juan',
    lastName: 'Perez',
    role: 'tester'
]

createUserRequest.setBodyContent(new groovy.json.JsonBuilder(requestBody).toString())

// Enviar petición
ResponseObject createResponse = WS.sendRequest(createUserRequest)

// Verificar estado de respuesta
WS.verifyResponseStatusCode(createResponse, 201)

// Parsear respuesta
def jsonSlurper = new JsonSlurper()
def responseData = jsonSlurper.parseText(createResponse.getResponseBodyContent())

// Verificar datos de respuesta
assert responseData.username == 'nuevousuario'
assert responseData.email == 'nuevousuario@ejemplo.com'
assert responseData.id != null

String userId = responseData.id

// GET detalles del usuario
RequestObject getUserRequest = findTestObject('API/Usuarios/GET_UsuarioPorId')
getUserRequest.setRestUrl("https://api.ejemplo.com/users/${userId}")

ResponseObject getResponse = WS.sendRequest(getUserRequest)

// Verificar respuesta GET
WS.verifyResponseStatusCode(getResponse, 200)
def userData = jsonSlurper.parseText(getResponse.getResponseBodyContent())
assert userData.username == 'nuevousuario'

// Verificar tiempo de respuesta
long responseTime = getResponse.getResponseTime()
assert responseTime < 2000 : "El tiempo de respuesta debe ser menor a 2 segundos"

// Verificar headers
WS.verifyElementPropertyValue(getResponse, 'Content-Type', 'application/json')

println("Usuario creado exitosamente con ID: ${userId}")

Configuración de Objeto de Prueba API

Objeto Web Service Request:

// Object Repository/API/Usuarios/POST_CrearUsuario

[Request]
Tipo: RESTful
Método: POST
URL: https://api.ejemplo.com/users
Headers:
  - Authorization: Bearer ${GlobalVariable.API_TOKEN}
  - Content-Type: application/json
Body:
{
  "username": "${username}",
  "email": "${email}",
  "role": "tester"
}

[Verificación]
Código de Estado: 201
Tiempo de Respuesta: < 3000ms

Suites de Prueba API con Data-Driven Testing

import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import internal.GlobalVariable as GlobalVariable

// Pruebas API basadas en datos
def testData = findTestData('Data Files/API_Usuarios')

for (int i = 1; i <= testData.getRowNumbers(); i++) {
    String username = testData.getValue('username', i)
    String email = testData.getValue('email', i)
    String expectedStatus = testData.getValue('expected_status', i)

    // Crear petición
    def request = findTestObject('API/Usuarios/POST_CrearUsuario')
    def body = [username: username, email: email]
    request.setBodyContent(new groovy.json.JsonBuilder(body).toString())

    // Enviar y verificar
    def response = WS.sendRequest(request)
    WS.verifyResponseStatusCode(response, expectedStatus.toInteger())

    println("Prueba ${i}: ${username} - Estado ${expectedStatus} - PASÓ")
}

Pruebas Móviles (iOS & Android)

Configuración de Prueba Móvil

import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.configuration.RunConfiguration

// Configurar desired capabilities
RunConfiguration.setWebDriverPreferencesProperty("appium:platformName", "Android")
RunConfiguration.setWebDriverPreferencesProperty("appium:deviceName", "Pixel 5")
RunConfiguration.setWebDriverPreferencesProperty("appium:app", "/ruta/a/app.apk")

// Iniciar aplicación
Mobile.startApplication('ruta/a/app.apk', false)

// Esperar elemento
Mobile.waitForElementPresent(findTestObject('Mobile/PantallaInicio/btn_login'), 10)

// Tocar elemento
Mobile.tap(findTestObject('Mobile/PantallaInicio/btn_login'), 5)

// Ingresar texto
Mobile.setText(findTestObject('Mobile/PantallaLogin/input_usuario'), 'usuarioprueba', 0)
Mobile.setText(findTestObject('Mobile/PantallaLogin/input_password'), 'password', 0)

// Ocultar teclado
Mobile.hideKeyboard()

// Tocar login
Mobile.tap(findTestObject('Mobile/PantallaLogin/btn_submit'), 5)

// Verificar navegación
Mobile.verifyElementExist(findTestObject('Mobile/Dashboard/lbl_bienvenida'), 10)

// Acciones de deslizamiento
Mobile.swipe(100, 500, 100, 200) // Deslizar hacia arriba

// Cerrar app
Mobile.closeApplication()

Pruebas Móviles Multiplataforma

// Keyword personalizado para pruebas multiplataforma
class AyudanteMovil {

    @Keyword
    def lanzarApp(String plataforma) {
        if (plataforma == 'iOS') {
            RunConfiguration.setWebDriverPreferencesProperty("appium:platformName", "iOS")
            RunConfiguration.setWebDriverPreferencesProperty("appium:deviceName", "iPhone 14")
            RunConfiguration.setWebDriverPreferencesProperty("appium:app", "/ruta/a/app.ipa")
        } else {
            RunConfiguration.setWebDriverPreferencesProperty("appium:platformName", "Android")
            RunConfiguration.setWebDriverPreferencesProperty("appium:deviceName", "Pixel 5")
            RunConfiguration.setWebDriverPreferencesProperty("appium:app", "/ruta/a/app.apk")
        }

        Mobile.startApplication(GlobalVariable.MOBILE_APP, false)
    }

    @Keyword
    def loginUsuario(String username, String password, String plataforma) {
        def campoUsuario = plataforma == 'iOS' ?
            'Mobile/iOS/input_usuario' : 'Mobile/Android/input_usuario'
        def campoPassword = plataforma == 'iOS' ?
            'Mobile/iOS/input_password' : 'Mobile/Android/input_password'

        Mobile.setText(findTestObject(campoUsuario), username, 5)
        Mobile.setText(findTestObject(campoPassword), password, 5)
        Mobile.tap(findTestObject("Mobile/${plataforma}/btn_login"), 5)
    }
}

Características Avanzadas y Patrones

Keywords Personalizados

Extiende las capacidades de Katalon con keywords Groovy personalizados:

// Keywords/KeywordsWebPersonalizados.groovy
package com.ejemplo.keywords

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import org.openqa.selenium.WebElement

class KeywordsWebPersonalizados {

    @Keyword
    def esperarYHacerClick(TestObject testObject, int timeout = 10) {
        WebUI.waitForElementClickable(testObject, timeout)
        WebUI.click(testObject)
    }

    @Keyword
    def desplazarAElemento(TestObject testObject) {
        WebElement element = WebUI.findWebElement(testObject, 10)
        WebUI.executeJavaScript(
            "arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});",
            Arrays.asList(element)
        )
        WebUI.delay(1)
    }

    @Keyword
    def verificarTextoElementoContiene(TestObject testObject, String textoEsperado) {
        String textoActual = WebUI.getText(testObject)
        assert textoActual.contains(textoEsperado) :
            "Texto esperado '${textoEsperado}' no encontrado en '${textoActual}'"
    }

    @Keyword
    String generarEmailAleatorio(String dominio = 'ejemplo.com') {
        String cadenaAleatoria = UUID.randomUUID().toString().substring(0, 8)
        return "test_${cadenaAleatoria}@${dominio}"
    }

    @Keyword
    def loginComoUsuario(String username, String password) {
        WebUI.setText(findTestObject('PaginaLogin/input_usuario'), username)
        WebUI.setEncryptedText(findTestObject('PaginaLogin/input_password'), password)
        WebUI.click(findTestObject('PaginaLogin/btn_login'))
        WebUI.waitForElementPresent(findTestObject('Dashboard/lbl_bienvenida'), 10)
    }
}

Uso:

import com.ejemplo.keywords.KeywordsWebPersonalizados

KeywordsWebPersonalizados custom = new KeywordsWebPersonalizados()

// Usar keywords personalizados
custom.desplazarAElemento(findTestObject('Pagina/btn_submit'))
custom.esperarYHacerClick(findTestObject('Pagina/btn_submit'))

String email = custom.generarEmailAleatorio('dominioprueba.com')
custom.verificarTextoElementoContiene(findTestObject('Pagina/lbl_mensaje'), 'Éxito')

custom.loginComoUsuario('admin', 'contrasena_encriptada')

Variables Globales y Perfiles

Gestiona configuraciones específicas del entorno:

// Profiles/default.glbl
GlobalVariable.BASE_URL = 'https://staging.ejemplo.com'
GlobalVariable.API_TOKEN = 'token_api_staging_aqui'
GlobalVariable.TIMEOUT = 10

// Profiles/produccion.glbl
GlobalVariable.BASE_URL = 'https://ejemplo.com'
GlobalVariable.API_TOKEN = 'token_api_produccion_aqui'
GlobalVariable.TIMEOUT = 15

// Uso en pruebas
WebUI.navigateToUrl(GlobalVariable.BASE_URL + '/login')

Test Listeners para Lógica Personalizada

// Test Listeners/TestListener.groovy
import com.kms.katalon.core.annotation.AfterTestCase
import com.kms.katalon.core.annotation.BeforeTestCase
import com.kms.katalon.core.context.TestCaseContext

class TestListener {

    @BeforeTestCase
    def beforeTestCase(TestCaseContext testCaseContext) {
        println("Iniciando prueba: ${testCaseContext.getTestCaseId()}")
        // Lógica de configuración personalizada
        // Inicializar datos de prueba
        // Configurar conexiones a base de datos
    }

    @AfterTestCase
    def afterTestCase(TestCaseContext testCaseContext) {
        println("Prueba completada: ${testCaseContext.getTestCaseId()}")

        if (testCaseContext.getTestCaseStatus() == "FAILED") {
            // Tomar screenshot en fallo
            WebUI.takeScreenshot("failures/${testCaseContext.getTestCaseId()}.png")

            // Registrar info adicional de debug
            println("Prueba falló en: " + new Date())

            // Enviar notificación
            // enviarNotificacionSlack(testCaseContext)
        }

        // Limpieza
        WebUI.closeBrowser()
    }
}

Integración CI/CD

Integración con Jenkins

// Jenkinsfile
pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/tuorg/pruebas-katalon.git'
            }
        }

        stage('Ejecutar Pruebas') {
            steps {
                script {
                    def katalonStudio = '/Applications/Katalon Studio.app/Contents/MacOS/katalon'

                    sh """
                        "${katalonStudio}" \
                        -noSplash \
                        -runMode=console \
                        -projectPath="${WORKSPACE}/TuProyecto.prj" \
                        -retry=0 \
                        -testSuiteCollectionPath="Test Suites/Suite_Regresion" \
                        -executionProfile="produccion" \
                        -browserType="Chrome (headless)" \
                        -apiKey="${KATALON_API_KEY}" \
                        --config -webui.autoUpdateDrivers=true
                    """
                }
            }
        }

        stage('Publicar Reportes') {
            steps {
                publishHTML([
                    reportDir: 'Reports',
                    reportFiles: 'report.html',
                    reportName: 'Reporte de Pruebas Katalon'
                ])
            }
        }
    }

    post {
        always {
            junit 'Reports/**/*.xml'
        }
    }
}

Integración con Docker

# Dockerfile
FROM katalonstudio/katalon:latest

# Copiar proyecto
COPY . /katalon/project

# Ejecutar pruebas
CMD katalon -noSplash -runMode=console \
    -projectPath=/katalon/project/TuProyecto.prj \
    -testSuiteCollectionPath="Test Suites/Pruebas_Smoke" \
    -browserType="Chrome (headless)" \
    -apiKey=$KATALON_API_KEY

Mejores Prácticas y Optimización

1. Organizar Pruebas Jerárquicamente

Test Cases/
├── Smoke/
│   ├── Web/
│   └── API/
├── Regresion/
│   ├── Critico/
│   └── Medio/
└── Integracion/

2. Usar Patrón Page Object

Crear clases de página reutilizables:

// Keywords/pages/PaginaLogin.groovy
class PaginaLogin {
    static def campoUsuario = 'PaginaLogin/input_usuario'
    static def campoPassword = 'PaginaLogin/input_password'
    static def botonLogin = 'PaginaLogin/btn_login'

    @Keyword
    static def login(String username, String password) {
        WebUI.setText(findTestObject(campoUsuario), username)
        WebUI.setText(findTestObject(campoPassword), password)
        WebUI.click(findTestObject(botonLogin))
    }
}

3. Habilitar Auto-reparación

Configurar auto-reparación en Project Settings:

  • Habilitar ejecución con auto-reparación
  • Establecer estrategias de localizador de respaldo
  • Revisar elementos reparados regularmente

4. Optimizar Ejecución

// Ejecución paralela en Test Suite Collection
// Habilitar en configuración de Test Suite Collection:
- Instancias paralelas máximas: 4
- Ejecutar con: Chrome (headless)

Comparación con Otras Herramientas

CaracterísticaKatalon StudioSelenium + JavaCypressTestComplete
Complejidad de SetupNingunaAltaBajaBaja
Grabar y ReproducirNoNo
ScriptingGroovyJava/Python/C#JavaScriptMúltiple
Pruebas APIIntegradoLibrerías externas
Pruebas MóvilesIntegradoSetup AppiumNo
ReportesExcelenteBásicoBuenoExcelente
CostoTier gratis + PagoGratisGratis + PagoSolo pago
Curva de AprendizajeBaja-MediaAltaMediaBaja-Media

Conclusión

Katalon Studio se destaca como una solución verdaderamente todo-en-uno para automatización de pruebas que equilibra facilidad de uso con capacidades poderosas. Su plataforma unificada elimina la necesidad de múltiples herramientas e integraciones complejas, haciéndola ideal para equipos de todos los tamaños y niveles de habilidad.

Katalon Studio es Perfecto Para:

  • Equipos que necesitan configuración rápida de automatización de pruebas
  • Organizaciones que prueban web, API y móvil
  • Equipos con habilidades mixtas (testers manuales + ingenieros de automatización)
  • Proyectos que requieren reportes y analytics comprehensivos
  • Integración CI/CD con configuración mínima

Al aprovechar las características integradas de Katalon, gestión inteligente de objetos y capacidades de integración extensivas, los equipos pueden lograr un time-to-market más rápido mientras mantienen altos estándares de calidad.

Próximos Pasos

  1. Descargar Katalon Studio desde https://katalon.com
  2. Completar los tutoriales integrados
  3. Crear tu primera prueba usando Record Web
  4. Explorar gestión de Object Repository
  5. Configurar integración CI/CD con tu pipeline
  6. Unirse al Katalon Community Forum para soporte

Comienza con pruebas simples de grabar-y-reproducir, luego adopta gradualmente scripting y características avanzadas a medida que crece la madurez de automatización de tu equipo.