Rinaldi Fonseca

Testes de aceitação com Ruby on Rails, Rspec e Capybara

21 de maio de 2011

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=test

Ao 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 »

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

Feed RSS dos comentários deste post URL de TrackBack

Deixe um comentário

Spam protection by WP Captcha-Free