testando rails apps com rspec

75
nando vieira testando rails apps com rspec

Upload: nando-vieira

Post on 19-May-2015

6.915 views

Category:

Technology


4 download

DESCRIPTION

Minha apresentação no Ceará on Rails 2009

TRANSCRIPT

Page 1: Testando Rails apps com RSpec

nando vieira

testando railsapps com rspec

Page 2: Testando Rails apps com RSpec

sobre mim• trabalho com web desde 1999

• desenvolvo com ruby desde 2006

• escrevo testes desde 2007

RubyPHP JavaScript Objective-C

Page 3: Testando Rails apps com RSpec

minhas urls• http://simplesideias.com.br

• http://howtocode.com.br

• http://spesa.com.br

• http://twitter.com/fnando

• http://github.com/fnando

Page 4: Testando Rails apps com RSpec

Por que testar?Para verificar se o sistema se comporta como deveria.

Page 5: Testando Rails apps com RSpec

Como testar?Testes manuais.Testes automatizados.Testes manuais.Testes automatizados.

Page 6: Testando Rails apps com RSpec

Testes automatizadosTrazem mais confiança.Identificam regressões no código.Permitem refatorar com segurança.

Page 7: Testando Rails apps com RSpec

Testar antes ou depois?Tanto faz.

Page 8: Testando Rails apps com RSpec

Testar depoisExige mais disciplina.O código é mais difícil de testar.

Page 9: Testando Rails apps com RSpec

Testar antesO código é mais simples de testar.Geralmente é mais bem escrito.

a.k.a Test Driven Development

Page 10: Testando Rails apps com RSpec

Então surgiu o BDDDesenvolver aplicações descrevendo seu comportamento do ponto de vista do cliente.

Behavior Driven Development

Page 11: Testando Rails apps com RSpec

BDD não é sobre testar o código.

Page 12: Testando Rails apps com RSpec

É sobre o design e documentação do código.

Page 13: Testando Rails apps com RSpec

É sobre escrever software que é realmente importante.

Page 14: Testando Rails apps com RSpec

Frameworks

JBehave, PHPSpec, GSpec, JSpec, specs, NSpec...

Sua linguagem preferida deve ter umframework BDD.

Page 15: Testando Rails apps com RSpec

No Ruby temos o RSpec.

Page 16: Testando Rails apps com RSpec

RSpec é um framework BDD para Ruby e Rails.

Spec e StoryDavid Chelimsky

http://rspec.info

Page 17: Testando Rails apps com RSpec

Descreva o comportamento como em uma conversa.

Page 18: Testando Rails apps com RSpec

Eu: descreva uma palestraVocês:• ela deve ter um palestrante.• ela deve ter um tempo definido.• ela deve ser interessante.

Page 19: Testando Rails apps com RSpec

describe "My Talk" do it "should be awesome" do true.should be_true endend

Page 20: Testando Rails apps com RSpec

Configuração

Page 21: Testando Rails apps com RSpec

Ruby on RailsUse como plugin.script/plugin install git://github.com/dchelimsky/rspec.gitscript/plugin install git://github.com/dchelimsky/rspec-rails.git

Page 22: Testando Rails apps com RSpec

Ruby on RailsUse como gem.gem install rspecgem install rspec-rails

Page 23: Testando Rails apps com RSpec

Ruby on RailsConfigure sua aplicação.script/generate rspec

Page 24: Testando Rails apps com RSpec

Ruby on RailsGenerators disponíveis.script/generateintegration_spec, rspec, rspec_controller, rspec_model, rspec_scaffold

Page 25: Testando Rails apps com RSpec

O que testar?Tudo o que você julgar importante ser testado.

Page 26: Testando Rails apps com RSpec

Como testar?Teste uma coisa de cada vez.Acostume-se com o workflow.

Page 27: Testando Rails apps com RSpec

Red-Green-RefactorWorkflow

Page 28: Testando Rails apps com RSpec

RedEscreva um teste que falhe

Page 29: Testando Rails apps com RSpec

GreenEscreva a funcionalidade

Page 30: Testando Rails apps com RSpec

RefactorRefatore o código que passou

Page 31: Testando Rails apps com RSpec

Rails Checklist• Models• Controllers• Helpers• Views• E-mails• Rake tasks• JavaScript• ...

• Models• Controllers• Helpers• Views

Page 32: Testando Rails apps com RSpec

Modelscript/generate rspec_model user role:string --skip-fixture

create app/models/user.rbcreate spec/models/user_spec.rbcreate db/migrate/20091104135200_create_users.rb

Page 33: Testando Rails apps com RSpec

Modelspec/models/user_spec.rbrequire '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) endend

Page 34: Testando Rails apps com RSpec

ExemploVerificar se um usuário é admin.

Page 35: Testando Rails apps com RSpec

describe User do it "should be an admin" do subject.role = "admin" subject.should be_admin endend

Escreva um teste que falhespec/models/user_spec.rb

Page 36: Testando Rails apps com RSpec

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

$ rake spec:models

Execute a suíte de testes

Page 37: Testando Rails apps com RSpec

app/models/user.rbFaça o teste passar

class User < ActiveRecord::Base def admin? true endend

Page 38: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:models

.

Finished in 0.087279 seconds

1 example, 0 failures

Page 39: Testando Rails apps com RSpec

Adicione um teste negativospec/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 endend

Page 40: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:models.F

1)'User should not be admin' FAILEDexpected admin? to return false, got true./spec/models/user_spec.rb:10:

Finished in 0.098295 seconds

2 examples, 1 failure

Page 41: Testando Rails apps com RSpec

app/models/user.rbFaça o teste passar

class User < ActiveRecord::Base def admin? role == "admin" endend

Page 42: Testando Rails apps com RSpec

ModelCoisas mais comunsit "should be valid" do subject.should be_validend

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).recordsend

Page 43: Testando Rails apps com RSpec

Controllerscript/generate rspec_controller users

create spec/controllers/users_controller_spec.rbcreate spec/helpers/users_helper_spec.rbcreate app/controllers/users_controller.rbcreate app/helpers/users_helper.rb

Page 44: Testando Rails apps com RSpec

Controllerspec/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

Page 45: Testando Rails apps com RSpec

ExemploCriar 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 endend

Page 46: Testando Rails apps com RSpec

Escreva um teste que falhespec/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 endend

Page 47: Testando Rails apps com RSpec

F

1) 'UsersController GET: new should instantiate user' FAILEDexpected 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

$ rake spec:controllers

Execute a suíte de testes

Page 48: Testando Rails apps com RSpec

app/controllers/users_controller.rbFaça o teste passar

class UsersController < ApplicationController def new @user = User.new endend

Page 49: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:controllers

.

Finished in 0.119345 seconds

1 example, 0 failures

Page 50: Testando Rails apps com RSpec

Escreva o próximo testespec/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 endend

Page 51: Testando Rails apps com RSpec

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

$ rake spec:controllers

Execute a suíte de testes

Page 52: Testando Rails apps com RSpec

app/controllers/users_controller.rbFaça o teste passar

class UsersController < ApplicationController def create @user = User.new(params[:user]) endend

Page 53: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:controllers

..

Finished in 0.119345 seconds

2 example, 0 failures

Page 54: Testando Rails apps com RSpec

Escreva o próximo testespec/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 endend

Page 55: Testando Rails apps com RSpec

F

1) 'UsersController POST: create on success should redirect to the show page' FAILEDexpected redirect to "http://test.host/users/1", got no redirect

Finished in 0.138342 seconds

4 examples, 2 failures

$ rake spec:controllers

Execute a suíte de testes

Page 56: Testando Rails apps com RSpec

app/controllers/users_controller.rbFaça o teste passar

class UsersController < ApplicationController def create @user = User.new(params[:user]) if @user.save redirect_to @user end endend

Page 57: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:controllers

.....F

Finished in 0.119345 seconds

5 examples, 1 failures

Page 58: Testando Rails apps com RSpec

Escreva o próximo testespec/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 endend

Page 59: Testando Rails apps com RSpec

F

1) 'UsersController POST: create on success should set success message' FAILEDexpected: "A new user has been created!", got: nil (using ==)

Finished in 0.138342 seconds

5 examples, 1 failure

$ rake spec:controllers

Execute a suíte de testes

Page 60: Testando Rails apps com RSpec

app/controllers/users_controller.rbFaça o teste passarclass UsersController < ApplicationController def create @user = User.new(params[:user]) if @user.save flash[:notice] = "A new user has been created!" redirect_to @user end endend

Page 61: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:controllers

.......

Finished in 0.119345 seconds

7 examples

Page 62: Testando Rails apps com RSpec

Escreva o próximo testespec/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 endend

Page 63: Testando Rails apps com RSpec

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

Page 64: Testando Rails apps com RSpec

ExemploExibir conteúdo para usuários admin.<% content_for_admin(@user) do %> <!-- admin content --><% end %>

Page 65: Testando Rails apps com RSpec

Escreva um teste que falhespec/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 endend

Page 66: Testando Rails apps com RSpec

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

$ rake spec:helpers

Execute a suíte de testes

Page 67: Testando Rails apps com RSpec

app/helpers/users_helper.rbFaça o teste passar

module UsersHelper def content_for_admin(user, &block) yield if user.admin? endend

Page 68: Testando Rails apps com RSpec

Execute a suíte de testes$ rake spec:helpers

.

Finished in 0.119345 seconds

1 example, 0 failures

Page 69: Testando Rails apps com RSpec

ViewsTeste a semântica e não o código gerado.É difícil escrever testes antes do markup.Utilize stubs & mocks!Sem exemplos!

Page 70: Testando Rails apps com RSpec

Duas coisas que você deve tirar desta palestraTente 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.

Page 71: Testando Rails apps com RSpec

Saiba mais sobreRSpec http://rspec.info Cucumber http://cukes.infoFactory Girl http://bit.ly/4EicvV

Page 72: Testando Rails apps com RSpec

TATFT

Page 73: Testando Rails apps com RSpec

dúvidas?

Page 74: Testando Rails apps com RSpec

one more thing

compra agora!http://howtocode.com.br