Melhorando os testes dos seus models do Rails 3 com RSpec 2 e Remarkable ou Shoulda

Uma das coisas que mais me incomoda quando estou fazendo os meus testes,  é escrever testes para verificar os campos obrigatórios. Eu gosto muito de usar o RSpec e aqui está um exemplo comum de código que testa um modelo ‘Usuario’ que tem os atributos ‘nome’ e ‘idade’ obrigatórios:

describe Usuario do
  before :all do
    @obrigatorios = {nome: 'David Paniz', idade: 25}
  end

  it "deve ter Nome obrigatório" do
    u = Usuario.new(@obrigatorios.merge(nome: nil))
    u.should_not be_valid
    u.should have_at_least(1).error_on(:nome)
  end

  it "deve ter Idade obrigatório" do
    u = Usuario.new(@obrigatorios.merge(idade: nil))
    u.should_not be_valid
    u.should have_at_least(1).error_on(:idade)
  end

  it "Deve ser valido com todos os campos obrigatório" do
    u = Usuario.new(@obrigatorios)
    u.should be_valid
  end
end

Sempre que escrevo um código desses sinto que estou testando o Rails e não o meu model. No fundo a única coisa que tenho que testar é se eu coloquei a linha do validates_presence_of :atributo. O resto do trabalho (deixar o valid? falso e criar o error no campo) é problema do Rails e não do meu modelo. Além desse sensação estranha de testar a coisa errada esse é o tipo de código que eu escrevo e na hora percebo que a abordagem não é nada DRY.

Dei uma olhada em 2 opções para melhorar a abordagem dos testes, o Shoulda e o Remarkable.

Remarkable

Para instalar o remarkable com o Rails 3 o RSpec 2 precisamos usar a versão 4 que ainda está em alpha, nesse instante 4.0.0.alpha4.
Adicione ao seu Gemfile as dependências:

gem "rspec"
gem "rspec-rails"
gem "remarkable_activerecord", '4.0.0.alpha4'

Usando o Remakable você ganha alguns matcher especiais para verificar apenas se você realmente colocou a validação do atributo no seu model, por exemplo o matcher validate_presence_of. O código de teste equivalente ao de cima ficaria assim:

describe Usuario do
  it {should validate_presence_of :nome }
  it {should validate_presence_of :idade }
end

Para que o RSpec reconheça esses matchers do Remakable é preciso um último detalhe de configuração que é adicionar um require do remarkable no seu spec_helper.rb logo abaixo do require ‘rspec/rails’

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'remarkable/active_record'

Shoulda

O shoulda ficou muito famoso sendo utilizado com o TestUnit, mas existe um sub-projeto dele que é o ‘shoulda-matchers’, atualmente na versão 1.0.0.beta1, que é a gem que vamos usar com o Rails 3 o RSpec 2. Adicione ao seu Gemfile as dependências:

gem "rspec"
gem "rspec-rails"
gem "shoulda-matchers"

Curiosamente para esses casos mais básicos o matcher do Shoulda é idêntico ao do Remakable e o código de teste fica idêntico ao dele:

describe Usuario do
  it {should validate_presence_of :nome }
  it {should validate_presence_of :idade }
end

Dessa vez não é preciso nenhuma configuração extra, basta apenas executar os testes e:  Seja uma pessoa mais feliz!

Conclusão

Ambas são ótimas opções para dar uma bombada nos seus testes, cada um com suas vantagens e desvantagens. Recomendo uma lida nas respectivas documentações para conhecer mais de cada um deles e escolher o que melhor supre suas necessidades.

Posted in Ruby Tagged with: , , ,
3 comments on “Melhorando os testes dos seus models do Rails 3 com RSpec 2 e Remarkable ou Shoulda
  1. PotHix says:

    Æ!!

    Utilizei bastante o Remarkable, mas depois de migrar para o Rails 3 eu comecei a usar o Shoulda.
    Tive vários problemas com algumas macros do Remarkable no Rails 3, portanto decidi migrar e o shoulda atendeu bem o que eu precisava.

    Há blaços

  2. Ótimo post Paniz.
    Eu tenho usado RSpec2 com Shoulda em todos os projetos que participo, e tenho gostado bastante do resultado.

    Parabéns novamente pelo post.

  3. Adriano says:

    O Shoulda até um tempinho atrás deixava a suíte de testes beeeemm mais lenta.. acho que a razão era de 3x ou 4x mais. Confesso que não sei se continua assim, mas acredito que sim.

    []‘s

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>