Testes de aceitação com Ruby on Rails, Rspec e Capybara
Por algum tempo utilizei a gem Steak para testes de aceitação em minhas aplicações Rails.
De forma resumida, podemos considerar o Steak como um facilitador para a integração do Rspec com o Capybara.
Porém a partir deste commit, a gem Capybara ganhou uma nova DSL que irá permitir a realização de testes de aceitação com Rspec sem depender do Steak.
Particularmente achei isso muito interessante. Será uma dependência a menos e as coisas estão ficando cada vez mais facilitadas.
Abaixo, vou listar alguns passos para utilizarmos esta nova funcionalidade do Capybara.
1) Crie uma nova aplicação Rails e configure seu Gemfile como o seguinte:
gem 'sqlite3' gem 'rspec-rails' gem 'capybara', '1.0.0.beta1' gem 'database_cleaner'
Obs: as versões anteriores a 1.0.0.beta1 do Capybara não possuem suporte a esta nova DSL
2) Rode o comando bundle install para instalar todas as dependências
3) Rode o comando rails g rspec:install para setar as configurações base do Rspec
4) Abra o arquivo spec/spec_helper.rb e sete o parâmetro use_transactional_fixtures para false, da seguinte forma:
config.use_transactional_fixtures = false
Esta configuração será necessária quando desejarmos rodar nossos testes com o driver de javascript
5) Crie o diretório spec/support e adicione o arquivo capybara.rb com o seguinte conteúdo:
require 'capybara/rails' require 'capybara/dsl' RSpec.configure do |c| c.include Capybara::DSL, :example_group => { :file_path => /\bspec\/acceptance\// } end
É com esta configuração que fazemos esta integração da nova DSL do Capybara com o Rspec. Ainda, estamos configurando que os nossos arquivos de testes de aceitação irão ficar em spec/acceptance.
6) Crie o arquivo spec/support/database_cleaner.rb com o seguinte arquivo:
require 'database_cleaner' RSpec.configure do |config| DatabaseCleaner.strategy = :truncation config.before :each do Capybara.reset_sessions! DatabaseCleaner.clean end end
Basicamente estamos usando a gem DatabaseCleaner para limpar a nossa base de dados a cada execução dos testes. Também estamos resetando as sessões do Capybara.
Neste ponto terminamos a fase de configuração. Agora já poderemos escrever nossos testes.
Vamos usar o nosso bom e velho exemplo de Blog, e criar o seguinte teste em: spec/acceptance/post_spec.rb
require 'spec_helper' feature "Post Blogs", %q{ In order to have an awesome blog As an author I want to create a post } do background do Post.create(:title => "My Post Title", :body => "My Body") end scenario "Post index", :js => true do visit posts_path page.should have_content('My Post Title') page.should have_content('My Body') end end
Basicamente estamos definindo nossa feature, e no bloco background estamos criando um Post antes da execução de cada teste.
No cenário Post index, estamos escrevendo algumas ações e poderíamos utilizar todos os métodos do Capybara para interagir com a página, como por exemplo fill_in, click_link etc.
Também estamos usando o “ :js => true” para que o nosso teste seja executado com o browser aberto. Isso será necessário quando precisarmos interagir com alguma funcionalidade que envolva javascript, ajax etc. Se seu teste não depende de javascript, recomendo não usar o :js => true, pois fará apenas que ele fique mais lento.
Por fim, estamos verificando se o post está presente na página.
É importante observar que a ideia, é apenas mostrar o que é possível de se fazer. Não estamos discutindo sobre a melhor maneira de testar esta tipo de funcionalidade(cadastro de post).
Obviamente, se rodarmos o teste agora ele irá falhar.
Agora, vamos implementar nosso código para que o teste passe, e um simples Scaffold resolverá a questão.
rails g scaffold Post title:string body:text
rake db:migrate RAILS_ENV=testAo rodarmos o teste com o comando:
rspec spec/acceptance/posts_spec.rb
O teste deverá passar.
Conclusão
Pensando no cenário em que a equipe não tem o cliente ajudando ou escrevendo histórias com Cucumber, acho muito válido escrever testes de aceitação com estas ferramentas. Ainda mas agora, que poderemos utilizar apenas Rspec e Capybara.
6 Comentários »
Feed RSS dos comentários deste post URL de TrackBack

Grande Rinaldi!
Sensacional o post! Estou fazendo testes de integração desta forma também e está funcionando muito bem!
Só pra acrescentar meus 2 cents: além do diretório ‘acceptance’, o rspec também entende os diretórios ‘integration’ e ‘request’… Estou usando o diretório ‘integration’
Grande abraço!
Comentário por Lucas Catón — 22 de maio de 2011 @ 16:26
Valeu pelo complemento Lucas!
Você tem razão. Inclusive vi um pessoal comentando sobre isso em uma thread do Github.
Abraços!
Comentário por Rinaldi Fonseca — 22 de maio de 2011 @ 16:31
Outra coisa!
Se eu não me engano, a partir da versão 3 do Rspec, não será mais aceito incluir algo no bloco do RSpec.configure, depois que ele já foi aberto uma vez, como você fez no capybara.rb!
Comentário por Lucas Catón — 22 de maio de 2011 @ 23:15
Então teremos que aguardar o David Chelimsky mostrar a versão alternativa do RSpec.configure do Rspec 3 =)
Comentário por Rinaldi Fonseca — 22 de maio de 2011 @ 23:26
Muito legal teu post!
Para testes de aceitação estou utilizando o Cucumber + Capybara. Tentei o Webrat, mas a integração dele com outros drivers (Selenium, por exemplo) era muito complicada. Acho importante que eles sejam “human readable”, mesmo que seja tão difícil de algum cliente/stakeholder ler.
Outra coisa, tu não consegue colocar uma @tag antes dos scenarios para identificar qual o driver que tu quer utilizar?
@selenium
scenario etc etc
Sei que no Cucumber funciona.
Comentário por Matias Leidemer — 21 de junho de 2011 @ 17:01
Olá,
Não testei, mas acredito que com @tag não seja possível. Apenas nas configurações.
Comentário por Rinaldi Fonseca — 29 de junho de 2011 @ 3:51