Testando Rails apps com RSpec

  • 6,687 views
Uploaded on

Minha apresentação no Ceará on Rails 2009

Minha apresentação no Ceará on Rails 2009

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
6,687
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
153
Comments
0
Likes
19

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. testando rails apps com rspec nando vieira
  • 2. sobre mim • trabalho com web desde 1999 • desenvolvo com ruby desde 2006 • escrevo testes desde 2007 Ruby JavaScript Objective-C PHP
  • 3. minhas urls • http://simplesideias.com.br • http://howtocode.com.br • http://spesa.com.br • http://twitter.com/fnando • http://github.com/fnando
  • 4. Por que testar? Para verificar se o sistema se comporta como deveria.
  • 5. Como testar? Testes manuais. Testes automatizados.
  • 6. Testes automatizados Trazem mais confiança. Identificam regressões no código. Permitem refatorar com segurança.
  • 7. Testar antes ou depois? Tanto faz.
  • 8. Testar depois Exige mais disciplina. O código é mais difícil de testar.
  • 9. a.k.a Test Driven Development Testar antes O código é mais simples de testar. Geralmente é mais bem escrito.
  • 10. Behavior Driven Development Então surgiu o BDD Desenvolver aplicações descrevendo seu comportamento do ponto de vista do cliente.
  • 11. BDD não é sobre testar o código.
  • 12. É sobre o design e documentação do código.
  • 13. É sobre escrever software que é realmente importante.
  • 14. Frameworks Sua linguagem preferida deve ter um framework BDD. JBehave, PHPSpec, GSpec, JSpec, specs, NSpec...
  • 15. No Ruby temos o RSpec.
  • 16. David Chelimsky Spec e Story RSpec é um framework BDD para Ruby e Rails. http://rspec.info
  • 17. Descreva o comportamento como em uma conversa.
  • 18. Eu: descreva uma palestra Vocês: • ela deve ter um palestrante. • ela deve ter um tempo definido. • ela deve ser interessante.
  • 19. describe "My Talk" do it "should be awesome" do true.should be_true end end
  • 20. Configuração
  • 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. Ruby on Rails Use como gem. gem install rspec gem install rspec-rails
  • 23. Ruby on Rails Configure sua aplicação. script/generate rspec
  • 24. Ruby on Rails Generators disponíveis. script/generate integration_spec, rspec, rspec_controller, rspec_model, rspec_scaffold
  • 25. O que testar? Tudo o que você julgar importante ser testado.
  • 26. Como testar? Teste uma coisa de cada vez. Acostume-se com o workflow.
  • 27. Red-Green-Refactor Workflow
  • 28. Red Escreva um teste que falhe
  • 29. Green Escreva a funcionalidade
  • 30. Refactor Refatore o código que passou
  • 31. Rails Checklist • Models • Controllers • Helpers • Views • E-mails • Rake tasks • JavaScript • ...
  • 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. 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. Exemplo Verificar se um usuário é admin.
  • 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. 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. Faça o teste passar app/models/user.rb class User < ActiveRecord::Base def admin? true end end
  • 38. Execute a suíte de testes $ rake spec:models . Finished in 0.087279 seconds 1 example, 0 failures
  • 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. 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. Faça o teste passar app/models/user.rb class User < ActiveRecord::Base def admin? role == "admin" end end
  • 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. 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. 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. 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. 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. 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. Faça o teste passar app/controllers/users_controller.rb class UsersController < ApplicationController def new @user = User.new end end
  • 49. Execute a suíte de testes $ rake spec:controllers . Finished in 0.119345 seconds 1 example, 0 failures
  • 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. 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. Faça o teste passar app/controllers/users_controller.rb class UsersController < ApplicationController def create @user = User.new(params[:user]) end end
  • 53. Execute a suíte de testes $ rake spec:controllers .. Finished in 0.119345 seconds 2 example, 0 failures
  • 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. 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. 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. Execute a suíte de testes $ rake spec:controllers .....F Finished in 0.119345 seconds 5 examples, 1 failures
  • 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. 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. 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. Execute a suíte de testes $ rake spec:controllers ....... Finished in 0.119345 seconds 7 examples
  • 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. 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. Exemplo Exibir conteúdo para usuários admin. <% content_for_admin(@user) do %> <!-- admin content --> <% end %>
  • 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. 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. 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. Execute a suíte de testes $ rake spec:helpers . Finished in 0.119345 seconds 1 example, 0 failures
  • 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. 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. Saiba mais sobre RSpec http://rspec.info Cucumber http://cukes.info Factory Girl http://bit.ly/4EicvV
  • 72. TATFT
  • 73. dúvidas?
  • 74. one more thing compra agora! http://howtocode.com.br
  • 75. obrigado nando@simplesideias.com.br