# Cucumber e Gherkin: Automação BDD com Exemplos Práticos

**Meta Description:** Aprenda Cucumber e Gherkin: escrever cenários BDD, step definitions, hooks, tags e como implementar desenvolvimento guiado por comportamento.

---

## Cucumber Framework

Cucumber é uma ferramenta que permite escrever testes em linguagem natural (Gherkin) que são executados automaticamente.

### Instalação

```bash
# Ruby
gem install cucumber

# Java (Maven)
<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>7.14.0</version>
</dependency>

# Python
pip install behave

# JavaScript
npm install @cucumber/cucumber
```

---

## Gherkin - Linguagem

### Estrutura Básica

```gherkin
Funcionalidade: Login de Usuário
  Como um usuário registrado
  Quero fazer login no sistema
  Para acessar minha conta

  Cenário: Login com credenciais válidas
    Dado que estou na página de login
    Quando preencho o campo email com "usuario@exemplo.com"
    E preencho o campo senha com "senha123"
    E clico no botão "Entrar"
    Então sou redirecionado para o dashboard
    E vejo a mensagem "Bem-vindo, usuário"

  Cenário: Login com credenciais inválidas
    Dado que estou na página de login
    Quando preencho o campo email com "invalido@exemplo.com"
    E preencho o campo senha com "senhaerrada"
    E clico no botão "Entrar"
    Então vejo a mensagem de erro "Credenciais inválidas"
    E permaneço na página de login
```

### Keywords

| Keyword | Usage |
|---------|-------|
| Funcionalidade | Nome do recurso |
| Cenário | Caso de uso |
| Dado | Pré-condição |
| Quando | Ação |
| Então | Resultado esperado |
| E | Adiciona condição |
| Mas | Condição negativa |
| Esquema do Cenário | Cenário com parâmetros |
| Exemplos | Tabela de dados |

---

## Step Definitions

### Python (Behave)

```python
# features/steps/login_steps.py
from behave import given, when, then
from selenium.webdriver.common.by import By

@given('estou na página de login')
def step_impl(context):
    context.browser.get('https://exemplo.com/login')

@when('preencho o campo email com "{email}"')
def step_impl(context, email):
    element = context.browser.find_element(By.ID, 'email')
    element.send_keys(email)

@when('preencho o campo senha com "{senha}"')
def step_impl(context, senha):
    element = context.browser.find_element(By.ID, 'password')
    element.send_keys(senha)

@when('clico no botão "{texto}"')
def step_impl(context, texto):
    buttons = context.browser.find_elements(By.TAG_NAME, 'button')
    for button in buttons:
        if button.text == texto:
            button.click()
            break

@then('sou redirecionado para o dashboard')
def step_impl(context):
    assert 'dashboard' in context.browser.current_url

@then('vejo a mensagem "{texto}"')
def step_impl(context, texto):
    assert texto in context.browser.page_source
```

### Java (Cucumber)

```java
// src/test/java/steps/LoginSteps.java
package steps;

import io.cucumber.java.pt.*;
import org.openqa.selenium.By;
import static org.junit.Assert.*;

public class LoginSteps {
    
    WebDriver driver = Hooks.driver;
    
    @Dado("estou na página de login")
    public void estouNaPaginaDeLogin() {
        driver.get("https://exemplo.com/login");
    }
    
    @Quando("preencho o campo email com {string}")
    public void preenchoEmail(String email) {
        driver.findElement(By.id("email")).sendKeys(email);
    }
    
    @Quando("preencho o campo senha com {string}")
    public void preenchoSenha(String senha) {
        driver.findElement(By.id("password")).sendKeys(senha);
    }
    
    @Quando("clico no botão {string}")
    public void clicoNoBotao(String texto) {
        driver.findElement(By.xpath("//button[text()='" + texto + "']")).click();
    }
    
    @Então("sou redirecionado para o dashboard")
    public void souRedirecionado() {
        assertTrue(driver.getCurrentUrl().contains("dashboard"));
    }
    
    @Então("vejo a mensagem {string}")
    public void vejoMensagem(String mensagem) {
        assertTrue(driver.getPageSource().contains(mensagem));
    }
}
```

---

## Data Tables

```gherkin
Funcionalidade: Carrinho de Compras
  
  Cenário: Adicionar múltiplos produtos ao carrinho
    Quando adiciono os seguintes produtos ao carrinho:
      | Produto    | Quantidade | Preço  |
      | Camiseta  | 2         | R$49,90|
      | Calça     | 1         | R$89,90|
      | Tênis     | 1         | R$199,90|
    Então o total do carrinho deve ser R$389,70
```

```python
# Step with table
@when('adiciono os seguintes produtos ao carrinho')
def step_impl(context):
    total = Decimal('0')
    for row in context.table:
        product = row['Produto']
        quantity = int(row['Quantidade'])
        price = Decimal(row['Preço'].replace('R$', '').replace(',', '.'))
        
        # Add to cart logic
        add_to_cart(product, quantity)
        
        total += price * quantity
    
    context.expected_total = total
```

---

## Hooks

```python
# features/environment.py
from behave import *
from selenium import webdriver

def before_all(context):
    """Executa antes de tudo"""
    context.browser = webdriver.Chrome()

def after_all(context):
    """Executa após tudo"""
    context.browser.quit()

def before_scenario(context, scenario):
    """Executa antes de cada cenário"""
    context.browser.delete_all_cookies()

def after_scenario(context, scenario):
    """Executa após cada cenário"""
    if scenario.status == 'failed':
        # Take screenshot
        context.browser.save_screenshot(f'failed_{scenario.name}.png')

def before_step(context, step):
    """Executa antes de cada step"""
    pass

def after_step(context, step):
    """Executa após cada step"""
    if step.status == 'failed':
        print(f"Step failed: {step.name}")
```

---

## Tags

```gherkin
@smoke @login
Funcionalidade: Login
  
  @critical
  Cenário: Login com sucesso
    ...

  Cenário: Login com falha
    ...

@regression
Funcionalidade: Carrinho
  ...
```

```bash
# Executar apenas com tag
behave --tags=@smoke
behave --tags="not @skip"
behave --tags="@smoke,@login"  # OR
behave --tags="@smoke+@critical"  # AND
```

---

## Conclusão

Cucumber/Gherkin facilita comunicação entre equipes. As chaves são:

1. **Linguagem de negócio** - Todos entendem
2. **Step definitions** - Conecta Gherkin a código
3. **Hooks** - Setup/teardown
4. **Tags** - Selecionar cenários
5. **Data tables** - Dados complexos
