SlideShare une entreprise Scribd logo
1  sur  75
Télécharger pour lire hors ligne
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 Objective-C
       PHP
minhas urls
• http://simplesideias.com.br
• http://howtocode.com.br
• http://spesa.com.br
• http://twitter.com/fnando
• http://github.com/fnando
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 cliente.
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 interessante.
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://github.com/dchelimsky/rspec-rails.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_scaffold
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.rb
create db/migrate/20091104135200_create_users.rb
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
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 = "admin"
    subject.should be_admin
  end
end
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
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 = "admin"
    subject.should be_admin
  end

  it "should not be admin" do
    subject.should_not be_admin
  end
end
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
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.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
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
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
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
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
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
Faça o teste passar
app/controllers/users_controller.rb


class UsersController < ApplicationController
  def new
    @user = User.new
  end
end
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" 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
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
Faça o teste passar
app/controllers/users_controller.rb


class UsersController < ApplicationController
  def create
    @user = User.new(params[:user])
  end
end
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" 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
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
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
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" 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
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
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
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" 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
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
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
    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
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
Faça o teste passar
app/helpers/users_helper.rb

module UsersHelper
  def content_for_admin(user, &block)
    yield if user.admin?
  end
end
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 exemplos!
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.
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

Contenu connexe

Tendances

Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Railstchandy
 
LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09Carlos Santos
 
Ionic 2/3 + Firebase
Ionic 2/3 + FirebaseIonic 2/3 + Firebase
Ionic 2/3 + FirebaseBruno Catão
 
Maven 3, Sonar e Hudson
Maven 3, Sonar e HudsonMaven 3, Sonar e Hudson
Maven 3, Sonar e HudsonRodrigo Branas
 
tmn - Introdução ao JavaScript
tmn - Introdução ao JavaScripttmn - Introdução ao JavaScript
tmn - Introdução ao JavaScriptClaudio Gamboa
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com DjangoMarinho Brandão
 
Automação de Testes com SoapUI v1
Automação de Testes com SoapUI v1Automação de Testes com SoapUI v1
Automação de Testes com SoapUI v1mateuscaletti
 
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2Thyago Maia
 
Como Dominar seu Fluxo de Desenvolvimento com TDD
Como Dominar seu Fluxo de Desenvolvimento com TDDComo Dominar seu Fluxo de Desenvolvimento com TDD
Como Dominar seu Fluxo de Desenvolvimento com TDDRachid Calazans
 
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1Thyago Maia
 
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1Thyago Maia
 
uma história sobre testes de API
uma história sobre testes de APIuma história sobre testes de API
uma história sobre testes de APISamuel Lourenço
 
Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Rafael Ponte
 

Tendances (20)

Design Patterns on Rails
Design Patterns on RailsDesign Patterns on Rails
Design Patterns on Rails
 
LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09
 
Ionic 2/3 + Firebase
Ionic 2/3 + FirebaseIonic 2/3 + Firebase
Ionic 2/3 + Firebase
 
Mean Stack
Mean StackMean Stack
Mean Stack
 
Maven 3, Sonar e Hudson
Maven 3, Sonar e HudsonMaven 3, Sonar e Hudson
Maven 3, Sonar e Hudson
 
tmn - Introdução ao JavaScript
tmn - Introdução ao JavaScripttmn - Introdução ao JavaScript
tmn - Introdução ao JavaScript
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com Django
 
Python 06
Python 06Python 06
Python 06
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Maven em 10 minutos
Maven em 10 minutosMaven em 10 minutos
Maven em 10 minutos
 
Automação de Testes com SoapUI v1
Automação de Testes com SoapUI v1Automação de Testes com SoapUI v1
Automação de Testes com SoapUI v1
 
Api usando Silex
Api usando SilexApi usando Silex
Api usando Silex
 
Maven introdução Muito Rápida
Maven introdução Muito RápidaMaven introdução Muito Rápida
Maven introdução Muito Rápida
 
Grails
GrailsGrails
Grails
 
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 2
 
Como Dominar seu Fluxo de Desenvolvimento com TDD
Como Dominar seu Fluxo de Desenvolvimento com TDDComo Dominar seu Fluxo de Desenvolvimento com TDD
Como Dominar seu Fluxo de Desenvolvimento com TDD
 
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
 
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 4 - 2019.1
 
uma história sobre testes de API
uma história sobre testes de APIuma história sobre testes de API
uma história sobre testes de API
 
Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)
 

Similaire à Testando Rails apps com RSpec

Dito Tech Talk RSpec
Dito Tech Talk RSpecDito Tech Talk RSpec
Dito Tech Talk RSpecguest49d83b2
 
SOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistasSOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistaslucashungaro
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2  ruby-ptWorkshop Ruby on Rails dia 2  ruby-pt
Workshop Ruby on Rails dia 2 ruby-ptPedro Sousa
 
(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - SubalgoritmosCarlos Santos
 
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2Cezar Souza
 
T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)Carlos Santos
 
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)Wennder Santos
 
Dockerizando aplicações em uma fintech o bom, o mau e o feio as surpresas
Dockerizando aplicações em uma fintech  o bom, o mau e o feio as surpresasDockerizando aplicações em uma fintech  o bom, o mau e o feio as surpresas
Dockerizando aplicações em uma fintech o bom, o mau e o feio as surpresasRafael Gomes
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Rodrigo Urubatan
 
pepinos do cliente no código de testes da aplicação com OSS
pepinos do cliente no código de testes da aplicação com OSSpepinos do cliente no código de testes da aplicação com OSS
pepinos do cliente no código de testes da aplicação com OSSRodrigo Urubatan
 
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoTDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010lucashungaro
 

Similaire à Testando Rails apps com RSpec (20)

Dito Tech Talk RSpec
Dito Tech Talk RSpecDito Tech Talk RSpec
Dito Tech Talk RSpec
 
SOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistasSOLID através de BDD: um guia prático para rubistas
SOLID através de BDD: um guia prático para rubistas
 
Ruby & Rails
Ruby & RailsRuby & Rails
Ruby & Rails
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2  ruby-ptWorkshop Ruby on Rails dia 2  ruby-pt
Workshop Ruby on Rails dia 2 ruby-pt
 
Aula Ruby
Aula RubyAula Ruby
Aula Ruby
 
(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos
 
Rails na prática
Rails na práticaRails na prática
Rails na prática
 
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
 
T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)
 
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
 
Desafio Rest API
Desafio Rest APIDesafio Rest API
Desafio Rest API
 
Dockerizando aplicações em uma fintech o bom, o mau e o feio as surpresas
Dockerizando aplicações em uma fintech  o bom, o mau e o feio as surpresasDockerizando aplicações em uma fintech  o bom, o mau e o feio as surpresas
Dockerizando aplicações em uma fintech o bom, o mau e o feio as surpresas
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
 
Php 05 Mvc
Php 05 MvcPhp 05 Mvc
Php 05 Mvc
 
pepinos do cliente no código de testes da aplicação com OSS
pepinos do cliente no código de testes da aplicação com OSSpepinos do cliente no código de testes da aplicação com OSS
pepinos do cliente no código de testes da aplicação com OSS
 
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoTDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direito
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
 

Plus de Nando Vieira

Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
A explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoA explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoNando Vieira
 
Presentta: usando Node.js na prática
Presentta: usando Node.js na práticaPresentta: usando Node.js na prática
Presentta: usando Node.js na práticaNando Vieira
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby MetaprogrammingNando Vieira
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9Nando Vieira
 
jQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe JavascriptjQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe JavascriptNando Vieira
 
Test-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoTest-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoNando Vieira
 

Plus de Nando Vieira (7)

Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
A explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoA explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo preto
 
Presentta: usando Node.js na prática
Presentta: usando Node.js na práticaPresentta: usando Node.js na prática
Presentta: usando Node.js na prática
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby Metaprogramming
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9
 
jQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe JavascriptjQuery - Javascript para quem não sabe Javascript
jQuery - Javascript para quem não sabe Javascript
 
Test-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoTest-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direito
 

Testando Rails apps com RSpec

  • 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.
  • 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
  • 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.
  • 28. Red Escreva um teste que falhe
  • 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
  • 74. one more thing compra agora! http://howtocode.com.br