# TestFly Part 5: BDD Testing with Cucumber 7, BaseCucumberSteps & @retryable Tags

URL: https://hakangul.lovable.app/blog/testfly-part-5-bdd-cucumber-7-integration-enterprise-testing
Author: Hakan Gül — Team Lead Senior Test Automation Engineer
Published: 2026-08-28
Updated: 2026-08-29
Category: test-automation
Tags: TestFly, Cucumber, BDD, BaseCucumberTest, BaseCucumberSteps, Retryable, Java, SDET

> Integrate Cucumber 7 with TestFly. Master BaseCucumberTest runners, BaseCucumberSteps helpers, CucumberStepLogger reporting, and per-scenario @retryable tags.

## English

## BDD with Cucumber 7 in TestFly

TestFly integrates with Cucumber 7 out of the box with zero boilerplate:
- **Automatic Driver Lifecycle:** Managed via `CucumberHooks` in `io.testfly.cucumber`.
- **Step Timeline Logging:** Streamed directly into the HTML report via `CucumberStepLogger`.
- **Automatic Screenshots:** Captured and embedded on failure in both reports.
- **Per-Scenario Retry:** Configured with `@retryable` or `@retryable=N` tags.

---

## 1. Runner Class (`BaseCucumberTest`)

```java
package com.yourcompany.bdd;

import io.cucumber.testng.CucumberOptions;
import io.testfly.cucumber.BaseCucumberTest;

@CucumberOptions(
    features = "src/test/resources/features",
    glue     = {"com.yourcompany.bdd.steps", "io.testfly.cucumber"},
    plugin   = {"pretty", "io.testfly.cucumber.CucumberStepLogger"}
)
public class CucumberRunner extends BaseCucumberTest {}
```

---

## 2. Step Definitions with `BaseCucumberSteps`

```java
package com.yourcompany.bdd.steps;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import io.testfly.cucumber.BaseCucumberSteps;
import org.openqa.selenium.By;

public class LoginSteps extends BaseCucumberSteps {

    @Given("the user is on the login page")
    public void onLoginPage() {
        open("/login");
    }

    @When("they login as {string} with password {string}")
    public void login(String username, String password) {
        find(By.id("username")).type(username);
        find(By.id("password")).type(password);
        find(By.id("submit")).click();
    }

    @Then("the dashboard is visible")
    public void dashboardVisible() {
        assertThat(By.id("dashboard")).isVisible(); // auto-retrying assertion
    }
}
```

---

## 3. Per-Scenario Retry Tag

```gherkin
@retryable=2
Scenario: Flaky payment gateway widget
  Given the user is on the payment screen
  When they submit payment details
  Then the transaction should be confirmed
```

## Türkçe

## TestFly ile Cucumber 7 BDD Entegrasyonu

TestFly, Cucumber 7 ile kutudan çıktığı gibi tam uyumlu çalışır:
- **Otomatik Sürücü Yönetimi:** `io.testfly.cucumber.CucumberHooks` tarafından yönetilir.
- **Adım Zaman Çizelgesi:** `CucumberStepLogger` ile doğrudan HTML raporuna akar.
- **Otomatik Ekran Görüntüleri:** Hata anında yakalanıp rapora iliştirilir.
- **Senaryo Bazlı Yeniden Deneme:** `@retryable` veya `@retryable=N` etiketleri.

---

## 1. Runner Sınıfı (`BaseCucumberTest`)

```java
package com.yourcompany.bdd;

import io.cucumber.testng.CucumberOptions;
import io.testfly.cucumber.BaseCucumberTest;

@CucumberOptions(
    features = "src/test/resources/features",
    glue     = {"com.yourcompany.bdd.steps", "io.testfly.cucumber"},
    plugin   = {"pretty", "io.testfly.cucumber.CucumberStepLogger"}
)
public class CucumberRunner extends BaseCucumberTest {}
```

---

## 2. `BaseCucumberSteps` ile Adım Tanımları

```java
package com.yourcompany.bdd.steps;

import io.cucumber.java.tr.Diyelimki;
import io.cucumber.java.tr.Eğer;
import io.cucumber.java.tr.O_zaman;
import io.testfly.cucumber.BaseCucumberSteps;
import org.openqa.selenium.By;

public class LoginAdimlari extends BaseCucumberSteps {

    @Diyelimki("kullanıcı giriş sayfasındadır")
    public void girisSayfasinda() {
        open("/login");
    }

    @Eğer("kullanıcı adı {string} ve şifre {string} ile giriş yaparsa")
    public void girisYap(String username, String password) {
        find(By.id("username")).type(username);
        find(By.id("password")).type(password);
        find(By.id("submit")).click();
    }

    @O_zaman("dashboard ekranı görünür olmalıdır")
    public void dashboardGorunur() {
        assertThat(By.id("dashboard")).isVisible(); // otomatik bekleyen doğrulama
    }
}
```

---

## 3. Senaryo Bazlı Retry Etiketi

```gherkin
@retryable=2
Senaryo: Dış ödeme servis entegrasyonu
  Diyelim ki kullanıcı ödeme ekranındadır
  Eğer geçerli kart bilgileri girilirse
  O zaman ödeme onay kodu ekranda görünmelidir
```
