testando rails
apps com rspec
   nando vieira
sobre mim
• trabalho com web desde 1999
• desenvolvo com ruby desde 2006
• escrevo testes desde 2007
Ruby       JavaScript...
minhas urls
• http://simplesideias.com.br
• http://howtocode.com.br
• http://spesa.com.br
• http://twitter.com/fnando
• ht...
Por que testar?
Para verificar se o sistema se comporta
como deveria.
Como testar?
Testes manuais.
Testes automatizados.
Testes automatizados
Trazem mais confiança.
Identificam regressões no código.
Permitem refatorar com segurança.
Testar antes ou depois?
Tanto faz.
Testar depois
Exige mais disciplina.
O código é mais difícil de testar.
a.k.a Test Driven Development
Testar antes
O código é mais simples de testar.
Geralmente é mais bem escrito.
Behavior Driven Development
Então surgiu o BDD
Desenvolver aplicações descrevendo seu
comportamento do ponto de vista do c...
BDD não é sobre testar o
código.
É sobre o design e
documentação do código.
É sobre escrever software
que é realmente importante.
Frameworks
Sua linguagem preferida deve ter um
framework BDD.
JBehave, PHPSpec, GSpec, JSpec, specs,
NSpec...
No Ruby temos o RSpec.
David Chelimsky Spec e Story
RSpec é um framework
BDD para Ruby e Rails.


                       http://rspec.info
Descreva o comportamento
como em uma conversa.
Eu: descreva uma palestra
Vocês:
• ela deve ter um palestrante.
• ela deve ter um tempo definido.
• ela deve ser interessan...
describe "My Talk" do
  it "should be awesome" do
    true.should be_true
  end
end
Configuração
Ruby on Rails
Use como plugin.
script/plugin install git://github.com/dchelimsky/rspec.git
script/plugin install git://git...
Ruby on Rails
Use como gem.
gem install rspec
gem install rspec-rails
Ruby on Rails
Configure sua aplicação.
script/generate rspec
Ruby on Rails
Generators disponíveis.
script/generate
integration_spec, rspec, rspec_controller, rspec_model, rspec_scaffo...
O que testar?
Tudo o que você julgar importante ser
testado.
Como testar?
Teste uma coisa de cada vez.
Acostume-se com o workflow.
Red-Green-Refactor
Workflow
Red
Escreva um teste que falhe
Green
Escreva a funcionalidade
Refactor
Refatore o código que passou
Rails Checklist
• Models
• Controllers
• Helpers
• Views
• E-mails
• Rake tasks
• JavaScript
• ...
Model
script/generate rspec_model user role:string --skip-fixture

create app/models/user.rb
create spec/models/user_spec.r...
Model
spec/models/user_spec.rb
require 'spec_helper'

describe User do
  before(:each) do
    @valid_attributes = {

    }...
Exemplo
Verificar se um usuário é admin.
Escreva um teste que falhe
spec/models/user_spec.rb
describe User do
  it "should be an admin" do
    subject.role = "admi...
Execute a suíte de testes
$ rake spec:models
F

1) NoMethodError in 'User should be an admin'
undefined method `admin?' fo...
Faça o teste passar
app/models/user.rb

class User < ActiveRecord::Base
  def admin?
    true
  end
end
Execute a suíte de testes
$ rake spec:models

.

Finished in 0.087279 seconds

1 example, 0 failures
Adicione um teste negativo
spec/models/user_spec.rb

describe User do
  it "should be an admin" do
    subject.role = "adm...
Execute a suíte de testes
$ rake spec:models
.F

1)
'User should not be admin' FAILED
expected admin? to return false, got...
Faça o teste passar
app/models/user.rb

class User < ActiveRecord::Base
  def admin?
    role == "admin"
  end
end
Model
Coisas mais comuns
it "should be valid" do
  subject.should be_valid
end

it "should have errors" do
  subject.shoul...
Controller
script/generate rspec_controller users
create   spec/controllers/users_controller_spec.rb
create   spec/helpers...
Controller
spec/controllers/users_controller_spec.rb


describe UsersController do

  #Delete this example and add some re...
Exemplo
Criar um novo usuário.
class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def c...
Escreva um teste que falhe
spec/controllers/users_controller_spec.rb


describe UsersController do
  context "GET: new" do...
Execute a suíte de testes
$ rake spec:controllers

F

1) 'UsersController GET: new should instantiate user' FAILED
expecte...
Faça o teste passar
app/controllers/users_controller.rb


class UsersController < ApplicationController
  def new
    @use...
Execute a suíte de testes
$ rake spec:controllers

.

Finished in 0.119345 seconds

1 example, 0 failures
Escreva o próximo teste
spec/controllers/users_controller_spec.rb

describe UsersController do
  describe "POST: create" d...
Execute a suíte de testes
$ rake spec:controllers
F

1) Spec::Mocks::MockExpectationError in 'UsersController POST:
create...
Faça o teste passar
app/controllers/users_controller.rb


class UsersController < ApplicationController
  def create
    @...
Execute a suíte de testes
$ rake spec:controllers

..

Finished in 0.119345 seconds

2 example, 0 failures
Escreva o próximo teste
spec/controllers/users_controller_spec.rb

describe UsersController do
  describe "POST: create" d...
Execute a suíte de testes
$ rake spec:controllers

F

1) 'UsersController POST: create on success should redirect to
the s...
Faça o teste passar
app/controllers/users_controller.rb

class UsersController < ApplicationController
  def create
    @u...
Execute a suíte de testes
$ rake spec:controllers

.....F

Finished in 0.119345 seconds

5 examples, 1 failures
Escreva o próximo teste
spec/controllers/users_controller_spec.rb

describe UsersController do
  describe "POST: create" d...
Execute a suíte de testes
$ rake spec:controllers
F

1) 'UsersController POST: create on success should set success
messag...
Faça o teste passar
app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    @us...
Execute a suíte de testes
$ rake spec:controllers

.......

Finished in 0.119345 seconds

7 examples
Escreva o próximo teste
spec/controllers/users_controller_spec.rb

describe UsersController do
  describe "POST: create" d...
Helper
É gerado quando um controller é criado


describe UsersHelper do
  #Delete this example and add some real ones or d...
Exemplo
Exibir conteúdo para usuários admin.
<% content_for_admin(@user) do %>
    <!-- admin content -->
<% end %>
Escreva um teste que falhe
spec/helpers/users_helper_spec.rb


describe UsersHelper do
  describe "#content_for_admin" do
...
Execute a suíte de testes
$ rake spec:helpers
F

1) NoMethodError in 'UsersHelper#content_for_admin should display
content...
Faça o teste passar
app/helpers/users_helper.rb

module UsersHelper
  def content_for_admin(user, &block)
    yield if use...
Execute a suíte de testes
$ rake spec:helpers

.

Finished in 0.119345 seconds

1 example, 0 failures
Views
Teste a semântica e não o código gerado.
É difícil escrever testes antes do markup.
Utilize stubs & mocks!
Sem exemp...
Duas coisas que você deve
tirar desta palestra
Tente de verdade se acostumar ao workflow RED-
GREEN-REFACTOR.

Crie testes ...
Saiba mais sobre
RSpec http://rspec.info
Cucumber http://cukes.info
Factory Girl http://bit.ly/4EicvV
TATFT
dúvidas?
one more thing


    compra agora!
    http://howtocode.com.br
obrigado
nando@simplesideias.com.br
Upcoming SlideShare
Loading in …5
×

Testando Rails apps com RSpec

7,819 views

Published on

Minha apresentação no Ceará on Rails 2009

Published in: Technology
0 Comments
23 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
7,819
On SlideShare
0
From Embeds
0
Number of Embeds
663
Actions
Shares
0
Downloads
163
Comments
0
Likes
23
Embeds 0
No embeds

No notes for slide

Testando Rails apps com RSpec

  1. 1. testando rails apps com rspec nando vieira
  2. 2. sobre mim • trabalho com web desde 1999 • desenvolvo com ruby desde 2006 • escrevo testes desde 2007 Ruby JavaScript Objective-C PHP
  3. 3. minhas urls • http://simplesideias.com.br • http://howtocode.com.br • http://spesa.com.br • http://twitter.com/fnando • http://github.com/fnando
  4. 4. Por que testar? Para verificar se o sistema se comporta como deveria.
  5. 5. Como testar? Testes manuais. Testes automatizados.
  6. 6. Testes automatizados Trazem mais confiança. Identificam regressões no código. Permitem refatorar com segurança.
  7. 7. Testar antes ou depois? Tanto faz.
  8. 8. Testar depois Exige mais disciplina. O código é mais difícil de testar.
  9. 9. a.k.a Test Driven Development Testar antes O código é mais simples de testar. Geralmente é mais bem escrito.
  10. 10. Behavior Driven Development Então surgiu o BDD Desenvolver aplicações descrevendo seu comportamento do ponto de vista do cliente.
  11. 11. BDD não é sobre testar o código.
  12. 12. É sobre o design e documentação do código.
  13. 13. É sobre escrever software que é realmente importante.
  14. 14. Frameworks Sua linguagem preferida deve ter um framework BDD. JBehave, PHPSpec, GSpec, JSpec, specs, NSpec...
  15. 15. No Ruby temos o RSpec.
  16. 16. David Chelimsky Spec e Story RSpec é um framework BDD para Ruby e Rails. http://rspec.info
  17. 17. Descreva o comportamento como em uma conversa.
  18. 18. Eu: descreva uma palestra Vocês: • ela deve ter um palestrante. • ela deve ter um tempo definido. • ela deve ser interessante.
  19. 19. describe "My Talk" do it "should be awesome" do true.should be_true end end
  20. 20. Configuração
  21. 21. Ruby on Rails Use como plugin. script/plugin install git://github.com/dchelimsky/rspec.git script/plugin install git://github.com/dchelimsky/rspec-rails.git
  22. 22. Ruby on Rails Use como gem. gem install rspec gem install rspec-rails
  23. 23. Ruby on Rails Configure sua aplicação. script/generate rspec
  24. 24. Ruby on Rails Generators disponíveis. script/generate integration_spec, rspec, rspec_controller, rspec_model, rspec_scaffold
  25. 25. O que testar? Tudo o que você julgar importante ser testado.
  26. 26. Como testar? Teste uma coisa de cada vez. Acostume-se com o workflow.
  27. 27. Red-Green-Refactor Workflow
  28. 28. Red Escreva um teste que falhe
  29. 29. Green Escreva a funcionalidade
  30. 30. Refactor Refatore o código que passou
  31. 31. Rails Checklist • Models • Controllers • Helpers • Views • E-mails • Rake tasks • JavaScript • ...
  32. 32. Model script/generate rspec_model user role:string --skip-fixture create app/models/user.rb create spec/models/user_spec.rb create db/migrate/20091104135200_create_users.rb
  33. 33. Model spec/models/user_spec.rb require 'spec_helper' describe User do before(:each) do @valid_attributes = { } end it "should create a new instance given valid attributes" do User.create!(@valid_attributes) end end
  34. 34. Exemplo Verificar se um usuário é admin.
  35. 35. Escreva um teste que falhe spec/models/user_spec.rb describe User do it "should be an admin" do subject.role = "admin" subject.should be_admin end end
  36. 36. Execute a suíte de testes $ rake spec:models F 1) NoMethodError in 'User should be an admin' undefined method `admin?' for #<User id: nil, created_at: nil, updated_at: nil> active_record/attribute_methods.rb:255:in `method_missing' ./spec/models/user_spec.rb:5: Finished in 0.088512 seconds 1 example, 1 failure
  37. 37. Faça o teste passar app/models/user.rb class User < ActiveRecord::Base def admin? true end end
  38. 38. Execute a suíte de testes $ rake spec:models . Finished in 0.087279 seconds 1 example, 0 failures
  39. 39. Adicione um teste negativo spec/models/user_spec.rb describe User do it "should be an admin" do subject.role = "admin" subject.should be_admin end it "should not be admin" do subject.should_not be_admin end end
  40. 40. Execute a suíte de testes $ rake spec:models .F 1) 'User should not be admin' FAILED expected admin? to return false, got true ./spec/models/user_spec.rb:10: Finished in 0.098295 seconds 2 examples, 1 failure
  41. 41. Faça o teste passar app/models/user.rb class User < ActiveRecord::Base def admin? role == "admin" end end
  42. 42. Model Coisas mais comuns it "should be valid" do subject.should be_valid end it "should have errors" do subject.should have(1).error_on(:role) subject.should have(2).errors_on(:role) end it "should have no errors" do subject.should have(:no).error_on(:role) end it "should have records" do User.should have(1).record User.should have(2).records end
  43. 43. Controller script/generate rspec_controller users create spec/controllers/users_controller_spec.rb create spec/helpers/users_helper_spec.rb create app/controllers/users_controller.rb create app/helpers/users_helper.rb
  44. 44. Controller spec/controllers/users_controller_spec.rb describe UsersController do #Delete this example and add some real ones it "should use UsersController" do controller.should be_an_instance_of(UsersController) end end
  45. 45. Exemplo Criar um novo usuário. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = "A new user has been created!" redirect_to @user end end end
  46. 46. Escreva um teste que falhe spec/controllers/users_controller_spec.rb describe UsersController do context "GET: new" do it "should instantiate user" do assigns[:user].should be_a_kind_of(User) end end end
  47. 47. Execute a suíte de testes $ rake spec:controllers F 1) 'UsersController GET: new should instantiate user' FAILED expected nil to be a kind of User(id: integer, role: string, created_at: datetime, updated_at: datetime) Finished in 0.088512 seconds 1 example, 1 failure
  48. 48. Faça o teste passar app/controllers/users_controller.rb class UsersController < ApplicationController def new @user = User.new end end
  49. 49. Execute a suíte de testes $ rake spec:controllers . Finished in 0.119345 seconds 1 example, 0 failures
  50. 50. Escreva o próximo teste spec/controllers/users_controller_spec.rb describe UsersController do describe "POST: create" do context "on success" do it "should create user with provided arguments" do user = mock_model(User).as_null_object User.should_receive(:new).with("role" => "editor").and_return(user) post :create, :user => {:role => "editor"} end end end end
  51. 51. Execute a suíte de testes $ rake spec:controllers F 1) Spec::Mocks::MockExpectationError in 'UsersController POST: create on success should create user with provided arguments' <User(id: integer, role: string, created_at: datetime, updated_at: datetime) (class)> expected :new with ({"role"=>"editor"}) once, but received it 0 times Finished in 0.138342 seconds 4 examples, 3 failures
  52. 52. Faça o teste passar app/controllers/users_controller.rb class UsersController < ApplicationController def create @user = User.new(params[:user]) end end
  53. 53. Execute a suíte de testes $ rake spec:controllers .. Finished in 0.119345 seconds 2 example, 0 failures
  54. 54. Escreva o próximo teste spec/controllers/users_controller_spec.rb describe UsersController do describe "POST: create" do context "on success" do it "should redirect to the show page" do post :create, :user => {:role => "editor"} response.should redirect_to(user_url(assigns[:user])) end end end end
  55. 55. Execute a suíte de testes $ rake spec:controllers F 1) 'UsersController POST: create on success should redirect to the show page' FAILED expected redirect to "http://test.host/users/1", got no redirect Finished in 0.138342 seconds 4 examples, 2 failures
  56. 56. Faça o teste passar app/controllers/users_controller.rb class UsersController < ApplicationController def create @user = User.new(params[:user]) if @user.save redirect_to @user end end end
  57. 57. Execute a suíte de testes $ rake spec:controllers .....F Finished in 0.119345 seconds 5 examples, 1 failures
  58. 58. Escreva o próximo teste spec/controllers/users_controller_spec.rb describe UsersController do describe "POST: create" do context "on success" do it "should set success message" do post :create, :user => {:role => "editor"} flash[:notice].should == "A new user has been created!" end end end end
  59. 59. Execute a suíte de testes $ rake spec:controllers F 1) 'UsersController POST: create on success should set success message' FAILED expected: "A new user has been created!", got: nil (using ==) Finished in 0.138342 seconds 5 examples, 1 failure
  60. 60. Faça o teste passar app/controllers/users_controller.rb class UsersController < ApplicationController def create @user = User.new(params[:user]) if @user.save flash[:notice] = "A new user has been created!" redirect_to @user end end end
  61. 61. Execute a suíte de testes $ rake spec:controllers ....... Finished in 0.119345 seconds 7 examples
  62. 62. Escreva o próximo teste spec/controllers/users_controller_spec.rb describe UsersController do describe "POST: create" do context "on failure" do it "should not redirect" do user = mock_model(User) user.should_receive(:save).and_return(false) User.should_receive(:new).and_return(user) post :create response.should_not be_redirect end end end end
  63. 63. Helper É gerado quando um controller é criado describe UsersHelper do #Delete this example and add some real ones or delete this file it "should be included in the object returned by #helper" do included_modules = (class << helper; self; end).send :included_modules included_modules.should include(UsersHelper) end end
  64. 64. Exemplo Exibir conteúdo para usuários admin. <% content_for_admin(@user) do %> <!-- admin content --> <% end %>
  65. 65. Escreva um teste que falhe spec/helpers/users_helper_spec.rb describe UsersHelper do describe "#content_for_admin" do it "should display content for admins" do user = User.new(:role => "admin") content = helper.content_for_admin(user) { "content" } content.should == "content" end end end
  66. 66. Execute a suíte de testes $ rake spec:helpers F 1) NoMethodError in 'UsersHelper#content_for_admin should display content for admins' undefined method `content_for_admin' for #<Spec::Rails::Example::HelperExampleGroup::HelperObject: 0x1030c2138> Finished in 0.138342 seconds 1 example, 1 failure
  67. 67. Faça o teste passar app/helpers/users_helper.rb module UsersHelper def content_for_admin(user, &block) yield if user.admin? end end
  68. 68. Execute a suíte de testes $ rake spec:helpers . Finished in 0.119345 seconds 1 example, 0 failures
  69. 69. Views Teste a semântica e não o código gerado. É difícil escrever testes antes do markup. Utilize stubs & mocks! Sem exemplos!
  70. 70. Duas coisas que você deve tirar desta palestra Tente de verdade se acostumar ao workflow RED- GREEN-REFACTOR. Crie testes tão rápido quanto possível. Ou você não irá escrever testes.
  71. 71. Saiba mais sobre RSpec http://rspec.info Cucumber http://cukes.info Factory Girl http://bit.ly/4EicvV
  72. 72. TATFT
  73. 73. dúvidas?
  74. 74. one more thing compra agora! http://howtocode.com.br
  75. 75. obrigado nando@simplesideias.com.br

×