Cucumber com Ruby em 10 Minutos

Artigos

Cucumber com Ruby em 10 Minutos

Fernando Papito
Escrito por Fernando Papito em 14 de julho de 2019
Junte-se a mais de 7000 alunos

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

Neste artigo você vai…

  • Instalar o Cucumber
  • Escrever seu primeiro cenário com a sintaxe do Gherkin
  • Automatizar o cenário com Ruby
  • 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 Ruby instalado.

Abra um terminal para verificar se o Ruby está instalado corretamente:

ruby -v
gem install bundler
bundle -v

Crie um projeto do ZERO

mkdir c:\qaninja
mkdir c:\qaninja\prado-do-dia
cd c:\qaninja\prado-do-dia

Na pasta “prado-do-dia”, crie um arquivo com o nome Gemfile e coloque as o seguinte código:

source "https://rubygems.org"

gem "cucumber", "~> 3.1.0"
gem "rspec", "~> 3.7.0"

Instalando o Cucumber pelo Gemfile

bundle install
cucumber --version
cucumber --init

Pronto, agora você tem um projeto simples para trabalhar com Cucumber.

Pra sabermos que se tudo está funcionando certinho, vamos executar o cucumber:

cucumber

O resultado no terminal deve ser assim:

0 scenarios
0 steps
0m0.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 DadoQuandoEntã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:

cucumber

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 códigos Ruby que automatizam o comportamento e já está sugerindo os métodos (esqueleto) em códigos Ruby para avançamos com o processo de desenvolvimento do app Prato do Dia.

Crie o arquivo steps.rb em features/step_definitions/

Agora, copie os métodos no arquivo steps.rb

Dado("que hoje é {string}") do |string|
  pending # Write code here that turns the phrase above into concrete actions
end

Quando("eu pergunto qual é o prato do dia") do
  pending # Write code here that turns the phrase above into concrete actions
end

Então("a resposta deve ser {string}") do |string|
  pending # Write code here that turns the phrase above into concrete actions
end

Executando cenário como pendente

Agora que temos os steps em métodos ruby, vamos pedir ao Cucumber para executá-lo novamente. No terminal digite cucumber conforme abaixo:

O Cucumber encontrou os códigos Ruby 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:

class Restaurante
  def prato_do_dia(dia)
  end
end

Dado("que hoje é {string}") do |dia|
  @hoje = dia
end

Quando("eu pergunto qual é o prato do dia") do
  @valor_obtido = Restaurante.new.prato_do_dia(@hoje)
end

Então("a resposta deve ser {string}") do |valor_esperado|
  expect(@valor_obtido).to eql valor_esperado
end

Perceba que eu fiz a implementação do comportamento, onde a classe Restaurante representa a unidade de código que deve ser desenvolvida. Seguida pelos steps que ativam e acessam os recursos da classe 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:

class Restaurante
  def prato_do_dia(dia)
    if dia == "segunda-feira"
      return "Virado a Paulista"
    end
  end
end

Agora veja cenário passando

Execute o Cucumber novamente:

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:

class Restaurante
  def prato_do_dia(dia)
    case (dia)
    when "segunda-feira"
      return "Virado a Paulista"
    when "terça-feira"
      return "Dobradinha"
    end
  end
end

Execute o cucumber mais uma vez:

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: cucumber –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:

Acho que você começou a entender o que estamos fazendo né?
Resultado de imagem para TDD everywhere

Implementando os demais cenários

Agora que temos todos os cenários, devemos fazer algumas refatorações:

class Restaurante
  def prato_do_dia(dia)
    case (dia)
    when "segunda-feira"
      return "Virado a Paulista"
    when "terça-feira"
      return "Dobradinha"
    when "quarta-feira"
      return "Feijoada"
    when "quinta-feira"
      return "Macarrão"
    when "sexta-feira"
      return "Filé de Peixe"
    end
  end
end

Executando o Cucumber mais uma vez:

Finalizando

Neste breve artigo, você viu como instalar o Cucumber, 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

Quer saber mais sobre Cucumber e BDD? Veja nossos cursos!

E ai,

o que você achou deste conteúdo? Conte nos comentários.

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

Junte-se a mais de 7000 alunos