Neste artigo você vai…
- Instalar o CucumberJS
- Escrever seu primeiro cenário com a sintaxe do Gherkin
- Automatizar o cenário com Javascript e NodeJS
- Executar especificações vivas com Cucumber
- Entender o fluxo básico do BDD (Behavior-Driven Development)
Vamos usar o Cucumber e BDD para desenvolver uma pequena biblioteca que possa descobrir qual o prato do dia na capital paulista.
Antes de começarmos, você precisará do NodeJS instalado.
https://nodejs.org/en/
Abra um terminal para verificar se o NodeJS está instalado corretamente:
node -v
npm -v
Crie um projeto do ZERO
mkdir c:\qaninja
mkdir c:\qaninja\cucumberjs
mkdir c:\qaninja\cucumberjs\prato-do-dia
cd c:\qaninja\cucumberjs\prato-do-dia
npm init --yes
npm install cucumber --save-dev
Abra o arquivo package.json e deixe igualzinho o exemplo abaixo:
{
"name": "prato-do-dia",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "cucumber-js"
},
"keywords": ["nodejs", "cucumberjs", "bdd", "qaninja", "javascript"],
"author": "Fernando Papito",
"license": "ISC",
"devDependencies": {
"cucumber": "^5.1.0"
}
}
Preparando a estrutura do Cucumber
mkdir features
mkdir features/step_definitions
Na pasta “prato-do-dia”, crie um arquivo com o nome cucumber.js
Deixe conforme o exemplo abaixo:
module.exports = {
default: `--format-options '{"snippetInterface": "synchronous"}'`
}
Agora crie também o arquivo steps.js dentro da pasta “step_definitions” e cole o seguinte código:
const assert = require('assert');
const { Given, When, Then } = require('cucumber');
Verificando o CucumberJS está funcionando
Execute o comando:
npm test
O Cucumber vai avisar que não encontrou nenhuma especificação para ser executada. Igualmente ao resultado abaixo:
0 scenarios
0 steps
0m00.000s
Especificando cenários para uma estória de usuário
Quando fazemos o BDD (Desenvolvimento Guiado por Comportamento) com o Cucumber, usamos exemplos concretos para especificar o que queremos que o app faça.
Sobre o BDD
Os cenários devem ser criados antes do código do app. Eles começam sua vida como uma especificação executável . À medida que o app vai sendo codificado, os cenários assumem um papel como documentação viva e testes automatizados .
No Cucumber, um exemplo é chamado de cenário . Os cenários são definidos nos arquivos com extensão .feature
, e devem estar dentro da pasta features
Estão, vamos fazer o seguinte:
Dentro da pasta features, crie um arquivo com o nome prato_do_dia.feature
Abra o arquivo no seu editor preferido (VSCode é top) e deixe assim:
#language:pt
Funcionalidade: Prato do dia!
Queremos saber qual o prato do dia na capital paulista
Cenário: Hoje é dia de virado a paulista
Dado que hoje é "segunda-feira"
Quando eu pergunto qual é o prato do dia
Então a resposta deve ser "Virado a Paulista"
A primeira linha define o idioma da sintaxe do Gheckin.
Na linha 2, temos a palavra-chave Funcionalidade:
com o nome da mesma. Por questões de boas práticas, recomendo usar um nome semelhante ao nome do arquivo.
Na linha 4, uma breve descrição do recurso. o Cucumber não executa a descrição, é apenas documentação.
A linha 6 Cenário: Hoje é dia de virado a paulista
é um cenário de uso, que descreve o comportamento do usuário ao usar o app que será desenvolvido.
As últimas três linhas começando com Dado
, Quando
e Então
são os steps para reproduzir o comportamento do cenário. são do nosso cenário. É isso que o Cucumber irá executar para desenvolvermos o app.
Executando cenário indefinido
Agora que temos um cenário bem bonito, vamos pedir ao Cucumber para executá-lo. No terminal digite cucumber conforme abaixo:
npm test
O Cucumber finaliza a execução como undefined
. Quer dizer que deu ruim? absolutamente não :). Olha que top, o cucumber percebeu que não existem funções em Javascript que automatizam o comportamento e já está sugerindo as funções (esqueleto) em Javascript para avançamos com o processo de desenvolvimento do app Prato do Dia.
UUU
Warnings:
1) Scenario: Hoje é dia de virado a paulista # features/prato-do-dia.feature:6
? Dado que hoje é "segunda-feira"
Undefined. Implement with the following snippet:
Given('que hoje é {string}', function (string) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
? Quando eu pergunto qual é o prato do dia
Undefined. Implement with the following snippet:
When('eu pergunto qual é o prato do dia', function () {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
? Então a resposta deve ser "Virado a Paulista"
Undefined. Implement with the following snippet:
Then('a resposta deve ser {string}', function (string) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
1 scenario (1 undefined)
3 steps (3 undefined)
0m00.000s
No arquivo steps.js
em features/step_definitions/
, copie as funcções no arquivo steps.js
const assert = require('assert');
const { Given, When, Then } = require('cucumber');
Given('que hoje é {string}', function (string) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
When('eu pergunto qual é o prato do dia', function () {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
Then('a resposta deve ser {string}', function (string) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
Executando cenário como pendente
Agora que temos os steps em funções javascript, vamos pedir ao Cucumber para executá-lo novamente. No terminal digite cucumber e veja o resultado conforme o exemplo abaixo:
P--
Warnings:
1) Scenario: Hoje é dia de virado a paulista # features/prato-do-dia.feature:6
? Dado que hoje é "segunda-feira" # features/step_definitions/steps.js:4
Pending
- Quando eu pergunto qual é o prato do dia # features/step_definitions/steps.js:9
- Então a resposta deve ser "Virado a Paulista" # features/step_definitions/steps.js:14
1 scenario (1 pending)
3 steps (1 pending, 2 skipped)
0m00.000s
O Cucumber encontrou os códigos Javascript que dão vida a especificação, mas o resultado ficou como pendente , ou seja, ja temos a estrutura que testa e agora falta implementar. Olha o TDD na prática.
Executando cenário com falha
Quando fazemos o BDD
(Desenvolvimento Orientado por Comportamento) com o Cucumber, usamos exemplos concretos para especificar o que queremos que o software faça. Os cenários são gravados antes do código do app. Eles começam sua vida como uma especificação executável . À medida que o produto surge, os cenários assumem um papel como documentação viva e testes automatizados .
Altere os steps, conforme o exemplo abaixo:
const assert = require('assert');
const { Given, When, Then } = require('cucumber');
function pratoDoDia(dia) {
}
Given('que hoje é {string}', function (dia) {
this.hoje = dia;
});
When('eu pergunto qual é o prato do dia', function () {
this.valorObtido = pratoDoDia(this.hoje);
});
Then('a resposta deve ser {string}', function (valorEsperado) {
assert.equal(this.valorObtido, valorEsperado);
});
Perceba que eu fiz a implementação do comportamento, onde a função pratoDoDia representa a unidade de código que deve ser desenvolvida. Seguida pelos steps que ativam e acessam os recursos para que a mesma seja testada.
Então execute o Cucumber novamente.

As coisas estão ficando muito chiques! Os dois primeiros passos estão passando, mas o último está falhando.
Isso acontece porque o método “prado_do_dia” só recebe o valor “segunda-feira”, mas não possui uma regra para tratar essa informação e fazer com que o comportamento especificado devolva o valor esperado para o cenário. Revolva isso conforme o exemplo abaixo:
function pratoDoDia(dia) {
if (dia === 'segunda-feira') {
return 'Virado a Paulista'
}
}
Agora veja cenário passando
Execute o Cucumber novamente:
...
1 scenario (1 passed)
3 steps (3 passed)
0m00.002s
Adicionando mais um cenário
Vamos adicionar mais um cenário, onde o valor de entrada será “terça-feira” e valor esperado (saída) será “Dobradinha”.
#language:pt
Funcionalidade: Prato do dia!
Queremos saber qual o prato do dia na capital paulista
Cenário: Hoje é dia de virado a paulista
Dado que hoje é "segunda-feira"
Quando eu pergunto qual é o prato do dia
Então a resposta deve ser "Virado a Paulista"
Cenário: Hoje é dia de dobradinha
Dado que hoje é "terça-feira"
Quando eu pergunto qual é o prato do dia
Então a resposta deve ser "Dobradinha"
Execute o cucumber de novo:
O segundo falhou. Isso ocorre porque ainda não implementamos a regra de negócio para terça-feira!

Vamos trocar o if pelo case e deixar assim:
function pratoDoDia(dia) {
switch (dia) {
case 'segunda-feira':
return 'Virado a Paulista'
case "terça-feira":
return "Dobradinha"
}
}
Execute o cucumber mais uma vez:
......
2 scenarios (2 passed)
6 steps (6 passed)
0m00.002s
Usando cenários múltiplos
Sabemos que há mais dias na semana do que apenas segunda e terça-feira. E nestes dias também temos pratos típicos da capital paulista. Portanto vamos atualizar nosso cenário para usar variáveis e avaliar mais possibilidades.
Esta técnica é chamada de Scenario Outline. Em português, Delineação do Cenário ou Esquema do Cenário.
Digite o comando: ./node_modules/.bin/cucumber-js –i18n-keywords pt no terminal
Voce verá todas as palavras reservadas em português.
Atualize o prato_do_dia.feature
, conforme o exemplo abaixo:
#language:pt
Funcionalidade: Prato do dia!
Queremos saber qual o prato do dia na capital paulista
Esquema do Cenário: Descubra o prato do dia
Dado que hoje é "<dia>"
Quando eu pergunto qual é o prato do dia
Então a resposta deve ser "<resposta>"
Exemplos:
| dia | resposta |
| segunda-feira | Virado a Paulista |
| terça-feira | Dobradinha |
| quarta-feira | Feijoada |
| quinta-feira | Macarrão |
| sexta-feira | Filé de Peixe |
Execute o cucumber mais uma vez:


Implementando os demais cenários
Agora que temos todos os cenários, devemos fazer algumas refatorações:
function pratoDoDia(dia) {
switch (dia) {
case 'segunda-feira':
return 'Virado a Paulista'
case "terça-feira":
return "Dobradinha"
case "quarta-feira":
return "Feijoada"
case "quinta-feira":
return "Macarrão"
case "sexta-feira":
return "Filé de Peixe"
}
}

Executando o Cucumber mais uma vez:
...............
5 scenarios (5 passed)
15 steps (15 passed)
0m00.001s
Finalizando
Neste breve artigo, você viu como instalar o CucumberJS, e como seguir o processo do BDD para desenvolver uma funcionalidade simples guiado pelo comportamento!
Você pode conferir o projeto final no meu Github
https://github.com/papitoio/prato-do-dia-js
Curtiu? Compartiha nas suas redes sociais!
Abração
Papito
Comentários