© Casa do Código
Todos os direitos reservados e protegidos pela Lei nº9.610, de 10/02/1998.
Nenhuma parte deste livro poderá ser reproduzida, nem transmitida, sem autorização prévia por escrito da editora, sejam quais forem os meios: fotográficos,
eletrônicos, mecânicos, gravação ou quaisquer outros.
Casa do Código
Livros para o programador
Rua Vergueiro, 3185 - 8º andar
04101-300 – Vila Mariana – São Paulo – SP – Brasil
Casa do Código
Dedicatória
Dedico este livro a duas pessoas: minha mãe e minha noiva.
Sem o trabalho árduo e constante suporte da minha mãe, eu não estaria aqui
hoje, escrevendo um livro. Ela é minha heroína e a pessoa mais batalhadora que já
conheci. Obrigado Lilian Pessoa por me dar as oportunidades que tive na vida.
Escrever um livro é uma empreitada bem mais trabalhosa que eu pensei. Centenas de horas de trabalho. Essas horas não foram um investimento apenas meu, foi
também da minha noiva. Vários meses sem ter um �nal de semana tranquilo para
passar ao lado dela. Obrigado Ana Raquel por segurar essa barra e por me apoiar até
a última palavra deste livro.
i
Casa do Código
Agradecimentos
Primeiro eu gostaria de agradecer ao Adriano Almeida, da Casa do Código, pelo
convite para escrever este livro. Sem esse primeiro empurrão é muito improvável
que esse livro existiria. Escrevê-lo foi não só um excelente desa�o mas também uma
grande oportunidade de aprendizado.
Gostaria de agradecer também à Plataformatec e a todo mundo que trabalha
comigo lá. São os melhores pro�ssionais com quem eu já trabalhei e me inspiram
todo dia a ser um pro�ssional melhor.
Não posso deixar também de agradecer a minha família e amigos como um todo.
Ao fazer este livro, tive que abdicar de passar inúmeras horas com eles, decisão que
não foi fácil de tomar e muito menos de manter.
Por �m, gostaria de agradecer às pessoas que investiram seu tempo revisando as
primeiras versões deste livro. Eles não tinham nenhuma obrigação de fazê-lo, �zeram pela boa vontade, amizade, por serem colaborativos e pela vontade de aprender
algo novo. São eles: Bernardo Chaves, Erich Kist, Danilo Inacio e Anna Cruz.
iii
Casa do Código
Sobre o autor
Hugo Baraúna é cofundador e sócio da Plataformatec, empresa de consultoria em
desenvolvimento de so�ware especializada em Ruby e Rails.
A Plataformatec é referência nacional e internacional no mundo Ruby, devido
principalmente a seus projetos open source e sua colaboração com a comunidade.
Ele atua tanto na direção da empresa quanto como desenvolvedor, tendo participado
de projetos de consultoria, coaching e desenvolvimento para startups e empresas da
Fortune ����.
Hugo se formou em Engenharia de Computação pela Politécnica da USP. Durante a faculdade, passou pelo laboratório USP-Microso� e por empresas como
Procwork e IBM.
Para ele, só é possível fazer produtos e serviços de qualidade quando se ama o
que faz.
v
Casa do Código
Apresentação
Abordagem do livro
Este livro não é um manual do Cucumber e de RSpec. Já existem diversos lugares
listando as funcionalidades, classes e métodos do Cucumber e RSpec. Portanto, o
objetivo não é repetir o que já existe pronto em vários outros lugares.
A abordagem deste livro é apresentar como usar essas ferramentas, em vez de
mostrar todos os detalhes de cada uma delas. Saber o que as ferramentas oferecem é
diferente de saber como usá-las. Além da mostra do uso básico, várias boas práticas
não documentadas previamente também são apresentadas, utilizando exemplos ao
longo do livro inteiro.
Estrutura do livro
Este livro está estruturado em quatro partes:
�) A primeira consiste em uma introdução ao conceito e histórico do TDD e BDD,
assim como um primeiro contato com o RSpec e com o Cucumber. Ela é formada
pelos capítulos � e �;
�) A segunda é uma apresentação geral do RSpec. Passando pela estrutura básica de
um teste de unidade feito com ele, pela organização de testes e pelo uso de test
doubles como mocks e stubs. Ela é formada pelos capítulos � a �;
�) A terceira parte consiste em uma apresentação do Cucumber e de como usá-lo
para escrever especi�cações executáveis. Ela é formada pelos capítulos � a �;
�) Por �m, na quarta e última parte, nós construiremos uma aplicação do zero seguindo o conceito de outside-in development do BDD, utilizando RSpec e Cucumber. Ela é formada pelos capítulos �� a ��.
vii
Casa do Código
Para quem é este livro?
Estou aprendendo ou já sei programar em Ruby mas nunca �z TDD
Se você se enquadra no caso acima, este livro é perfeito para você. Você irá aprender como fazer testes automatizados e seguir o �uxo de TDD e BDD para fazer um
código mais fácil de ser mantido e com mais qualidade.
Aprender uma habilidade nova não é simples, mas pode ser mais e�ciente com a
ajuda de uma apresentação estruturada e de um caminho de�nido. Este livro mostra
passo a passo como usar o RSpec e o Cucumber para construir uma aplicação inteira
seguindo o �uxo de TDD/BDD.
Já faço testes automatizados mas não sei se estou fazendo do jeito certo
Existem diversos fatores que in�uenciam o desenvolvimento de bons testes. O
que testar? Como testar? Em qual camada testar? Por onde começo?
Fazer testes do jeito certo não é apenas ter cobertura de testes em ����. Por
exemplo, a maioria das pessoas não sabem que em um teste a clareza é muito mais
importante do que o DRY (don’t repeat yourself ). A maioria das pessoas não sabem
a diferença entre mocks e stubs e quando usar um ao invés do outro.
Este livro responde todas as dúvidas acima e mais várias outras, que o ajudarão
a estruturar seu conhecimento em testes automatizados e a escrever testes de qualidade.
Já �z testes de unidade, mas não conheço Cucumber, nem o conceito de especi�cação executável
Testes de unidade são uma parte muito importante na prática de TDD, mas existem outras camadas de teste, tal como a camada de testes de aceitação. Este livro
mostra o que são testes de aceitação e como fazê-los utilizando Cucumber.
Na explicação do uso de Cucumber, este livro vai além dos testes de aceitação. O
Cucumber é, na verdade, uma ferramenta de documentação, que une especi�cação
e testes automatizados, formando o que conhecemos por “especi�cação executável”.
Este livro mostra como usar o Cucumber do modo certo, quando vale a pena
usá-lo e como usá-lo em conjunto com o RSpec para fechar o ciclo de outside-in
development.
O que preciso ter instalado?
Ao longo do livro veremos vários exemplos de código, e na última parte construiremos um projeto de � a ���. Para ir desenvolvendo o código junto com o livro,
você precisará de algumas coisas instaladas.
viii
Casa do Código
Você precisará ter instalado o Ruby �.� ou �.�. Qualquer uma das duas versões
deve funcionar, mas dê preferência para a �.�.
Além do Ruby, será necessário instalar o Bundler, RSpec e Cucumber. A versão
do Bundler utilizada é a �.�.�. A versão do Cucumber é a �.�.��. As versões do RSpec
e de seus componentes usadas são:
• rspec: �.��.�
• rspec-core: �.��.�
• rspec-expectations: �.��.�
• rspec-mocks: �.��.�
Sobre o sistema operacional, você pode usar o Mac OS X, o Linux ou Windows.
Dito isso, historicamente o Ruby funciona melhor no Linux e no Mac OS X do que no
Windows. Portanto, se você for usuário de Windows e quiser programar em Ruby,
uma boa opção é usar uma máquina virtual rodando Linux.
Um último detalhe sobre o sistema operacional, ao longo do livro alguns comandos de shell Unix-like são usados, tal como o mkdir para criar diretório, o cd para
entrar em um diretório e o touch para criar um arquivo. Apesar de serem usados comandos de um shell Unix-like, a intenção de cada comando será explicada ao
longo do livro, de modo que você possa saber o que deve ser feito, caso não esteja
usando um shell Unix-like, como no Windows.
Você tem dúvidas ou achou algum erro no livro?
Este livro possui um grupo de discussão de email com o seguinte endereço:
[email protected].
Se você tiver dúvidas sobre o conteúdo do livro ou algo relacionado, você pode
enviar um e-mail para o endereço acima.
Caso você ache algum possível erro no livro, por favor o envie nessa lista de
discussão.
Por �m, se você tiver alguma dúvida sobre o código desenvolvido na quarta parte
deste livro, a parte do projeto, você pode veri�car um repositório no Github com o
código �nal como referência: https://github.com/hugobarauna/forca.
ix
Casa do Código
Sumário
Sumário
�
�
�
Visão geral sobre TDD
�
�.�
TDD e sua história . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
�
�.�
E por qual motivo eu deveria usar TDD? . . . . . . . . . . . . . . . . .
�
Primeiros passos com RSpec e Cucumber
�
�.�
Olá RSpec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
�
�.�
Olá Cucumber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
��
�.�
O que é BDD? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ��
Introdução ao básico do RSpec
��
�.�
Aprendendo a estrutura básica de um teste com RSpec . . . . . . . . . ��
�.�
Por que existem tantos matchers no RSpec . . . . . . . . . . . . . . . . ��
�.�
Conhecendo os RSpec built-in matchers . . . . . . . . . . . . . . . . . ��
�.�
Custom matchers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Entendendo o protocolo interno de matcher do RSpec . . . . . . . . . ��
�.�
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . ��
� Organização, refatoração e reuso de testes com o RSpec
��
�.�
Reduzindo duplicação com hooks do RSpec . . . . . . . . . . . . . . . ��
�.�
DRY versus clareza nos testes . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
A�er hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Around hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Organizando seus testes . . . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Reuso de testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . ��
xi
Casa do Código
Sumário
�
Mocks e stubs
�.�
Por que preciso de mocks? . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Conhecendo o conceito de test doubles . . . . . . . . . . . . . . . . . . ��
�.�
Usando stubs com RSpec . . . . . . . . . . . . . . . . . . . . . . . . . . ��
�.�
Escrevendo mock expectations com RSpec . . . . . . . . . . . . . . . . ���
�.�
Quando usar mock e quando usar stub . . . . . . . . . . . . . . . . . . ���
�.�
Usando o método double para fazer testes isolados . . . . . . . . . . . ���
�.�
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . ���
� Conhecendo o Cucumber
�
�
xii
��
���
�.�
Por que usar cucumber? . . . . . . . . . . . . . . . . . . . . . . . . . . ���
�.�
Cucumber como estímulo de conversa sobre os requisitos . . . . . . . ���
�.�
Cucumber: especi�cação e testes juntos! . . . . . . . . . . . . . . . . . ���
�.�
Cucumber para construir uma documentação viva . . . . . . . . . . . ���
�.�
Visão geral de cucumber . . . . . . . . . . . . . . . . . . . . . . . . . . ���
�.�
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . ���
Especi�cando funcionalidades com Cucumber
���
�.�
Instalando e fazendo setup do Cucumber . . . . . . . . . . . . . . . . ���
�.�
Estrutura de uma feature com cucumber . . . . . . . . . . . . . . . . . ���
�.�
Escrevendo um cenário . . . . . . . . . . . . . . . . . . . . . . . . . . . ���
�.�
Escrevendo cenários expressivos com Cucumber . . . . . . . . . . . . ���
�.�
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . ���
Automatizando especi�cações com cucumber
���
�.�
Escrevendo os primeiros step de�nitions . . . . . . . . . . . . . . . . . ���
�.�
Escrevendo step de�nitions para cenários expressivos . . . . . . . . . ���
�.�
Support code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ���
�.�
Cucumber World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ���
�.�
Usando Cucumber hooks . . . . . . . . . . . . . . . . . . . . . . . . . . ���
�.�
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . ���
Casa do Código
Sumário
� Boas práticas no uso de Cucumber
�.� Use e abuse das descrições da funcionalidade e dos cenários
�.� Evite detalhes desnecessários . . . . . . . . . . . . . . . . . . .
�.� Cenários imperativos VS cenários declarativos . . . . . . . .
�.� Organizando os arquivos da minha especi�cação executável
�.� Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
���
���
���
���
���
���
.
.
.
.
.
.
���
���
���
���
���
���
���
.
.
.
.
.
.
.
.
.
���
���
���
���
���
���
���
���
���
���
�� Finalizando a primeira funcionalidade
��.� Deixando o segundo cenário no verde . . . . . . . . . . . . . . . . . .
��.� Finalizando a primeira funcionalidade . . . . . . . . . . . . . . . . . .
��.� Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . .
���
���
���
���
�� BDD na prática, começando um projeto com BDD
��.� De�nindo o escopo da nossa aplicação: Jogo da Forca
��.� Especi�cando uma funcionalidade com Cucumber . .
��.� Usando RSpec no nosso primeiro teste . . . . . . . . .
��.� Usando Aruba para testar uma aplicação CLI . . . . .
��.� Reutilizando step de�nitions de um modo melhor . .
��.� Pontos-chave deste capítulo . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
�� Começando o segundo cenário
��.� De�nindo o segundo cenário . . . . . . . . . . . . . . . . . . . . . .
��.� Reduza duplicação através de support code . . . . . . . . . . . . .
��.� Implementando o �uxo do jogo no binário . . . . . . . . . . . . . .
��.� Modi�cando nosso cenário para receber o feedback correto . . . .
��.� Usando subject e let do RSpec para evitar duplicação nos testes . .
��.� Refatorando o código para poder implementar o segundo cenário
��.� Extraindo uma classe através de refatoração . . . . . . . . . . . . .
��.� Possibilitando ao jogador terminar o jogo no meio . . . . . . . . .
��.� Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . .
�� Refatorando nosso código
��.� Identi�cado os pontos a serem refatorados . . . . .
��.� Extraindo uma classe de um método privado . . .
��.� Distribuindo responsabilidades para outras classes
��.� Pontos-chave deste capítulo . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
���
. ���
. ���
. ���
. ���
xiii
Casa do Código
Sumário
�� Especi�cando a segunda funcionalidade
��.� Documentando especi�cação e critério de aceite com Cucumber
��.� De�nindo o teste de aceitação do primeiro cenário . . . . . . . .
��.� Melhore a testabilidade do seu so�ware . . . . . . . . . . . . . . .
��.� Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . .
�� Finalizando a segunda funcionalidade
��.� Refatorando nosso jogo para ter uma máquina de estados . .
��.� Refatorando o �uxo do jogo para usar a máquina de estados
��.� Organizando seus testes otimizando para leitura . . . . . . .
��.� Interface discovery utilizando test doubles . . . . . . . . . . .
��.� Finalizando a funcionalidade Adivinhar letra . . . . . . . . .
��.� Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . .
�� Finalizando nosso jogo
��.� Especi�cando o �m do jogo
��.� Jogador vence o jogo . . . .
��.� Jogador perde o jogo . . . .
��.� Próximos passos . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Bibliogra�a
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
���
���
���
���
���
���
���
.
.
.
.
���
���
���
���
���
���
Versão: ��.�.��
xiv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
���
���
���
���
���
Download

Dedicatória