The Makers BTG Tests framework follows a clear package structure based on org.btg.practual as the root package. This organization ensures maintainability and scalability as your test suite grows.
org.btg.practual/├── runners/ # Test runners and configuration├── stepDefinitions/ # Cucumber step implementations└── (future: pages/) # Page objects for UI automation
All test code should reside under the org.btg.practual package to ensure proper Serenity reporting and test discovery.
Contains test runner classes that configure Cucumber and Serenity execution.Example:CucumberRunner.java
package org.btg.practual.runners;@Suite@IncludeEngines("cucumber")@SelectClasspathResource("features")@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "org.btg.practual.stepDefinitions")public class CucumberRunner {}
Keep all runner configuration centralized in this package.
stepDefinitions
Contains all Cucumber step definition classes that implement the Gherkin steps.Example:GeneracionReporteSteps.java
package org.btg.practual.stepDefinitions;import io.cucumber.java.es.*;public class GeneracionReporteSteps { @Dado("el usuario ingresa a la web de Chronos") public void el_usuario_ingresa_a_la_web_de_chronos() { // Implementation }}
Each step definition class should focus on a specific feature or domain.
pages (Future)
Reserved for Page Object Model (POM) implementations when UI automation expands.This package will contain classes representing web pages and their interactions.
Each .feature file should contain exactly one feature with related scenarios.
#language:esCaracterística: Generación de reportes desde la web de Chronos @test Esquema del escenario: [Happy Path] Generacion exitosa de reporte Dado el usuario ingresa a la web de Chronos Cuando ingrese los datos del reporte "<report>" para la compañia "<company>" segun la fecha "<report_date>" Entonces se genera el reporte "<report>" de manera exitosa
Feature file names should match the feature they describe: GeneracionReporte.feature describes “Generación de reportes” feature.
Within a feature file, group related scenarios using tags and clear naming:
Happy path scenarios: [Happy Path] prefix and @test tag
Error scenarios: [Error] or [Negative] prefix and @error tag
Edge cases: [Edge Case] prefix and appropriate tags
@test @smokeEsquema del escenario: [Happy Path] Generacion exitosa de reporte@test @regressionEsquema del escenario: [Error] Fallo al generar reporte con datos invalidos@test @edge-caseEscenario: [Edge Case] Generacion de reporte en fecha festiva
For large features, you can split step definitions into logical groups:
// For authentication-related stepspublic class LoginSteps { }// For navigation stepspublic class NavigationSteps { }// For common steps used across featurespublic class CommonSteps { }
Avoid creating a single “god class” with all step definitions. Split them logically by feature or domain.
Within a step definition class, organize methods in the order they appear in scenarios:
@Dado (Given) - Preconditions
@Cuando (When) - Actions
@Entonces (Then) - Assertions
public class GeneracionReporteSteps { // Given steps - Setup and preconditions @Dado("el usuario ingresa a la web de Chronos") public void el_usuario_ingresa_a_la_web_de_chronos() { // Setup code } // When steps - Actions and interactions @Cuando("ingrese los datos del reporte {string} para la compañia {string} segun la fecha {string}") public void ingrese_los_datos_del_reporte(String reporte, String compania, String fecha) { // Action code } // Then steps - Assertions and validations @Entonces("se genera el reporte {string} de manera exitosa") public void se_genera_el_reporte_de_manera_exitosa(String reporte) { // Assertion code }}
@Suite@IncludeEngines("cucumber")@SelectClasspathResource("features")@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "org.btg.practual.stepDefinitions")@ConfigurationParameter(key = FILTER_TAGS_PROPERTY_NAME, value = "@test")@ConfigurationParameter( key = PLUGIN_PROPERTY_NAME, value = "io.cucumber.core.plugin.SerenityReporterParallel,pretty,html:target/cucumber-report.html")public class CucumberRunner {}
For different test suites (smoke, regression), create separate runner classes: SmokeTestRunner.java, RegressionTestRunner.java