0
DesenvolvimentoBaseado em TestesBDD + CucumberEduardo Mendesedumendes@gmail.com
@dudumendesIntrodução
AgendaBDDCucumber
@dudumendesBDD
TDD Abordagem de desenvolvimento de software em que os testes direcionam a implementação do software
TDDFavorece o design de softwareExpressa o comportamento do códigoDocumenta o código
@dudumendesTestes unitários Uma forma de aplicar o TDD   Traduzem as expectativas dos desenvolvedores   sobre o comportame...
Expectativas dos usuáriosCasos de UsoEstórias de UsuárioAmbas não possuem mecanismos de validação quetraduzam as expectati...
@dudumendes BDDBehaviour Driven Development
@dudumendesBDDBehaviour Driven Design
@dudumendesBDD“Behaviour-Driven Development is about implementingan application by describing its behaviour from theperspe...
Entender o mundo a partir da visao doBDD                         STK_HD                           Para entregar COISAS UTE...
Behaviour Driven Development  Uma abordagem no estilo TDD  Documentação executável  Melhora a comunicação dos times    Esc...
@dudumendesBDDPrincípios  Enough is enough  Deliver stakeholder value  It’s all behaviour
@dudumendesBDDPrincípios    O bastante é o bastante      Trabalhar para alcançar as expectativas dos stakeholders, mas    ...
@dudumendes                                      redCiclo do BDD                                      red                 ...
@dudumendesBDDO Ciclo Stakeholder e analista discutem os requisitos    os requisitos são organizados em funcionalidades   ...
@dudumendesBDDO Ciclo Stakeholder, analista e testador determinam os escopos das estórias    o analista pensa na funcional...
@dudumendesBDDO Ciclo Cenários prioritários são identificados    Stakeholder especifica exatamente o que quer    entregue   ...
@dudumendesBDDO Ciclo Desenvolvedores    Automatizam cenários que orientam o    desenvolvimento    Descrevem comportamento...
@dudumendesProcesso do BDD
@dudumendesEstórias no BDD
BDDEstórias e Comportamento Estórias   Correspondem às Estórias de Usuário   Expressam o comportamento das explicações em ...
BDDEstórias e Comportamento    Comportamento (ou Spec)      Correspondem às expectativas em nível de      classe      Expr...
Estórias e Comportamento  Estórias de Usuário    Formado por um conjunto de Cenários    (Scenarios)      critérios de acei...
Estrutura de uma estóriaConnextra Format   Título   Narrativa     As a [algum_papel]     I want [alguma_necessidade]     S...
Estrutura de uma estória  Título  Narrativa    Como um [algum_papel]    Eu quero [alguma_necessidade]    Para que [benefici...
redCiclo do BDD              refactor                                      red                                            ...
@dudumendesCucumber
Cucumber Framework BDD Open Source baseado em RSpec   Criado por Aslak Hellesøy Versão atual 1.2.1
CucumberCaracterísticas  Implementação em Ruby  Estórias de usuário baseadas em textos  Suporte a Injeção de dependências
Cucumberem 03 passos Escrever uma estória e executar a estória (.feature)   obter os snippets com os passos do teste Criar...
@dudumendesCucumber em 03 passosPasso 1 - Escrever uma estória
Estrutura de uma estória Narrativa   As a [algum_papel]   I want [alguma_necessidade]   So that [beneficio/valor_da_caracte...
Estrutura de uma estória Narrative:   In order to [beneficio/valor_da_caracteristica]   As a [algum_papel]   I want to [alg...
@dudumendesEstórias no Cucumberarquivos  de texto com extensão “.feature”localização  diretório features  o comando procur...
Cucumber em 03 passosPasso 1 - Escrever uma estória  Feature: greeter says hello    In order to test Cucumber    As a deve...
@dudumendescucumber
@dudumendescontinuação: snippets
@dudumendesResultadoO cucumber encontrou a feature  tentou executá-la  mas não sabe como executá-laO cucumber sugeriu algu...
@dudumendesCucumber em 03 passosPasso 2 - Criar o arquivo de passos
@dudumendesEstórias no Cucumberarquivos  em Ruby com sufixo “_steps”localização  features/step_definitionsexecução  comando ...
@dudumendes                                             greeter_steps.rbGiven /^a greeter$/ do  pending # express the rege...
@dudumendesCucumber em 03 passosPasso 3 - Dar implementação às estórias
@dudumendes                                    greeter_steps.rbGiven /^a greeter$/ do  @greeter = CucumberGreeter.newendWh...
@dudumendes
@dudumendesclass CucumberGreeter  def greet    "Hello Cucumber"  endendGiven /^a greeter$/ do  @greeter = CucumberGreeter....
@dudumendes
Cucumber PassosEscrever uma estória  Arquivo de texto de extensão .featureRecuperar os snippetsCriar o arquivo de passos
Estórias no CucumberEstórias em arquivos de textos  01 Narrativa (Narrative)  * Cenários (Scenarios)Narrativa  Opcional  A...
Cenários no Cucumber  Cenários consistem em:    Título    Passos:      Given, When, Then      And      é possível colocar ...
@dudumendesGherkin                      Features                      Step definitionsFeature:                 Aplicação  S...
@dudumendesGherkinFeature            ThenScenario           AndScenario Outline   ButScenarios          |Given            ...
@dudumendesGherkin --i18n cucumber --i18n pt
@dudumendesExercício Criar uma versão em português para o Hello World
Esquema de CenáriosScenario Outline  É comum em testes de aceitação definir-se exemplos  de cenários reais com valores para...
Esquemas de cenáriosNos cenários os parâmetros devem ser envolvidoscom sinais “<” e “>”  Eles devem ser declarados como es...
@dudumendes# language: ptFuncionalidade: Depositar Dinheiro  Esquema do Cenário: Depositar Dinheiro    Dado um cliente esp...
@dudumendesO comando cucumber
@dudumendesOrganizando featuresComando cucumber sem opções  serão procurados todos os arquivos .rb e .feature  abaixo do d...
@dudumendes# language: ptFuncionalidade: Futuro hospede reserva um quarto  A fim de proporcionar mais comodidade  Como don...
@dudumendesOrganizando features
@dudumendesOrganizando featuresComando cucumber sem opções  serão procurados todos os arquivos .rb e .featurePara projetos...
@dudumendesOrganizando featuresfeatures   seguro        cucumber features      medico        executa todos      dentario  ...
@dudumendesA vida de um cenárioNo processo de software  Cada cenário de uma funcionalidade precisa ser descrito e  aprovad...
@dudumendesTags para features/scenarios É como uma annotation pode ser utilizada para marcar features e/ou scenarios   sce...
@dudumendesTags@aprovada @sprint_1Funcionalidade: paciente solicita consulta    @em_progresso    Cenario: paciente selecio...
@dudumendesTagscucumber --tags @cuc, @umbercucumber --tags @cuc || @umber  executa todos os cenário com @cuc OU @umbercucu...
@dudumendesPasso-a-passo
@dudumendesGiven    When           Then
Passos                                                      @dudumendes   Um passo candidato (StepCandidate) de uma   feat...
@dudumendesPassosUm passo candidato (StepCandidate) de umafeature deve estar associado a uma implementaçãode passo em um a...
@dudumendesDefinição de passosCriação do arquivo de feature  Quando você cria uma feature    executa o cucumber      cenári...
@dudumendes               Executa               Cenário                                  Existe        Não                ...
@dudumendes# language: ptFuncionalidade: Futuro hospede reserva um quarto  A fim de proporcionar mais comodidade  Como don...
@dudumendesDefinição de passosCriação do arquivo de passos  Cria-se o arquivo de passosDado /^um hotel com "(.*?)" quartos ...
@dudumendesGiven / When / ThenO formato Connextra Utilizados para descrever os passos de um teste de aceitação   servem pa...
@dudumendesGivenDado Indica algo que se aceita como verdadeiro e certo em um cenário   Dado que tenho R$ 20 em minha conta...
@dudumendesWhenQuando Indica o evento que ocorre naquele cenário   Quando eu saco R$ 10   Quando eu pulo da estratosfera  ...
@dudumendesThenEntão Indica uma saída esperada   Então eu devo ter R$ 5 no final   Então eu devo pular antes de sair da atm...
@dudumendesAnd / ButE / Mas Podem ser utilizados para complementar a descrição do Given e do Then Cenario: Reserva com suc...
@dudumendes
@dudumendesPassos compostos
@dudumendesPassos CompostosEm BDD, o autor de cenários deve possuir a liberdadede aprofundar o foco de um determinado cená...
@dudumendesPassos CompostosPassos compostos permitem criar grupos de execuçãode passos ligados a um único passo, o que pod...
@dudumendesFuncionalidade: Logar na aplicacao  Cenário: Usuario existe    Dado que o usuario "dudumendes" existe    Dado q...
@dudumendesCenário: Usuario existe  Dado que o usuario "dudumendes" existe  Dado que eu informei o login "dudumendes"  Dad...
@dudumendesFuncionalidade: Transferir Dinheiro  Cenário: Transferir Dinheiro    Quando eu seleciono "conta corrente" como ...
@dudumendesFuncionalidade: Transferir Dinheiro  Cenário: Transferir Dinheiro    Quando eu seleciono "conta corrente" como ...
@dudumendesQuando   /^eu transfiro (d+) da (.*?) para a (.*?)$/ do |valor, origem, destino|  step   "eu seleciono #{origem...
@dudumendesExercícioCompletar a feature da Transferência e fazer passar
@dudumendesHooks
@dudumendesHooksBefore  Executado antes de cada cenárioAfter  Executado depois de cada cenárioAfterStep  Executado após ca...
@dudumendesBefore do  puts "Isto executa antes de cada cenário"end    After do      puts "Isto executa depois de cada cená...
@dudumendesBackgroundContexto, Cenario de Fundo Before, After, AfterStep   Não possuem descrição na feature Background   S...
@dudumendesFuncionalidade: Convidar amigos Contexto: Usuario logado   Dado que "dudumendes" esta logado    Cenário: Convid...
@dudumendesTabelas em passos
@dudumendesFuncionalidade: Baralho  Cenário: tres do mesmo tipo ganha de dois pares   Dado uma mao com as seguintes cartas...
@dudumendesDado /^uma mao com as seguintes cartas$/ do |table|  # table is a Cucumber::Ast::Table  pending # express the r...
@dudumendesDado uma mao com as seguintes cartas| valor | naipe || 2 | CORACAO || 2 | ESPADAS || 2 | PAUS || 4 | OUROS || A...
@dudumendesDado /^uma mao com as seguintes cartas$/ do |cartas|  cartas.hashes.each {|hash|      @primeira_mao << Carta.ne...
@dudumendesExercíciofazer passar a feature
@dudumendesExercício
@dudumendesCriar a feature e fazer passarDados	  os	  negociantes:	  |nome|rank||Larry|Estagio	  3||Moe|Estagio	  1||Curly...
@dudumendesRails + cucumber + rspecpequena dose
@dudumendesrails new showtime
@dudumendesGemfilegroup :development, :test do gem "rspec-rails" gem "webrat"endgroup :test do gem "cucumber-rails" gem ”da...
@dudumendesbundle installrails generate rspec:install (dependencias do rspec)rails generate cucumber:install (dependencias...
@dudumendes /features/horario.featureFuncionalidade: Descrições  Como um frequentador de cinema  Eu quero ver horarios pre...
@dudumendessnippet
@dudumendes   features/step_definitions/horario_steps.rb# encoding: utf-8# language: ptDado /^um filme$/ do  @filme = Filme...
@dudumendesCriar o Model Filme rails g model filme horario_data:date horario_hora:time   Além do modelo criará o spec spec/...
@dudumendesapp/models/filme.rb class Filme < ActiveRecord::Base   attr_accessible :horario_data, :horario_hora   def horari...
@dudumendesValidando o modelo
@dudumendesrails generate model Email de:text para:text               mensagem:text
@dudumendesrequire spec_helperdescribe Email do  pending "add some examples to (or delete) #{__FILE__}"end
@dudumendesrequire spec_helperdescribe Email do    context "validações:" do            it "para é obrigatório"            ...
@dudumendes
@dudumendesrequire spec_helperdescribe Email do    context "validações:" do            it "para é obrigatório" do         ...
@dudumendes
@dudumendesapp/models/email.rbclass Email < ActiveRecord::Base  attr_accessible :mensagem, :paraend
@dudumendesapp/models/email.rbclass Email < ActiveRecord::Base  attr_accessible :mensagem, :para  validates_presence_of :p...
@dudumendesrequire spec_helperdescribe Email do  context "validações:" do    it "de é obrigatório" do      email = Email.c...
@dudumendes
@dudumendesdescribe Email do    context "validações:" do            it "para é obrigatório" do                email = Emai...
@dudumendes
require spec_helper                                           @dudumendesdescribe Email do    context "validações:" do    ...
@dudumendesclass Email < ActiveRecord::Base    attr_accessible :mensagem, :para      validates_presence_of :para      vali...
@dudumendesdescribe Email do    context "validações:" do            it "para é obrigatório" do                email = Emai...
@dudumendesclass Email < ActiveRecord::Base    attr_accessible :mensagem, :para      validates_presence_of :para      vali...
@dudumendesBibliografia BEHAVIOUR-DRIVEN DEVELOPMENT. http:// behaviour-driven.org/. CHELIMSKY, David. The RSpec Book. Prag...
Upcoming SlideShare
Loading in...5
×

BDD com Cucumber

1,756

Published on

Introdução ao BDD com Cucumber

Published in: Technology
2 Comments
6 Likes
Statistics
Notes
No Downloads
Views
Total Views
1,756
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
91
Comments
2
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "BDD com Cucumber"

  1. 1. DesenvolvimentoBaseado em TestesBDD + CucumberEduardo Mendesedumendes@gmail.com
  2. 2. @dudumendesIntrodução
  3. 3. AgendaBDDCucumber
  4. 4. @dudumendesBDD
  5. 5. TDD Abordagem de desenvolvimento de software em que os testes direcionam a implementação do software
  6. 6. TDDFavorece o design de softwareExpressa o comportamento do códigoDocumenta o código
  7. 7. @dudumendesTestes 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
  8. 8. Expectativas dos usuáriosCasos de UsoEstórias de UsuárioAmbas não possuem mecanismos de validação quetraduzam as expectativas dos usuários
  9. 9. @dudumendes BDDBehaviour Driven Development
  10. 10. @dudumendesBDDBehaviour Driven Design
  11. 11. @dudumendesBDD“Behaviour-Driven Development is about implementingan application by describing its behaviour from theperspective of its stakeholders.” David Chemlimsky
  12. 12. Entender o mundo a partir da visao doBDD STK_HD Para entregar COISAS UTEIS Entender o seu domínio Seus desafios e oportunidades As palavras que ele usa para descrever o comportamento que ele quer da aplicação Mais que da visão de um stakeholder Do ponto de vista de qualquer que está“Desenvolvimento orientado a comportamento diz envolvido no projetorespeito a implementar uma aplicação pela descriçãodo seu comportamento a partir da perspectiva de seusstakeholders.” David Chemlimsky
  13. 13. 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
  14. 14. @dudumendesBDDPrincípios Enough is enough Deliver stakeholder value It’s all behaviour
  15. 15. @dudumendesBDDPrincípios O bastante é o bastante Trabalhar para alcançar as expectativas dos stakeholders, mas evitar fazer mais do que se é necessário fazer Entregar valor ao stakeholder Se 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 comportamento Assim 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
  16. 16. @dudumendes redCiclo do BDD red refactor green refactor Passo green Cenário
  17. 17. @dudumendesBDDO 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
  18. 18. @dudumendesBDDO 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
  19. 19. @dudumendesBDDO 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
  20. 20. @dudumendesBDDO Ciclo Desenvolvedores Automatizam cenários que orientam o desenvolvimento Descrevem comportamentos esperados Implementam os comportamentos Refatoram
  21. 21. @dudumendesProcesso do BDD
  22. 22. @dudumendesEstórias no BDD
  23. 23. 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
  24. 24. BDDEstórias e Comportamento Comportamento (ou Spec) Correspondem às expectativas em nível de classe Expressam o comportamento a nível de serviço/ componente
  25. 25. Estórias e Comportamento Estórias de Usuário Formado por um conjunto de Cenários (Scenarios) critérios de aceitação Cada cenários possui “entradas”, eventos e “resultados” Utilizados em projetos ágeis Behaviour Expressado como métodos de testes Define o que aplicação deve e não deve fazer
  26. 26. 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]
  27. 27. 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]
  28. 28. redCiclo do BDD refactor red gre refactor Passo gre Cenário
  29. 29. @dudumendesCucumber
  30. 30. Cucumber Framework BDD Open Source baseado em RSpec Criado por Aslak Hellesøy Versão atual 1.2.1
  31. 31. CucumberCaracterísticas Implementação em Ruby Estórias de usuário baseadas em textos Suporte a Injeção de dependências
  32. 32. 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
  33. 33. @dudumendesCucumber em 03 passosPasso 1 - Escrever uma estória
  34. 34. Estrutura de uma estória Narrativa 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]
  35. 35. Estrutura de uma estória Narrative: 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]
  36. 36. @dudumendesEstó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
  37. 37. 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
  38. 38. @dudumendescucumber
  39. 39. @dudumendescontinuação: snippets
  40. 40. @dudumendesResultadoO cucumber encontrou a feature tentou executá-la mas não sabe como executá-laO cucumber sugeriu algumas dicas do código
  41. 41. @dudumendesCucumber em 03 passosPasso 2 - Criar o arquivo de passos
  42. 42. @dudumendesEstórias no Cucumberarquivos em Ruby com sufixo “_steps”localização features/step_definitionsexecução comando cucumber
  43. 43. @dudumendes greeter_steps.rbGiven /^a greeter$/ do pending # express the regexp above with the code you wish you hadendWhen /^I send it the greet message$/ do pending # express the regexp above with the code you wish you hadendThen /^I should see "(.*?)"$/ do |arg1| pending # express the regexp above with the code you wish you hadend
  44. 44. @dudumendesCucumber em 03 passosPasso 3 - Dar implementação às estórias
  45. 45. @dudumendes greeter_steps.rbGiven /^a greeter$/ do @greeter = CucumberGreeter.newendWhen /^I send it the greet message$/ do @message = @greeter.greetendThen /^I should see "(.*?)"$/ do |greeting| @message.should == greetingend
  46. 46. @dudumendes
  47. 47. @dudumendesclass CucumberGreeter def greet "Hello Cucumber" endendGiven /^a greeter$/ do @greeter = CucumberGreeter.newendWhen /^I send it the greet message$/ do @message = @greeter.greetendThen /^I should see "(.*?)"$/ do |greeting| expect(@message).to eql greetingend
  48. 48. @dudumendes
  49. 49. Cucumber PassosEscrever uma estória Arquivo de texto de extensão .featureRecuperar os snippetsCriar o arquivo de passos
  50. 50. Estórias no CucumberEstórias em arquivos de textos 01 Narrativa (Narrative) * Cenários (Scenarios)Narrativa Opcional As a, In order to, I want to
  51. 51. Cenários no Cucumber Cená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 (!-- )
  52. 52. @dudumendesGherkin Features Step definitionsFeature: Aplicação Scenario: Given When ThenInternacionalização Inglês é o padrão # language: pt
  53. 53. @dudumendesGherkinFeature ThenScenario AndScenario Outline ButScenarios |Given “”When #
  54. 54. @dudumendesGherkin --i18n cucumber --i18n pt
  55. 55. @dudumendesExercício Criar uma versão em português para o Hello World
  56. 56. 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
  57. 57. Esquemas de cenáriosNos cenários os parâmetros devem ser envolvidoscom sinais “<” e “>” Eles devem ser declarados como esquemas de cenáriosApós um cenário informam-se os valores válidos paraos parâmetros em um tabela determinada por“Cenários:”
  58. 58. @dudumendes# language: ptFuncionalidade: 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 |
  59. 59. @dudumendesO comando cucumber
  60. 60. @dudumendesOrganizando 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
  61. 61. @dudumendes# language: ptFuncionalidade: 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
  62. 62. @dudumendesOrganizando features
  63. 63. @dudumendesOrganizando featuresComando cucumber sem opções serão procurados todos os arquivos .rb e .featurePara projetos pequenos caminho mais simples é organizar os arquivos dentro do diretório featuresPara projetos maiores crie subdiretorios para cada feature vários arquivos em cada diretório com um subconjunto de ceários coesos
  64. 64. @dudumendesOrganizando featuresfeatures seguro cucumber features medico executa todos dentario cucumber features/seguro vida apenas os de seguro previdencia cucumber features/seguro/medico prbl somente os médicos vgbl
  65. 65. @dudumendesA 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
  66. 66. @dudumendesTags 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
  67. 67. @dudumendesTags@aprovada @sprint_1Funcionalidade: paciente solicita consulta @em_progresso Cenario: paciente seleciona horario disponivelcucumber --tags @em_progresso
  68. 68. @dudumendesTagscucumber --tags @cuc, @umbercucumber --tags @cuc || @umber executa todos os cenário com @cuc OU @umbercucumber --tags @cuc --tags @umbercucumber --tags @cuc && @umber executa todos os cenário com @cuc E @umbercucumber --tags ~@umbercucumber --tags !@umber executa todos os cenário sem @umber
  69. 69. @dudumendesPasso-a-passo
  70. 70. @dudumendesGiven When Then
  71. 71. Passos @dudumendes Um passo candidato (StepCandidate) de uma feature deve estar associado a uma implementação de passo em um arquivo de passos Arquivo de Passos cenario_a_steps.rb feature_X.feature Dado um contexto Cenario: Cenario A implementação Dado um contexto Quando algo acontecer Quando algo acontecer implementação Então Alguma coisa acontece Então Alguma coisa acontece implementaçãoEsta associação é feita através de expressões regulares
  72. 72. @dudumendesPassosUm passo candidato (StepCandidate) de umafeature deve estar associado a uma implementaçãode passo em um arquivo de passos Caso esteja: passed Caso contrário: undefined
  73. 73. @dudumendesDefiniçã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
  74. 74. @dudumendes Executa Cenário Existe Não Passo Cenário Lê 1.º passo definição? Indefinido Indefinido Sim Executa código Exceção SimLê próximo de definição do Pendente? lançada? passo passo Não Não Sim Existe Sim outro passo Não Cenário Cenário Falho Pendente Cenário Passou
  75. 75. @dudumendes# language: ptFuncionalidade: 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
  76. 76. @dudumendesDefinição de passosCriação do arquivo de passos Cria-se o arquivo de passosDado /^um hotel com "(.*?)" quartos e "(.*?)" reservas$/ do |total_de_quartos, total_de_reservas|end
  77. 77. @dudumendesGiven / 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
  78. 78. @dudumendesGivenDado 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
  79. 79. @dudumendesWhenQuando 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
  80. 80. @dudumendesThenEntã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
  81. 81. @dudumendesAnd / 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"
  82. 82. @dudumendes
  83. 83. @dudumendesPassos compostos
  84. 84. @dudumendesPassos CompostosEm BDD, o autor de cenários deve possuir a liberdadede 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áriosNeste contexto, os cenários compostos são úteis
  85. 85. @dudumendesPassos CompostosPassos compostos permitem criar grupos de execuçãode passos ligados a um único passo, o que pode sermuito útil e poderoso
  86. 86. @dudumendesFuncionalidade: 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
  87. 87. @dudumendesCená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
  88. 88. @dudumendesFuncionalidade: 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$/ do end
  89. 89. @dudumendesFuncionalidade: 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"
  90. 90. @dudumendesQuando /^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
  91. 91. @dudumendesExercícioCompletar a feature da Transferência e fazer passar
  92. 92. @dudumendesHooks
  93. 93. @dudumendesHooksBefore Executado antes de cada cenárioAfter Executado depois de cada cenárioAfterStep Executado após cada passo
  94. 94. @dudumendesBefore 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
  95. 95. @dudumendesBackgroundContexto, Cenario de Fundo Before, After, AfterStep Não possuem descrição na feature Background Similar ao Before Permite escrever passos na feature
  96. 96. @dudumendesFuncionalidade: 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
  97. 97. @dudumendesTabelas em passos
  98. 98. @dudumendesFuncionalidade: 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
  99. 99. @dudumendesDado /^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 hadendDado /^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 hadendEntao /^a primeira mao deve ganhar da segunda mao$/ do pending # express the regexp above with the code you wish you had
  100. 100. @dudumendesDado 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}]
  101. 101. @dudumendesDado /^uma mao com as seguintes cartas$/ do |cartas| cartas.hashes.each {|hash| @primeira_mao << Carta.new(hash) }endDado /^outra mao com as seguintes cartas$/ do |cartas| cartas.hashes.each {|hash| @segunda_mao << Carta.new(hash) }end
  102. 102. @dudumendesExercíciofazer passar a feature
  103. 103. @dudumendesExercício
  104. 104. @dudumendesCriar 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|
  105. 105. @dudumendesRails + cucumber + rspecpequena dose
  106. 106. @dudumendesrails new showtime
  107. 107. @dudumendesGemfilegroup :development, :test do gem "rspec-rails" gem "webrat"endgroup :test do gem "cucumber-rails" gem ”database_cleaner”end
  108. 108. @dudumendesbundle installrails generate rspec:install (dependencias do rspec)rails generate cucumber:install (dependencias do cucumber)rake db:migraterake db:test:preparerake specrake cucumber
  109. 109. @dudumendes /features/horario.featureFuncionalidade: 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"
  110. 110. @dudumendessnippet
  111. 111. @dudumendes features/step_definitions/horario_steps.rb# encoding: utf-8# language: ptDado /^um filme$/ do @filme = Filme.create!endQuando /^eu configuro o horario para "(.*?)" às "(.*?)"$/ do |data, hora| @filme.update_attribute(:horario_data, Date.parse(data)) @filme.update_attribute(:horario_hora, hora)endEntão /^o horario deve ser "([^"]*)"$/ do |horario| expect(@filme.horario).to eql horarioend
  112. 112. @dudumendesCriar 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
  113. 113. @dudumendesapp/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
  114. 114. @dudumendesValidando o modelo
  115. 115. @dudumendesrails generate model Email de:text para:text mensagem:text
  116. 116. @dudumendesrequire spec_helperdescribe Email do pending "add some examples to (or delete) #{__FILE__}"end
  117. 117. @dudumendesrequire spec_helperdescribe 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
  118. 118. @dudumendes
  119. 119. @dudumendesrequire spec_helperdescribe 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
  120. 120. @dudumendes
  121. 121. @dudumendesapp/models/email.rbclass Email < ActiveRecord::Base attr_accessible :mensagem, :paraend
  122. 122. @dudumendesapp/models/email.rbclass Email < ActiveRecord::Base attr_accessible :mensagem, :para validates_presence_of :paraend
  123. 123. @dudumendesrequire spec_helperdescribe 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 => "de@email.com") expect(email).to have(:no).error_on(:de) end it "para deve ser um email" endend
  124. 124. @dudumendes
  125. 125. @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 => "para@email.com") expect(email).to have(:no).error_on(:para) end it "para é inválido com email inválido" it "mensagem é obrigatória" endend
  126. 126. @dudumendes
  127. 127. require spec_helper @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 => "para@email.com") 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
  128. 128. @dudumendesclass 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
  129. 129. @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 => "para@email.com") 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
  130. 130. @dudumendesclass 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
  131. 131. @dudumendesBibliografia BEHAVIOUR-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.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×