Casa do Código
Dedicatória
Dedico a minha mãe e minha noiva.
i
Casa do Código
Agradecimentos
Agradeço a minha mãe, minha noiva, amigos e Plataformatec.
iii
Casa do Código
Sobre o autor
Hugo Baraúna é co-fundador da Plataformatec, empresa de consultoria em desenvol-
vimento de software especializada em Ruby e Rails. A Plataformatec é referência na-
cional 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 testes de carga.
Hugo se formou em Engenharia de Computação pela Politécnica da USP em
2010. Durante a faculdade, passou pelo laboratório USP-Microsoft 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
Prefácio
vii
Casa do Código
Sumário
Sumário
1
Visão geral sobre TDD
1
1.1
TDD e sua história . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.2
E por qual motivo eu deveria usar TDD? . . . . . . . . . . . . . . . . .
3
2
Primeiros passos com RSpec e Cucumber
5
2.1
Olá RSpec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2
Olá Cucumber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.3
O que é BDD? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
3
Introdução ao básico do RSpec
23
3.1
Aprendendo a estrutura básica de um teste com RSpec . . . . . . . . .
23
3.2
Porquê existem tantos matchers no RSpec . . . . . . . . . . . . . . . . 26
3.3
Conhecendo os RSpec built-in matchers . . . . . . . . . . . . . . . . .
33
3.4
Matchers relacionados a truthy e falsy
. . . . . . . . . . . . . . . . . .
33
3.5
Os matchers de equidade . . . . . . . . . . . . . . . . . . . . . . . . . .
34
3.6
Matchers relacionados a arrays . . . . . . . . . . . . . . . . . . . . . . .
35
3.7
Custom matchers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.8
Entendendo o protocolo interno de matcher do RSpec . . . . . . . . .
53
3.9
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . .
56
4
Organização, refatoração e reuso de testes com o RSpec
59
4.1
Reduzindo duplicação com hooks do RSpec . . . . . . . . . . . . . . .
59
4.2
DRY versus clareza nos testes
. . . . . . . . . . . . . . . . . . . . . . .
65
4.3
After hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.4
Around hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
ix
Sumário
Casa do Código
4.5
Organizando seus testes . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.6
Reuso de testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.7
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . 86
5
TDD na prática, começando um projeto com TDD
87
5.1
Definindo o escopo da nossa aplicação: Jogo da Forca . . . . . . . . . 88
5.2
Especificando uma funcionalidade com Cucumber . . . . . . . . . . . 89
5.3
Usando RSpec no nosso primeiro teste . . . . . . . . . . . . . . . . . . 94
5.4
Usando Aruba para testar uma aplicação CLI . . . . . . . . . . . . . . 99
5.5
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . 104
6
Começando o segundo cenário
107
6.1
Definindo o segundo cenário . . . . . . . . . . . . . . . . . . . . . . . . 107
6.2
Reduza duplicação através de support code . . . . . . . . . . . . . . . 108
6.3
Implementando o fluxo do jogo no binário . . . . . . . . . . . . . . . . 110
6.4
Modificando nosso cenário para receber
o feedback correto . . . . . . 113
6.5
Usando subject e let do RSpec para evitar duplicação nos testes . . . . 116
6.6
Refatorando o código para poder implementar o segundo cenário . . 119
6.7
Extraindo uma classe através de refatoração . . . . . . . . . . . . . . . 123
6.8
Possibilitando ao jogador terminar o jogo no meio . . . . . . . . . . . 127
6.9
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . 129
7
Finalizando a primeira funcionalidade
131
7.1
Continuando o segundo cenário . . . . . . . . . . . . . . . . . . . . . . 131
7.2
Deixando o segundo cenário no verde . . . . . . . . . . . . . . . . . . 132
7.3
Finalizando a primeira funcionalidade . . . . . . . . . . . . . . . . . . 139
7.4
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . 142
8
Refatorando nosso código
143
8.1
Identificado os pontos a serem refatorados . . . . . . . . . . . . . . . . 143
8.2
Extraindo uma classe de um método privado . . . . . . . . . . . . . . 146
8.3
Distribuindo responsabilidades para outras classes . . . . . . . . . . . 153
8.4
Pontos-chave deste capítulo . . . . . . . . . . . . . . . . . . . . . . . . 167
x
Casa do Código
Sumário
9
Especificando a segunda funcionalidade
169
9.1
Documentando especificação e critério de aceite com Cucumber . . . 169