</>

Technology

Cucumber

Difficulty

Advanced

Interview Question

You are asked to design a Cucumber BDD framework from scratch for a new e-commerce project. How would you approach it?

Answer

Designing a Cucumber BDD Framework from Scratch

Phase 1: Requirements Gathering (Day 1)

Before writing code, answer these:

  • Team size and Cucumber experience?
  • Application type (web/mobile/API/hybrid)?
  • Environments (dev/staging/prod)?
  • CI/CD tool (Jenkins/GitHub Actions)?
  • Reporting requirements (HTML/Slack/Jira)?
  • Parallel execution required?

Phase 2: Technology Stack Decision

CODE
Core BDD:       Cucumber 7.x (cucumber-java + cucumber-testng)
Browser:        Selenium WebDriver 4.x
Driver Setup:   WebDriverManager 5.x
Runner:         TestNG 7.x (parallel DataProvider support)
DI:             PicoContainer (constructor injection, zero config)
Build:          Maven 3.x
Reporting:      Masterthought cucumber-reporting + Allure
CI/CD:          Jenkins (Declarative Pipeline)
Version Ctrl:   Git + GitHub/GitLab
API Testing:    REST Assured 5.x (hybrid scenarios)
Assertions:     TestNG Assert + SoftAssert
Test Data:      Faker + config.properties per env

Phase 3: Project Structure

CODE
cucumber-bdd-framework/
  ├── pom.xml
  ├── testng.xml                          ← suite configuration
  ├── testng-parallel.xml                 ← parallel cross-browser
  ├── src/
  │   └── test/
  │       ├── java/
  │       │   ├── context/
  │       │   │   └── ScenarioContext.java  ← PicoContainer World
  │       │   ├── factory/
  │       │   │   └── DriverFactory.java    ← browser creation
  │       │   ├── hooks/
  │       │   │   └── Hooks.java            ← @Before/@After
  │       │   ├── pages/
  │       │   │   ├── BasePage.java         ← wait utilities
  │       │   │   ├── LoginPage.java
  │       │   │   ├── ProductPage.java
  │       │   │   └── CheckoutPage.java
  │       │   ├── stepDefinitions/
  │       │   │   ├── LoginSteps.java
  │       │   │   ├── ProductSteps.java
  │       │   │   └── CommonSteps.java
  │       │   ├── runners/
  │       │   │   ├── SmokeTestRunner.java
  │       │   │   ├── RegressionTestRunner.java
  │       │   │   └── RerunTestRunner.java
  │       │   └── utils/
  │       │       ├── ConfigReader.java
  │       │       ├── TestDataGenerator.java
  │       │       └── ApiUtils.java
  │       └── resources/
  │           ├── features/
  │           │   ├── login/login.feature
  │           │   ├── product/search.feature
  │           │   └── checkout/payment.feature
  │           └── config/
  │               ├── config.dev.properties
  │               ├── config.staging.properties
  │               └── config.prod.properties

Phase 4: Core Framework Classes

ScenarioContext.java (PicoContainer World):

Java
public class ScenarioContext {
    public WebDriver driver;
    public SoftAssert softAssert = new SoftAssert();
    private Map<String, Object> data = new HashMap<>();
    public void set(String key, Object val) { data.put(key, val); }
    public <T> T get(String key) { return (T) data.get(key); }
}

Hooks.java:

Java
public class Hooks {
    private final ScenarioContext ctx;
    public Hooks(ScenarioContext ctx) { this.ctx = ctx; }

    @Before(order = 100)
    public void setUp() {
        ctx.driver = DriverFactory.createDriver(
            ConfigReader.getBrowser(), ConfigReader.isHeadless());
        ctx.driver.manage().window().maximize();
        ctx.driver.manage().timeouts()
            .implicitlyWait(Duration.ofSeconds(0));  // use explicit waits only
    }

    @After(order = 100)
    public void softAssertAll() { ctx.softAssert.assertAll(); }

    @After(order = 0)
    public void tearDown(Scenario scenario) {
        if (scenario.isFailed()) {
            scenario.attach(
                ((TakesScreenshot) ctx.driver).getScreenshotAs(OutputType.BYTES),
                "image/png", "Failure");
        }
        ctx.driver.quit();
    }
}

Phase 5: Tagging & Execution Strategy

CODE
@smoke      → 15 tests  → every commit (<5 min)
@sanity     → 50 tests  → every PR merge (<20 min)
@regression → all tests → nightly (2AM)
@P1/@P2/@P3 → priority-based
@api/@ui/@db → test type
@wip        → excluded from CI

Phase 6: CI/CD Jenkins Pipeline

GROOVY
pipeline {
    agent any
    parameters {
        choice(name: 'ENV',    choices: ['staging', 'dev'], description: '')
        choice(name: 'TAGS',   choices: ['@smoke', '@regression'], description: '')
        choice(name: 'BROWSER', choices: ['chrome', 'firefox'], description: '')
    }
    stages {
        stage('Test')   { steps { sh "mvn clean test -Denv=${params.ENV} -Dcucumber.filter.tags='${params.TAGS}' -Dbrowser=${params.BROWSER}" } }
        stage('Rerun')  { steps { sh "mvn test -Prerun" } }
        stage('Report') { steps { sh "mvn verify -DskipTests" } }
    }
    post {
        always  { cucumber fileIncludePattern: '**/cucumber.json', reportTitle: 'BDD Report' }
        failure { slackSend channel: '#qa-alerts', color: 'danger', message: "❌ ${params.TAGS} failed on ${params.ENV}" }
    }
}

Phase 7: Onboarding QA Team

  1. Git clone + mvn clean verify -DskipTests → verify build
  2. Run @smoke suite → verify 15 tests pass
  3. Write one new feature file + step definition → first contribution
  4. Pair review of feature files in 3 Amigos sessions

Delivery timeline: Framework ready in 3 days, first regression suite in 2 weeks.

Follow AutomateQA

Related Topics