Desenvolvimento Guiado por Teste - TDD (Test-Driven Development)
Criado por Myriam Leggieri, @iammyr para Rails Girls Galway
Traduzido por Beatriz Rezener, @beatrizrezener
Os tutoriais básicos que foram mesclados e adaptados são: Tutorial Ruby on Rails, App RailsGirls e os tutoriais para criação de thumbnails, autenticando usuários, adicionando design, implantando com o OpenShift, adicionando comentários e tutorial do Mark McDonnell.
O Rails inclui um framework Test::Unit
padrão usado para testar seu código. Usaremos um framework de testes mais avançado, chamado RSpec
, para escrever um conjunto de testes. Precisamos ser capazes de escrever testes que sejam rápidos e que nos dê feedback intantâneo sobre os problemas com o nosso código.
Usaremos o Guard
e o RSpec
para monitorar alguns de nossos arquivos e executar testes sobre eles assim que eles forem modificados, para termos certeza de que as últimas mudanças não estão quebrando a aplicação.
Se algum erro for encontrado, então iremos nos aprofundar nele para entender a causa e consertá-lo, usando o Pry
.
Finalmente, dado que estamos assumindo que estamos desenvolvendo em colaboração com outros por meio do GitHub, também faremos com que cada contribuição não entre em conflito quando integrada com as demais. Por esse motivo, também realizaremos commits, push e testes de integração com frequência, em um processo chamado “Integração Contínua”. Usaremos a Travis-CI
para nos apoiar.
Teste contínuo com Guard
Em seu Gemfile
, adicione
e execute
para instalar as gems.
Então, crie um arquivo chamado Rakefile
em seu diretório principal do projeto e adicione
Quando você instala o RSpec
, ele dá acesso a uma tarefa construída em Rake
e é isso que estamos usando aqui. Nós criamos uma nova instância de RakeTask
que, por padrão, cria uma tarefa chamada spec
que procurará uma pasta chamada spec
e executará todos os arquivos de teste dentro dessa pasta, usando as opções de configuração que definimos (aqui cor e formato da saída de teste na linha de comando)
Nota: para executar os testes, basta digitar rake spec
na sua linha de comando. Você receberá zero falhas porque ainda não escrevemos qualquer teste ou qualquer código.
Agora, adicione o seguinte a um novo arquivo (no diretório principal do projeto) chamado Guardfile
:
O conteúdo deste arquivo diz ao Guard
o que fazer quando executamos o comando guard
.
Se executássemos guard rspec
, o Guard
observaria os arquivos especificados e executaria os comandos definidos assim que alguma alteração desses arquivos tivesse ocorrido. Nota: como nós só temos uma tarefa guard
, o rspec
, isso é executado por padrão se executarmos o comando guard
.
Neste caso, estamos dizendo ao Guard
que observe todos os arquivos dentro de nossas pastas app/views
e spec/features
e, se ocorrer alguma alteração em qualquer desses arquivos, então execute os arquivos de teste dentro da nossa pasta spec/features
para garantir que as mudanças que fizemos não quebraram nossos testes (e, consequentemente, não quebraram nosso código).
Agora, como é apropriado no Desenvolvimento Guiado por Teste (TDD), vamos criar um teste para a nossa página estática “Home”, antes mesmo de criá-la.
Nós vamos criar um arquivo intitulado home_spec.rb
e colocá-lo na pasta spec/feature
(a qual o Guard
está observando). O objetivo deste arquivo é tornar-se nosso arquivo de especificação (em outras palavras, este será o nosso código de teste e representará a funcionalidade esperada).
Nota: em Ruby, as palavras “teste” e “especificação” são muitas vezes consideradas intercambiáveis.
TDD: Escrevendo Código de Teste antes do Código da Aplicação
Normalmente, se você escreve o código da aplicação primeiro (então você não está fazendo o TDD), então você se encontrará escrevendo um código que, em algum momento do futuro, será desnecessariamente complicado e potencialmente obsoleto. Por meio do processo de refatoração ou alteração de requisitos, você poderá descobrir que algumas funções nunca serão chamadas.
É por isso que o TDD é considerado a melhor prática e o método de desenvolvimento favorito, porque cada linha de código que você produzirá foi produzida por um motivo: corrigir especificações (os requisitos do seu negócio) que estão falhando.
Vamos escrever o teste home.html.erb_spec.rb
como:
Para nos ajudar a reduzir o código clichê, o colocamos dentro de um arquivo especial auxiliar que vamos carregar nos nossos arquivos de especificação. Este arquivo será intitulado spec_helper.rb
.
Este arquivo irá fazer o seguinte:
- dizer ao Ruby onde o nosso código da aplicação principal está localizado
- carregar o código do nosso aplicativo (para que os testes sejam executados)
- carregar a gem
pry
(nos ajuda a depurar nosso código, se precisarmos).
Aqui está o código:
Vamos abrir uma nova linha de comando, insira guard
e deixe-o em execução: ele irá monitorar nossas páginas em app/views
e executar testes da spec/features
para elas. Se agora criarmos um arquivo vazio, o app/views/home.html.erb
o Guard
irá executar o teste e, sem supresa, o teste falhará.
O ponto de TDD é ter um loop de feedback estreito, também conhecido como ‘red, green, refactor’ (vermelho, verde, refatorar). Na prática, isso significa:
- escrever um teste que falha
- escrever o código mais simples possível para que ele passe
- refatorar o código
Então vamos criar nossa página estática “Home”. Criamos um PagesController
cujo objetivo é lidar com páginas estáticas (por exemplo, Home, About, Help). Cada página é representada por uma ação no controlador pages_controller.rb
.
Agora temos que dizer ao servidor que combine as requisições do navegador para cada página diferente de nossas ações:
Em seguida, criamos as páginas home.html.erb
, about.html.erb
e help.html.erb
em app/views/pages
. Esses arquivos contêm qualquer conteúdo que você deseja em suas páginas estáticas. Eles usarão, por padrão, o layout application.html.erb
do seu aplicativo.
Por enquanto, vamos deixá-los vazios e apenas adicionar o seguinte a home.html.erb
, para satisfazer nosso teste
Agora, se verificarmos a janela de linha de comando onde o guard
estava em execução, veremos que ele executou automaticamente nosso teste assim que salvamos as alterações em nosso arquivo home.html.erb
e que o teste agora está sendo bem-sucedido.
Nota: se quisermos executar manualmente os testes em vez de usar o Guard
, teríamos que executar rspec spec/features/home.html.erb_spec.rb
.
Depuração com Pry
Com o intuito de demonstrar o Pry, vamos adicionar mais código ao nosso controlador (este código extra não afeta nosso teste).
Um “break-point” é um lugar dentro do seu código onde a execução irá parar.
Você pode ter vários “break-points” definidos no seu código e você os cria usando binding.pry
(observe que foi incluído acima).
Quando você executar o seu código, você notará que o terminal irá parar e colocá-lo dentro do código do seu aplicativo no local exato em que o binding.pry
foi colocado.
A partir deste ponto, o Pry
tem acesso ao escopo local. Você pode digitar exit
para sair do Pry
e para o seu código continuar executando.
Nota: Você pode tentar encontrar onde você está, digitando: whereami
; Rastrear a pilha de execução: wtf
; Inspecionar os métodos e propriedades disponíveis: ls
; Mudar o Escopo: cd
.
Integração Contínua (CI) com Travis-CI
O princípio da IC é realizar “commit/push” o quanto antes e muitas vezes para evitar conflitos entre seu código e a “branch” principal. Quando você faz isso (neste caso, estamos realizando commits para o GitHub), é iniciada uma “build” no seu servidor CI, que executa os testes relevantes para garantir que tudo esteja funcionando como deve ser.
O Travis CI é um serviço de integração contínua hospedado para a comunidade de código aberto. Oferece serviços de CI gratuitos para projetos de código aberto e também tem um modelo pago para empresas. Usaremos o modelo de código aberto gratuito em nosso repositório GitHub.
O processo é o seguinte:
- Inscreva-se no Travis-CI usando sua conta GitHub
- Vá para a página “Accounts”
- Habilite o CI em todos os repositórios que deseja executá-lo
- Crie um arquivo
.travis.yml
dentro do diretório raiz do seu projeto e realize commit dele ao seu depósito GitHub
O arquivo .travis.yml
determina as configurações do Travis-CI para que ele saiba como gerenciar a execução dos testes em seu projeto. Vamos criá-lo da seguinte maneira:
Precisamos adicionar gem 'rake'
ao nosso Gemfile
dentro do grupo :test
, pois este é um requisito da Travis-CI.
O Travis-CI usa o RVM (Ruby Version Manager) para instalar versões do Ruby em seus servidores. Portanto, precisamos especificar as versões do Ruby para as quais queremos executar nossos testes.
Além disso, vamos adicionar a spec/spec_helper.rb
o seguinte:
e deixar claro no nosso Gemfile
quais gems são necessárias para teste e para o desenvolvimento:
Nota: se você tiver algum problema relacionado ao Travis-CI, pode participar do canal “#travis” no IRC freenode para obter ajuda para responder qualquer dúvida que você possa ter.
Outros Guias
- Handy cheatsheet for Ruby, Rails, console etc.
- Guia 1: Tutorial de Instalação para Rails Girls
- Guia 2: Tutorial para criação da app Rails Girls
- Guia 3: Como enviar para o GitHub
- Guia 4: Colocando seu app online em…
- Guia 5: Funcionalidades de uma área de comentários para a app Rails Girls
- Guia 6: Adicione design à sua aplicação com HTML e CSS
- Guia 7: Thumbnails em listas de ideas
- Guia 8: Autenticação (para usuários) com Devise
- Guia 9: Adicionando Gravatar para a aplicação
- Guia 10: Melhorando seu design da sua aplicação com HTML e CSS
- Guia 11: Continuous Deployment
- Guia 12: Construindo um aplicativo de votação em Sinatra
- Guia 13: Construa um diário em Ruby on Rails
- Guia 14: Adicione back-end ao seu aplicativo (páginas de administração)
- Guia 15: Acesse explicações adicionais do app Rails Girls