Introducão ao BDD com Cucumber, RSpec, Webrat e Selenium - Parte III

Seguindo com a série de posts iniciada aqui e aqui, trataremos agora da implementação dos passos especificados no nosso Cenário.

Antes de tudo é bom entender o que é o tal Test Driven Development, de onde vieram boa parte das idéias por trás do BDD.

Test Driven Development prega o desenvolvimento através de pequenas iterações onde existe primeiro a escrita de casos testes que definem o que precisa ser implementado e depois a produção de código necessário para que estes casos de testes sejam atendidos. Não vou explicar pq TDD é legal, uma busca rápida no google vai lhe dar muitos argumentos.

O BDD evolui a idéia do TDD no sentido que começamos o desenvolvimento do sistema com foco no comportamento esperado pelo cliente e expressamos esse comportamento através de uma linguagem mais adequada e mais próxima da natural. Isso ajuda bastante ao discutirmos requisitos com o cliente e no próprio entendimento pela equipe: nossa documentação é nosso código.

Quando construímos nossa User Story e fizemos o Cucumber rodá-la, mesmo com tudo pendente, fizemos isso para guiar nosso desenvolvimento olhando de fora para dentro: o que nosso cliente e espera (User Story), como ele espera (AcceptanceCriterias).

A partir de agora criaremos código para atender as essas expectativas e somente isso.

Por enquanto todos os nossos passos contidos no arquivo features/step_definitions/gerenciar_pessoas_steps.rb estão marcados como pendentes através do método pending

Comecemos então pelo primeiro passo:

Dado que estou na listagem de pessoas

A primeiro momento poderíamos implementar esse passo de forma específica no arquivo features/step_definitions/gerenciar_pessoas_steps.rb

Mas vamos a uma reflexão: geralmente iniciamos os cenários partindo de um determinado ponto do sistema, seria muito interessante definir esse passo de forma genérica, assim poderíamos escrever novos cenários com passos similares, por exemplo:

Dado que eu estou em listagem de cidades

sem a necessidade de implementar um novo passo. Para isso iremos mover o pedaço de código relativo ao passo acima para um novo arquivo features/step_definitions/passos_compartilhados.rb e nele iremos generalizar o passo parametrizando-o

Onde visit é um método do webrat para “visitar” a página especificada e path_to é um helper do Cucumber para definirmos rotas em nossos passos.

Executemos o cucumber novamente:

cucumber features –language pt

Na saída do comando verificamos que não foi possível encontrar um mapeamento para “listagem de pessoas”. Faremos esse mapeamento no arquivo features/support/paths.rb

Vamos executar o cucumber novamente e verificar a saída:

Agora temos outro relato: não existe o método pessoas_path por simplesmente ainda não termos um Controller chamado pessoas. O próximo passo de bebê seria adicionar um controller para pessoas e definir a rota. De toda forma como esse é um simples crud criaremos logo um scaffold através do gerador do rspec, executamos a migration de criação da tabela de passoas e preparamos o banco de teste:

script/generate rspec_scaffold pessoa nome:string endereco:string email:string rake db:migrate rake db:test:prepare

Executamos novamente o cucumber e agora temos o primeiro passo “verde” :D

Temos um outro passo pendente que também pode (e deve) ser generalizado, tiramos o seguinte trecho de código do arquivo features/step_definitions/gerenciar_pessoas_steps.rb e o levamos para features/step_definitions/passos_compartilhados.rb

e o alteramos para

Executamos novamente o cucumber

Precisamos agora de um link chamado “Nova pessoa” na nossa listagem. O script de geração de scaffold já gerou um link só que com o nome em inglês: “New pessoa”. Vamos no arquivo app/views/pessoas/index.html.erb e renomeamos:

<%= link_to ‘Nova pessoa’, new_pessoa_path %>

para

<%= link_to ‘Nova pessoa’, new_pessoa_path %>

Rodando o cucumber mais uma vez:
O negócio tá melhorando, já temos 2 passos “verdes”, partimos agora para os próximos passos:

E defino nome com o valor “Fulano de Tal”
E defino endereco com o valor “Rua Sicrano, 32″
E defino email com o valor “fulano@exemplo.com.br”

Como vocês podem ver, os três passos tem a mesma estrutura, vamos generalizá-lo também. Remova o seguinte trecho de código do arquivo features/step_definitions/gerenciar_pessoas_steps.rb

e adicione o código abaixo no features/step_definitions/passos_compartilhados_steps.rb

Ao ver o saida do cucumber uma alegria: só faltam dois passos!

Salvar o registro é um passo que pode existir em vários cenários, não é algo específico deste. Moveremos então o trecho de código abaixo de features/step_definitions/gerenciar_pessoas_steps.rb para features/step_definitions/passos_compartilhados.rb

E o alteramos para:

Rodamos o cucumber novamente
Percebemos a necessidade de alterar a descrição do botão no arquivo app/views/pessoas/new.html.erb

<%= f.submit ‘Create’ %>

para

<%= f.submit ‘Salvar’ %>

Agora sim, estamos quase lá:
Esvaziamos agora o arquivo features/step_definitions/gerenciar_pessoas_steps.rb pois o último passo também é algo genérico, pode ser aproveitado em outros cenários e funcionalidades. No futuro talvez adicionemos um passo específico da funcionalidade a medida que alteramos nossa User Story. Movemos a definição do último passo para features/step_definitions/passos_compartilhados.rb

Ao rodar o cucumber novamente vemos a necessidade de mudar a mensagem de retorno do método create do nosso controller

Fazemos isso:

Finalizamos assim a implementação da funcionalidade.

Talvez você tenha achado um tanto chato fazer passo por passo código que poderia ser previsto, mas a idéia em TDD é justamente essa: passos de bebê.

No próximo post trataremos da utilização do webrat em modo selenium.

Críticas e comentários são bem-vindos! Até mais! :D

7 Responses to “Introducão ao BDD com Cucumber, RSpec, Webrat e Selenium - Parte III”

  1. Arnaldo Says:

    Parabéns pelo tutorial Jefferson. Está mto bacana.
    É ótimo para começarmos a brincar com o cucumber.
    Dá um tok na lista qdo tiver novos post’s.
    []’s

  2. Maurício Linhares Says:

    Ótimo material rapaz :D

    Só falta botar um design expansivo no blog pra o código fonte aparecer normalmente, tá um cabaré aqui pra mim no Firefox XD

  3. edipo Says:

    Ola, muito legal os posts, um duvida, ali na parte de “defino …” eu estou tentando aqui, mas ele sempre dizia que nao conseguia encontrar o campo, tipo que fazer uma gambiarra para isso:

    Dado /^defino(.+) com o valor “([^\"]*)”$/ do |atributo,valor|
    atributo = atributo.gsub(/\s/, ”)
    fill_in “user_” + atributo, :with => valor
    end

    mas ai tira toda a flexibilidade do teste.. acredito que eh algo ali no gsub que eu tenha que mudar algo pois meus campos ficam assim user_login por exemplo..

  4. Jefferson Girão Says:

    Olá Édipo, se existe label você não precisa procurar pelo atributo através de seu id. Você pode procurar por exemplo pelo label “Usuário” se ele possuir o atributo “for” apontando para o seu user_login. Conseguiu entender?

    Pode definir o passo assim:

    defino Usuário com o valor “teste”

    sendo que você possui um

    Inclusive fica mais claro para o usuário comum entender a feature.

  5. NELSON Says:


    Pillspot.org. Canadian Health&Care.Best quality drugs.No prescription online pharmacy.Special Internet Prices. No prescription drugs. Buy pills online

    Buy:Prednisolone.Arimidex.Mega Hoodia.Human Growth Hormone.Zovirax.Zyban.100% Pure Okinawan Coral Calcium.Accutane.Lumigan.Actos.Petcam (Metacam) Oral Suspension.Valtrex.Prevacid.Retin-A.Nexium.Synthroid….

  6. DOUG Says:


    Medicamentspot.com. Canadian Health&Care.No prescription online pharmacy.Special Internet Prices.Best quality drugs. High quality pills. Buy drugs online

    Buy:Soma.Viagra Professional.Maxaman.Tramadol.Cialis.Cialis Soft Tabs.Viagra Super Force.Super Active ED Pack.Viagra Super Active+.Cialis Super Active+.Viagra.Zithromax.Cialis Professional.Propecia.Levitra.VPXL.Viagra Soft Tabs….

  7. 4001 Says:

    4 http://bergonimicd-e3.bestpartsstore.info/tag/Stealth+Roller+Coaster+4001+4/ : 4…

    Coaster…

Leave a Reply