Algumas Dicas Ao Usar Rails E Rspec

Antes de começar seria bom dar uma olhada nesse meu post

Esperando que você tenha lido o post do link acima, vamos fazer uma pequena modificação no arquivo gemfile, ficando agora assim:

1
2
3
4
5
group :development, :test do
  gem "rspec-rails", "~> 2.6"
  gem 'guard'
  gem 'guard-rspec'
end

Agora o porque de ter adicionado o :development, foi simplesmente para termos alguns benefícios do Rspec, onde ao criarmos um model, controller ou o próprio scaffold, também será gerado seus arquivos de teste.

Faça os seguintes comandos e veja as saídas:

rails g controller post index
rails g model post title:string body:text
rails g scaffold post title:string body:text

Se tudo ocorreu como o esperado você dete ter visto pelo menos esta saída:

invoke  active_record
create    db/migrate/20120327143756_create_posts.rb
create    app/models/post.rb
invoke    rspec
create      spec/models/post_spec.rb

Observe que foi criado um arquivo post_spec.rb dentro da pasta spec/models.

Pegando como exemplo somente o comando de criação do model, se executarmos o comando guard, devemos ter a seguinte saída:

Pending:
Post add some examples to (or delete) /home/rogerio/projetos/rspec_test/spec/models/post_spec.rb
    # No reason given
    # ./spec/models/post_spec.rb:4

Finished in 0.00026 seconds
1 example, 0 failures, 1 pending
Bye bye...

Acima ele diz que existe uma pendência, isto é claro, pois temos somente um arquivo base para criarmos nossos testes, então vamos colocar uma simples validação dentro do model post:

validate_presence_of :title

Essa validação diz que não é possivel cadastrar um post com título em branco, vamos fazer o teste para criar um Post.

1
2
3
4
5
6
describe Post do
  it "should be valid" do
      @post = Post.create(:title => "My first Post")
      @post.should be_valid
  end
end

Agora vamos preparar nosso banco de dados para executar o teste, abra o terminal e execute o comando:

rake db:migrate RAILS_ENV=test

Logo em seguida execute o comando guard, certamente nosso teste irá passar, vamos fazer a seguinte modificação na validação, de modo que irá quebrar nosso teste, adicione depois do campo title, o body, ficando assim:

validate_presence_of :title, :body

Agora nosso teste não esta passando, então vamos arrumar isso, ficando agora assim:

1
2
3
4
5
6
describe Post do
  it "should be valid" do
      @post = Post.create(:title => "My first Post", :body => 'Help me')
      @post.should be_valid
  end
end

Vamos adicionar um teste que verifica se o title esta nil:

1
2
3
4
5
6
7
8
9
describe Post do
  it "should be invalid without a title" do
      @post = Post.create(:title => nil, :body => "Help me")
      #@post.should be_invalid(:title) uma pequena correção aqui bem observada pelo
      #companheiro de trabalho Pedro Nascimento, be_invalid é usando com callbacks, o correto
      #é assim:
      @post.should_not be_valid
  end
end

E este é nosso arquivo final:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
describe Post do
  it "should be valid" do
      @post = Post.create(:title => "My first Post", :body => "Help me")
      @post.should be_valid
  end

  it "should be invalid without a title" do
      @post = Post.create(:title => nil, :body => "Help me")
      #@post.should be_invalid(:title) uma pequena correção aqui bem observada pelo
      #companheiro de trabalho Pedro Nascimento, be_invalid é usando com callbacks, o correto
      #é assim:
      @post.should_not be_valid
  end
end

Ficam as dicas:

Ao ver o before em um teste fique sabendo que ele contem condições que serão executadas antes do teste.

O it é sempre uma especificação, normalmente validando algo, que sempre esta associada a um describe.

O describe contem uma ou várias especificações, validando no final um determinado contexto.

Tente fazer seus teste sempre em inglês.

Faça primeiro os testes, depois code.

Além disso, poderiamos deixar o código mais dry usando o remarkable ou shoulda, que podemos integrar com o rspec, facilitando quando vamos fazer validação, um exemplo esta logo abaixo de como seria escrito o teste para validar o título do post:

it {should validate_presence_of :title }

Simples e fácil lol.

Comments