131
Desenvolvimento Baseado em Testes BDD + Cucumber Eduardo Mendes [email protected]

BDD com Cucumber

Embed Size (px)

DESCRIPTION

Introdução ao BDD com Cucumber

Citation preview

Page 1: BDD com Cucumber

DesenvolvimentoBaseado em TestesBDD + CucumberEduardo [email protected]

Page 2: BDD com Cucumber

@dudumendes

Introdução

Page 3: BDD com Cucumber

Agenda

BDDCucumber

Page 4: BDD com Cucumber

@dudumendes

BDD

Page 5: BDD com Cucumber

TDDAbordagem de desenvolvimento de software em que os testes direcionam a implementação do software

Page 6: BDD com Cucumber

TDD

Favorece o design de software

Expressa o comportamento do código

Documenta o código

Page 7: BDD com Cucumber

@dudumendes

Testes unitários

Uma forma de aplicar o TDD

Traduzem as expectativas dos desenvolvedores sobre o comportamento do código

Fragilidade: Muito acoplado à implementação

Não traduz as expectativas dos usuários

Page 8: BDD com Cucumber

Expectativas dos usuários

Casos de Uso

Estórias de Usuário

Ambas não possuem mecanismos de validação que traduzam as expectativas dos usuários

Page 9: BDD com Cucumber

@dudumendes

BDDBehaviour Driven Development

Page 10: BDD com Cucumber

@dudumendes

BDDBehaviour Driven Design

Page 11: BDD com Cucumber

@dudumendes

BDD

“Behaviour-Driven Development is about implementing an application by describing its behaviour from the perspective of its stakeholders.”

David Chemlimsky

Page 12: BDD com Cucumber

BDD

“Desenvolvimento orientado a comportamento diz respeito a implementar uma aplicação pela descrição do seu comportamento a partir da perspectiva de seus stakeholders.”

David Chemlimsky

Entender o mundo a partir da visao do STK_HD

Para entregar COISAS UTEISEntender o seu domínioSeus desafios e oportunidadesAs palavras que ele usa para descrever o comportamento que ele quer da aplicação

Mais que da visão de um stakeholderDo ponto de vista de qualquer que está envolvido no projeto

Page 13: BDD com Cucumber

Behaviour Driven Development

Uma abordagem no estilo TDD

Documentação executável

Melhora a comunicação dos times

Esclarece os mal-entendimentos entre clientes, especialistas de domínio, desenvolvedores

Pode ser utilizada por todos os envolvidos no projeto

Page 14: BDD com Cucumber

@dudumendes

BDDPrincípios

Enough is enough

Deliver stakeholder value

It’s all behaviour

Page 15: BDD com Cucumber

@dudumendes

BDDPrincípios

O bastante é o bastanteTrabalhar para alcançar as expectativas dos stakeholders, mas evitar fazer mais do que se é necessário fazer

Entregar valor ao stakeholderSe você está fazendo algo que não entrega valor ou não aumenta sua habilidade de entrega de valor, pare e faça outra coisa

Tudo é sobre comportamentoAssim como podemos descrever o comportamento a partir da perspectivas dos stakeholders, também podemos descrever o comportamento de um código a partir de outro código que o utiliza

Page 16: BDD com Cucumber

@dudumendes

Ciclo do BDD

red

red

greenrefactor

green

refactor

Cenário

Passo

Page 17: BDD com Cucumber

@dudumendes

BDDO Ciclo

Stakeholder e analista discutem os requisitos

os requisitos são organizados em funcionalidades (features)

podem ser quebradas em estórias

fazem sentido para o stakeholder

Page 18: BDD com Cucumber

@dudumendes

BDDO Ciclo

Stakeholder, analista e testador determinam os escopos das estórias

o analista pensa na funcionalidade de forma geral

o testador pensa em cenários concretos, com valores de entradas e saída

Page 19: BDD com Cucumber

@dudumendes

BDDO Ciclo

Cenários prioritários são identificados

Stakeholder especifica exatamente o que quer entregue

Desenvolvedores implementam o bastante para satisfazer os cenários e nada mais

Page 20: BDD com Cucumber

@dudumendes

BDDO Ciclo

Desenvolvedores

Automatizam cenários que orientam o desenvolvimento

Descrevem comportamentos esperados

Implementam os comportamentos

Refatoram

Page 21: BDD com Cucumber

@dudumendes

Processo do BDD

Page 22: BDD com Cucumber

@dudumendes

Estórias no BDD

Page 23: BDD com Cucumber

BDDEstórias e Comportamento

Estórias

Correspondem às Estórias de Usuário

Expressam o comportamento das explicações em alto nível

Necessidade de frameworks de estórias

Cucumber, JBehave

Page 24: BDD com Cucumber

BDDEstórias e Comportamento

Comportamento (ou Spec)

Correspondem às expectativas em nível de classeExpressam o comportamento a nível de serviço/componente

Page 25: BDD com Cucumber

Estórias e Comportamento

Estórias de Usuário

Formado por um conjunto de Cenários (Scenarios)

critérios de aceitaçãoCada cenários possui

“entradas”, eventos e “resultados”Utilizados em projetos ágeis

Behaviour

Expressado como métodos de testesDefine o que aplicação deve e não deve fazer

Page 26: BDD com Cucumber

Estrutura de uma estóriaConnextra Format

Título

Narrativa

As a [algum_papel]I want [alguma_necessidade]So that [beneficio/valor_da_caracteristica]

Critérios de aceitação (cenários)

Given [alguma(s)_condicao(oes)]When [evento_ocorrer]Then [certifico_algum_resultado]

Page 27: BDD com Cucumber

Estrutura de uma estória

Título

Narrativa

Como um [algum_papel]Eu quero [alguma_necessidade]Para que [beneficio/valor_da_caracteristica]

Critérios de aceitação (cenários)

Dado [alguma(s)_condicao(oes)_entrada]Quando [evento_ocorrer]Então [certifico_algum_resultado]

Page 28: BDD com Cucumber

Ciclo do BDD

red

red

grerefactor

grerefactor

Cenário

Passo

Page 29: BDD com Cucumber

@dudumendes

Cucumber

Page 30: BDD com Cucumber

Cucumber

Framework BDD Open Source baseado em RSpec

Criado por Aslak Hellesøy

Versão atual 1.2.1

Page 31: BDD com Cucumber

CucumberCaracterísticas

Implementação em Ruby

Estórias de usuário baseadas em textos

Suporte a Injeção de dependências

Page 32: BDD com Cucumber

Cucumberem 03 passos

Escrever uma estória e executar a estória (.feature)

obter os snippets com os passos do teste

Criar o arquivos de passos a partir dos snippets

Dar implementação aos passos

Page 33: BDD com Cucumber

@dudumendes

Cucumber em 03 passosPasso 1 - Escrever uma estória

Page 34: BDD com Cucumber

Estrutura de uma estóriaNarrativa

As a [algum_papel]

I want [alguma_necessidade]

So that [beneficio/valor_da_caracteristica]

Cenário

Given [alguma(s)_condicao(oes)]

When [evento_ocorrer]

Then [certifico_algum_resultado]

Page 35: BDD com Cucumber

Estrutura de uma estóriaNarrative:

In order to [beneficio/valor_da_caracteristica]

As a [algum_papel]

I want to [alguma_necessidade]

Scenario: Nome do Cenário

Given [alguma(s)_condicao(oes)]

When [evento_ocorrer]

Then [certifico_algum_resultado]

Page 36: BDD com Cucumber

@dudumendes

Estórias no Cucumberarquivos

de texto com extensão “.feature”

localização

diretório features

o comando procura por um diretório “features”

execução

comando cucumber

busca o diretório

Page 37: BDD com Cucumber

Cucumber em 03 passosPasso 1 - Escrever uma estória

Feature: greeter says hello

In order to test Cucumber As a developer I want a greeter to say hello

Scenario: greeter says hello Given a greeter When I send it the greet message Then I should see "Hello Cucumber"

gretter_say_hello.feature

Page 38: BDD com Cucumber

@dudumendes

cucumber

Page 39: BDD com Cucumber

@dudumendes

continuação: snippets

Page 40: BDD com Cucumber

@dudumendes

Resultado

O cucumber encontrou a feature

tentou executá-la

mas não sabe como executá-la

O cucumber sugeriu algumas dicas do código

Page 41: BDD com Cucumber

@dudumendes

Cucumber em 03 passosPasso 2 - Criar o arquivo de passos

Page 42: BDD com Cucumber

@dudumendes

Estórias no Cucumberarquivos

em Ruby com sufixo “_steps”

localização

features/step_definitions

execução

comando cucumber

Page 43: BDD com Cucumber

@dudumendes

Given /^a greeter$/ do pending # express the regexp above with the code you wish you hadend

When /^I send it the greet message$/ do pending # express the regexp above with the code you wish you hadend

Then /^I should see "(.*?)"$/ do |arg1| pending # express the regexp above with the code you wish you hadend

greeter_steps.rb

Page 44: BDD com Cucumber

@dudumendes

Cucumber em 03 passosPasso 3 - Dar implementação às estórias

Page 45: BDD com Cucumber

@dudumendes

Given /^a greeter$/ do @greeter = CucumberGreeter.newend

When /^I send it the greet message$/ do @message = @greeter.greetend

Then /^I should see "(.*?)"$/ do |greeting| @message.should == greetingend

greeter_steps.rb

Page 46: BDD com Cucumber

@dudumendes

Page 47: BDD com Cucumber

@dudumendes

class CucumberGreeter def greet "Hello Cucumber" end end

Given /^a greeter$/ do @greeter = CucumberGreeter.newend

When /^I send it the greet message$/ do @message = @greeter.greetend

Then /^I should see "(.*?)"$/ do |greeting| expect(@message).to eql greetingend

Page 48: BDD com Cucumber

@dudumendes

Page 49: BDD com Cucumber

Cucumber Passos

Escrever uma estória

Arquivo de texto de extensão .feature

Recuperar os snippets

Criar o arquivo de passos

Page 50: BDD com Cucumber

Estórias no Cucumber

Estórias em arquivos de textos

01 Narrativa (Narrative)

* Cenários (Scenarios)

Narrativa

Opcional

As a, In order to, I want to

Page 51: BDD com Cucumber

Cenários no CucumberCenários consistem em:

Título

Passos:Given, When, Then

And

é possível colocar then antes do when

Cenários podem depender de outros

Comentários (!-- )

Page 52: BDD com Cucumber

@dudumendes

Gherkin

Feature:

Scenario:

Given When Then

Internacionalização

Inglês é o padrão

# language: pt

Aplicação

Step definitions

Features

Page 53: BDD com Cucumber

@dudumendes

Gherkin

Feature

Scenario

Scenario Outline

Scenarios

Given

When

Then

And

But

|

“”

#

Page 54: BDD com Cucumber

@dudumendes

Gherkin --i18n

cucumber --i18n pt

Page 55: BDD com Cucumber

@dudumendes

Exercício

Criar uma versão em português para o Hello World

Page 56: BDD com Cucumber

Esquema de CenáriosScenario Outline

É comum em testes de aceitação definir-se exemplos de cenários reais com valores para verificar o estado de pronto da aplicação

Neste caso é possível se utilizar esquemas de cenários

Page 57: BDD com Cucumber

Esquemas de cenários

Nos cenários os parâmetros devem ser envolvidos com sinais “<” e “>”

Eles devem ser declarados como esquemas de cenários

Após um cenário informam-se os valores válidos para os parâmetros em um tabela determinada por “Cenários:”

Page 58: BDD com Cucumber

@dudumendes

# language: pt

Funcionalidade: Depositar Dinheiro

Esquema do Cenário: Depositar Dinheiro

Dado um cliente especial com saldo atual de <saldo_inicial> reais Quando ele realizar um deposito no valor <deposito> reais Então o deposito deve ser realizado E o saldo da conta atualizado para <saldo_final> reais Cenarios: valores possiveis | saldo_inicial | deposito | saldo_final | | 200 | 100 | 300 | | 200 | 100 | 300 | | 200 | 100 | 300 | | 200 | 100 | 300 |

Page 59: BDD com Cucumber

@dudumendes

O comando cucumber

Page 60: BDD com Cucumber

@dudumendes

Organizando featuresComando cucumber sem opções

serão procurados todos os arquivos .rb e .feature abaixo do diretório features

gera snippets para features indefinidas

cada Cenário e Passo tem comentários no final da linha

localização do cenário

nome do arquivo e número da linha

Page 61: BDD com Cucumber

@dudumendes

# language: pt

Funcionalidade: Futuro hospede reserva um quarto

A fim de proporcionar mais comodidade Como dono do hotel Eu gostaria que os futuros hospedes reservassem quartos pela internet

Cenario: Reserva com sucesso Dado um hotel com "10" quartos e "0" reservas

Page 62: BDD com Cucumber

@dudumendes

Organizando features

Page 63: BDD com Cucumber

@dudumendes

Organizando featuresComando cucumber sem opções

serão procurados todos os arquivos .rb e .feature

Para projetos pequenos

caminho mais simples é organizar os arquivos dentro do diretório features

Para projetos maiores

crie subdiretorios para cada feature

vários arquivos em cada diretório com um subconjunto de ceários coesos

Page 64: BDD com Cucumber

@dudumendes

Organizando featuresfeatures

seguro

medico

dentario

vida

previdencia

prbl

vgbl

cucumber features

executa todos

cucumber features/seguro

apenas os de seguro

cucumber features/seguro/medico

somente os médicos

Page 65: BDD com Cucumber

@dudumendes

A vida de um cenárioNo processo de software

Cada cenário de uma funcionalidade precisa ser descrito e aprovado

Durente a especificação, os cenários podem estar

pendentes de aprovação

em progresso

estados mistos em uma mesma feature

pode ser necessário testar um subjconjunto da suites de testes

Page 66: BDD com Cucumber

@dudumendes

Tags para features/scenarios

É como uma annotation

pode ser utilizada para marcar features e/ou scenarios

scenarios herdam as tags de suas features

podem ser utilizadas para

Page 67: BDD com Cucumber

@dudumendes

Tags

@aprovada @sprint_1

Funcionalidade: paciente solicita consulta

@em_progresso

Cenario: paciente seleciona horario disponivel

cucumber --tags @em_progresso

Page 68: BDD com Cucumber

@dudumendes

Tagscucumber --tags @cuc, @umber

cucumber --tags @cuc || @umber

executa todos os cenário com @cuc OU @umber

cucumber --tags @cuc --tags @umber

cucumber --tags @cuc && @umber

executa todos os cenário com @cuc E @umber

cucumber --tags ~@umber

cucumber --tags !@umber

executa todos os cenário sem @umber

Page 69: BDD com Cucumber

@dudumendes

Passo-a-passo

Page 70: BDD com Cucumber

@dudumendes

GivenWhen

Then

Page 71: BDD com Cucumber

@dudumendesPassosUm passo candidato (StepCandidate) de uma feature deve estar associado a uma implementação de passo em um arquivo de passos

feature_X.feature

Cenario: Cenario A

Dado um contexto

Quando algo acontecer

Então Alguma coisa acontece

Arquivo de Passos

cenario_a_steps.rb

Dado um contexto

Quando algo acontecer

Então Alguma coisa acontece

implementação

implementação

implementação

Esta associação é feita através de expressões regulares

Page 72: BDD com Cucumber

@dudumendes

Passos

Um passo candidato (StepCandidate) de uma feature deve estar associado a uma implementação de passo em um arquivo de passos

Caso esteja: passed

Caso contrário: undefined

Page 73: BDD com Cucumber

@dudumendes

Definição de passosCriação do arquivo de feature

Quando você cria uma feature

executa o cucumber

cenários indefinidos

passos indefinidos

snippets de código

Page 74: BDD com Cucumber

@dudumendes

ExecutaCenário

Lê 1.º passoExiste

definição?

Lê próximopasso

PassoIndefinido

Pendente?Exceção lançada?

Existe outro passo

CenárioFalho

Executa código de definição do

passo

Não

Sim

SimNão

CenárioPendente

Sim

CenárioIndefinido

Sim

Não

Não

CenárioPassou

Page 75: BDD com Cucumber

@dudumendes

# language: pt

Funcionalidade: Futuro hospede reserva um quarto

A fim de proporcionar mais comodidade Como dono do hotel Eu gostaria que os futuros hospedes reservassem quartos pela internet

Cenario: Reservar com sucesso Dado um hotel com "10" quartos e "0" reservas

Page 76: BDD com Cucumber

@dudumendes

Definição de passosCriação do arquivo de passos

Cria-se o arquivo de passos

Dado /^um hotel com "(.*?)" quartos e "(.*?)"

reservas$/ do |total_de_quartos, total_de_reservas|

end

Page 77: BDD com Cucumber

@dudumendes

Given / When / ThenO formato Connextra

Utilizados para descrever os passos de um teste de aceitação

servem para descrever o cenário de uma vida real

expressam comportamento esperado

Page 78: BDD com Cucumber

@dudumendes

GivenDado

Indica algo que se aceita como verdadeiro e certo em um cenário

Dado que tenho R$ 20 em minha conta

Dado que a Terra é redonda

Dado que hoje é sábado

É uma setença que descreve um contexto para os eventos e saídas que serão exercitados nos cenários

Não são pré-condições

Page 79: BDD com Cucumber

@dudumendes

WhenQuando

Indica o evento que ocorre naquele cenário

Quando eu saco R$ 10

Quando eu pulo da estratosfera

Melhor que se tenha um evento por cenário

melhor descrição da intenção de cada cenário

falhas não serão ocultadas quando mais que um evento for descrito

Page 80: BDD com Cucumber

@dudumendes

ThenEntão

Indica uma saída esperada

Então eu devo ter R$ 5 no final

Então eu devo pular antes de sair da atmosfera

Pode haver mais que uma saída por cenário

mas devem ser coesas

Page 81: BDD com Cucumber

@dudumendes

And / ButE / Mas

Podem ser utilizados para complementar a descrição do Given e do Then

Cenario: Reserva com sucesso

Dado um hotel com "10" quartos E com "0" reservas Quando um futuro hospede reservar "1" quarto Entao reservas será "1" E o número dos quartos será "9"

Page 82: BDD com Cucumber

@dudumendes

Page 83: BDD com Cucumber

@dudumendes

Passos compostos

Page 84: BDD com Cucumber

@dudumendes

Passos Compostos

Em BDD, o autor de cenários deve possuir a liberdade de aprofundar o foco de um determinado cenário

esta situação pode ultrapassar o limite de um cenário inicial

um passo pode depender de passos utilizados em outros cenários

Neste contexto, os cenários compostos são úteis

Page 85: BDD com Cucumber

@dudumendes

Passos Compostos

Passos compostos permitem criar grupos de execução de passos ligados a um único passo, o que pode ser muito útil e poderoso

Page 86: BDD com Cucumber

@dudumendes

Funcionalidade: Logar na aplicacao

Cenário: Usuario existe

Dado que o usuario "dudumendes" existe Dado que eu informei o login "dudumendes"

Dado /^que o usuario "(.*?)" existe$/ do |nome| # ...end

Dado /^que eu informei o login "(.*?)"$/ do |nome| # ...end

Page 87: BDD com Cucumber

@dudumendes

Cenário: Usuario existe

Dado que o usuario "dudumendes" existe Dado que eu informei o login "dudumendes"

Dado que "dudumendes" está logado

Dado /^que o usuario "(.*?)" existe$/ do |nome| # ...end

Dado /^que eu informei o login "(.*?)"$/ do |nome| # ...end

Dado /^que (.*?) está logado$/ do |nome| step "que o usuario #{nome} existe" step "que eu informei o login #{nome}"end

Page 88: BDD com Cucumber

@dudumendes

Funcionalidade: Transferir Dinheiro

Cenário: Transferir Dinheiro

Quando eu seleciono "conta corrente" como conta de origem E eu seleciono "poupanca" como conta de destino E eu informo que a quantidade é 20 E solicito executar

Quando /^eu seleciono "(.*?)" como conta de origem$/ do |origem|end

Quando /^eu seleciono "(.*?)" como conta de destino$/ do |destino|end

Quando /^eu informo que a quantidade é (\d+)$/ do |valor|end

Quando /^solicito executar$/ doend

Page 89: BDD com Cucumber

@dudumendes

Funcionalidade: Transferir Dinheiro

Cenário: Transferir Dinheiro

Quando eu seleciono "conta corrente" como conta de origem E eu seleciono "poupanca" como conta de destino E eu informo que a quantidade é 20 E solicito executar Cenário: Transferir Dinheiro Resumido

Quando eu transfiro 20 da "conta corrente" para a "poupanca"

Page 90: BDD com Cucumber

@dudumendes

Quando /^eu transfiro (\d+) da (.*?) para a (.*?)$/ do |valor, origem, destino| step "eu seleciono #{origem} como conta de origem" step "eu seleciono #{destino} como conta de destino" step "eu informo que a quantidade é #{valor}" step "solicito executar"end

Page 91: BDD com Cucumber

@dudumendes

ExercícioCompletar a feature da Transferência e fazer passar

Page 92: BDD com Cucumber

@dudumendes

Hooks

Page 93: BDD com Cucumber

@dudumendes

Hooks

Before

Executado antes de cada cenário

After

Executado depois de cada cenário

AfterStep

Executado após cada passo

Page 94: BDD com Cucumber

@dudumendes

Before do puts "Isto executa antes de cada cenário"end

After do puts "Isto executa depois de cada cenário"end

AfterStep do puts "Isto executa depois de cada passo"end

Before(“@cuc”) do puts "Isto executa antes de cada cenário com @cuc"end

Page 95: BDD com Cucumber

@dudumendes

BackgroundContexto, Cenario de Fundo

Before, After, AfterStep

Não possuem descrição na feature

Background

Similar ao Before

Permite escrever passos na feature

Page 96: BDD com Cucumber

@dudumendes

Funcionalidade: Convidar amigos

Contexto: Usuario logado

Dado que "dudumendes" esta logado Cenário: Convidar alguem que já é amigo Cenário: Convidar alguem que ainda não é amigo

Page 97: BDD com Cucumber

@dudumendes

Tabelas em passos

Page 98: BDD com Cucumber

@dudumendes

Funcionalidade: Baralho

Cenário: tres do mesmo tipo ganha de dois pares

Dado uma mao com as seguintes cartas | valor | naipe | | 2 | CORACAO | | 2 | ESPADAS | | 2 | PAUS | | 4 | OUROS | | A | CORACAO |

E outra mao com as seguintes cartas | valor | naipe | | 2 | CORACAO | | 2 | ESPADAS | | 4 | PAUS | | 4 | OUROS | | A | CORACAO | Entao a primeira mao deve ganhar da segunda mao

Page 99: BDD com Cucumber

@dudumendes

Dado /^uma mao com as seguintes cartas$/ do |table| # table is a Cucumber::Ast::Table pending # express the regexp above with the code you wish you hadend

Dado /^outra mao com as seguintes cartas$/ do |table| # table is a Cucumber::Ast::Table pending # express the regexp above with the code you wish you hadend

Entao /^a primeira mao deve ganhar da segunda mao$/ do pending # express the regexp above with the code you wish you had

Page 100: BDD com Cucumber

@dudumendes

Dado uma mao com as seguintes cartas | valor | naipe | | 2 | CORACAO | | 2 | ESPADAS | | 2 | PAUS | | 4 | OUROS | | A | CORACAO |

[ { :valor => '2', :naipe => 'CORACAO'}, { :valor => '2', :naipe => 'ESPADAS'}, { :valor => '2', :naipe => 'PAUS'}, { :valor => '4', :naipe => 'OUROS'}, { :valor => 'A', :naipe => 'CORACAO'}]

Page 101: BDD com Cucumber

@dudumendes

Dado /^uma mao com as seguintes cartas$/ do |cartas| cartas.hashes.each {|hash| @primeira_mao << Carta.new(hash) }end

Dado /^outra mao com as seguintes cartas$/ do |cartas| cartas.hashes.each {|hash| @segunda_mao << Carta.new(hash) }end

Page 102: BDD com Cucumber

@dudumendes

Exercíciofazer passar a feature

Page 103: BDD com Cucumber

@dudumendes

Exercício

Page 104: BDD com Cucumber

@dudumendes

Criar a feature e fazer passarDados  os  negociantes:  |nome|rank||Larry|Estagio  3||Moe|Estagio  1||Curly|Estagio  2|Quando  os  negociantes  são  ordenados  pelo  nomeEntão  os  comerciantes  devem  vir  na  seguinte  ordem:|nome|rank||Curly|Estagio  2||Larry|Estagio  3||Moe|Estagio  1|

Page 105: BDD com Cucumber

@dudumendes

Rails + cucumber + rspecpequena dose

Page 106: BDD com Cucumber

@dudumendes

rails new showtime

Page 107: BDD com Cucumber

@dudumendes

Gemfilegroup :development, :test do

gem "rspec-rails"

gem "webrat"

end

group :test do

gem "cucumber-rails"

gem ”database_cleaner”

end

Page 108: BDD com Cucumber

@dudumendes

bundle install

rails generate rspec:install (dependencias do rspec)

rails generate cucumber:install (dependencias do cucumber)

rake db:migrate

rake db:test:prepare

rake spec

rake cucumber

Page 109: BDD com Cucumber

@dudumendes

Funcionalidade: Descrições Como um frequentador de cinema Eu quero ver horarios precisos e concisos Para que eu possa encontrar filmes que se encaixem no meu horario

Cenário: Exibir minutos para horarios que não terminam em 00 Dado um filme Quando eu configuro o horario para "2012-10-10" às "2:15pm" Então o horario deve ser "October 10, 2012 2:15pm"

/features/horario.feature

Page 110: BDD com Cucumber

@dudumendes

snippet

Page 111: BDD com Cucumber

@dudumendes

features/step_definitions/horario_steps.rb

# encoding: utf-8# language: pt

Dado /^um filme$/ do @filme = Filme.create!end

Quando /^eu configuro o horario para "(.*?)" às "(.*?)"$/ do |data, hora| @filme.update_attribute(:horario_data, Date.parse(data)) @filme.update_attribute(:horario_hora, hora)end

Então /^o horario deve ser "([^"]*)"$/ do |horario| expect(@filme.horario).to eql horarioend

Page 112: BDD com Cucumber

@dudumendes

Criar o Model Filme

rails g model filme horario_data:date horario_hora:time

Além do modelo criará o spec spec/model/filme_spec.rb

rake db:migrate

rake db:test:prepare

Page 113: BDD com Cucumber

@dudumendes

app/models/filme.rb

class Filme < ActiveRecord::Base attr_accessible :horario_data, :horario_hora def horario "#{data_formatada} #{hora_formatada}" end def data_formatada horario_data.strftime("%B %d, %Y") end def hora_formatada horario_hora.strftime("%l:%M%p").strip.downcase end end

Page 114: BDD com Cucumber

@dudumendes

Validando o modelo

Page 115: BDD com Cucumber

@dudumendes

rails generate model Email de:text para:text mensagem:text

Page 116: BDD com Cucumber

@dudumendes

require 'spec_helper'

describe Email do pending "add some examples to (or delete) #{__FILE__}"end

Page 117: BDD com Cucumber

@dudumendes

require 'spec_helper'

describe Email do context "validações:" do

it "para é obrigatório"

it "para é válido com email válido"

it "para é inválido com email inválido"

it "mensagem é obrigatória"

endend

Page 118: BDD com Cucumber

@dudumendes

Page 119: BDD com Cucumber

@dudumendesrequire 'spec_helper'

describe Email do context "validações:" do

it "para é obrigatório" do email = Email.create expect(email).to have(1).error_on(:para) end

it "para é válido com email válido"

it "para é inválido com email inválido"

it "mensagem é obrigatória"

endend

Page 120: BDD com Cucumber

@dudumendes

Page 121: BDD com Cucumber

@dudumendes

class Email < ActiveRecord::Base attr_accessible :mensagem, :paraend

app/models/email.rb

Page 122: BDD com Cucumber

@dudumendes

class Email < ActiveRecord::Base attr_accessible :mensagem, :para validates_presence_of :paraend

app/models/email.rb

Page 123: BDD com Cucumber

@dudumendes

# encoding: utf-8

require 'spec_helper'

describe Email do context "validações:" do it "de é obrigatório" do email = Email.create expect(email).to have(1).error_on(:de) end it "para é obrigatório" it "mensagem é obrigatória"

it "de deve ser um email" do email = Email.create(:de => "[email protected]") expect(email).to have(:no).error_on(:de) end it "para deve ser um email" endend

Page 124: BDD com Cucumber

@dudumendes

Page 125: BDD com Cucumber

@dudumendes

describe Email do context "validações:" do it "para é obrigatório" do email = Email.create expect(email).to have(1).error_on(:para) end it "para é válido com email válido" do email = Email.create(:para => "[email protected]") expect(email).to have(:no).error_on(:para) end it "para é inválido com email inválido" it "mensagem é obrigatória" endend

Page 126: BDD com Cucumber

@dudumendes

Page 127: BDD com Cucumber

@dudumendes

# encoding: utf-8

require 'spec_helper'

describe Email do context "validações:" do it "para é obrigatório" do email = Email.create expect(email).to have(1).error_on(:para) end it "para é válido com email válido" do email = Email.create(:para => "[email protected]") expect(email).to have(:no).error_on(:para) end it "para é inválido com email inválido" do email = Email.create(:para => "invalido") expect(email).to have(1).error_on(:para) end it "mensagem é obrigatória" endend

Page 128: BDD com Cucumber

@dudumendes

class Email < ActiveRecord::Base attr_accessible :mensagem, :para validates_presence_of :para validates_format_of :para, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => trueend

Page 129: BDD com Cucumber

@dudumendesdescribe Email do context "validações:" do it "para é obrigatório" do email = Email.create expect(email).to have(1).error_on(:para) end it "para é válido com email válido" do email = Email.create(:para => "[email protected]") expect(email).to have(:no).error_on(:para) end it "para é inválido com email inválido" do email = Email.create(:para => "invalido") expect(email).to have(1).error_on(:para) end it "mensagem é obrigatória" do email = Email.create expect(email).to have(1).error_on(:mensagem) end endend

Page 130: BDD com Cucumber

@dudumendes

class Email < ActiveRecord::Base attr_accessible :mensagem, :para validates_presence_of :para validates_presence_of :mensagem validates_format_of :para, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => trueend

Page 131: BDD com Cucumber

@dudumendes

BibliografiaBEHAVIOUR-DRIVEN DEVELOPMENT. http://behaviour-driven.org/.

CHELIMSKY, David. The RSpec Book. PragBook, 2011.

JBEHAVE. http://jbehave.org/reference/.

PUGH, Ken. Lean-Agile Acceptance Test-Driven Development: better software through collaboration. Addison-Wesley, 2010.