0
RSpec Best Friends
Mauro quem...
RSpec Best
Friends
RSpec Best
Friends
maurogeorge.com.br
RSpec
sintaxe de expectativa
RSpec
spec/models/pokemon_spec.rb
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
...
spec/models/pokemon_spec.rb
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
...
spec/models/pokemon_spec.rb
it { expect(subject).to be_a(ActiveRecord::Base) }
spec/models/pokemon_spec.rb
it { should be_a(ActiveRecord::Base) }
spec/models/pokemon_spec.rb
it { is_expected.to be_a(ActiveRecord::Base) }
Somente RSpec 3
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
descrevendo melhor os testes
RSpec
spec/models/pokemon_spec.rb
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
...
spec/models/pokemon_spec.rb
describe '#nome_completo' do
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: ...
não teste apenas o happy path
RSpec
spec/models/pokemon_spec.rb
describe '#nome_completo' do
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: ...
spec/models/pokemon_spec.rb
describe '#nome_completo' do
it 'exibe o nome e o id nacional quando possui os valores' do
pok...
contextos para a melhor descrição
RSpec
spec/models/pokemon_spec.rb
describe '#nome_completo' do
context 'quando possui nome e o id nacional' do
it 'exibe o nome ...
de!nindo o sujeito
RSpec
spec/models/pokemon_spec.rb
context 'quando possui nome e o id nacional' do
before do
@pokemon = Pokemon.new(nome: 'Chariz...
spec/models/pokemon_spec.rb
context 'quando possui nome e o id nacional' do
let(:pokemon) do
Pokemon.new(nome: 'Charizard'...
spec/models/pokemon_spec.rb
context 'quando possui nome e o id nacional' do
subject do
Pokemon.new(nome: 'Charizard', id_n...
utilize sempre os matchers
RSpec
spec/models/pokemon_spec.rb
it 'é nil' do
expect(subject.nome_completo).to eq(nil)
end
spec/models/pokemon_spec.rb
it 'é nil' do
expect(subject.nome_completo).to be_nil
end
não use should
RSpec
spec/models/pokemon_spec.rb
it 'should have the name and the national_id' do
expect(pokemon.full_name).to eq('Charizard - ...
spec/models/pokemon_spec.rb
it 'does have the name and the national_id' do
expect(pokemon.full_name).to eq('Charizard - 6'...
ordem aleatória nos testes
RSpec
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.order = "random"
end
coding style
RSpec
https://github.com/mongoid/mongoid
coding style
RSpec
https://github.com/mongoid/mongoid
https://github.com/bbatsov/ruby-style-guide
coding style
RSpec
https://github.com/mongoid/mongoid
https://github.com/bbatsov/ruby-style-guide
https://github.com/bbatsov/rails-style-guid...
Testes que acessam rede
introdução
Testes que acessam rede
Testes lentos
introdução
Testes que acessam rede
Testes lentos
Testes quebradiços
introdução
Testes que acessam rede
Testes lentos
Testes quebradiços
Não poder testar sem rede
introdução
Testes que acessam rede
app/services/criador_pokemon.rb
class CriadorPokemon
# ...
def criar
Pokemon.create(nome: nome)
end
private
# ...
def cria...
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
criador_pokemon.criar
end
subject do
Pokemon....
webmock
Testes que acessam rede
webmock: feedback rápido
Testes que acessam rede
bash
Failure/Error: CriadorPokemon.new(6)
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregist...
webmock: forjando a resposta
Testes que acessam rede
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
body = '{' 
' "name": "Charizard"' 
'}'
stub_...
webmock: forjando com cURL
Testes que acessam rede
bash
$ curl -is http://pokeapi.co/api/v1/pokemon/6/ > 
spec/fixtures/services/criador_pokemon/resposta.txt
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
caminho_arquivo = 'spec/fixtures/services/cri...
vcr
Testes que acessam rede
vcr: con!guração
Testes que acessam rede
spec/support/vcr.rb
VCR.configure do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
c.hook_into :webmock
end
vcr: feedback rápido
Testes que acessam rede
bash
Failure/Error: CriadorPokemon.new(6)
VCR::Errors::UnhandledHTTPRequestError:
========================================...
vcr: forjando a resposta
Testes que acessam rede
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
VCR.use_cassette('CriadorPokemon/criar') do
c...
vcr: RSpec metadata
Testes que acessam rede
spec/support/vcr.rb
VCR.configure do |c|
# ...
c.configure_rspec_metadata!
end
spec/spec_helper.rb
RSpec.configure do |con...
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado', :vcr do
before do
criador_pokemon.criar
end
#...
it 'poss...
factory_girl
!xtures X factories
factory_girl
criando uma factory
factory_girl
spec/factories/usuarios.rb
FactoryGirl.define do
factory :usuario do
nome 'Mauro'
email 'mauro@helabs.com.br'
end
end
console rails
FactoryGirl.create(:usuario)
FactoryGirl.create(:usuario, email: 'mauro@helabs.com.br')
con!gurando
factory_girl
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.include FactoryGirl::Syntax::Methods
end
Em um teste qualquer...
attributes_for
factory_girl
spec/controllers/posts_controller_spec.rb
describe "POST 'create'" do
let(:params) do
{
artigo: {
titulo: 'Meu titulo',
co...
spec/controllers/posts_controller_spec.rb
describe "POST 'create'" do
let(:params) do
{ artigo: attributes_for(:artigo) }
...
herança
factory_girl
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo 'Conteúdo de Diversas dicas do RSpe...
console rails
FactoryGirl.create(:artigo_aprovado)
FactoryGirl.create(:artigo_nao_aprovado)
traits
factory_girl
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo 'Conteúdo de Diversas dicas do RSpe...
console rails
FactoryGirl.create(:artigo, :aprovado)
FactoryGirl.create(:artigo, :nao_aprovado)
dependent attributes
factory_girl
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo { "Conteúdo do artigo #{titulo}. Ap...
sequence
factory_girl
spec/factories/artigos.rb
factory :artigo do
sequence(:titulo) { |n| "Diversas dicas do RSpec #{n}" }
conteudo { "Conteúdo...
associações
factory_girl
console rails
usuario = FactoryGirl.create(:usuario)
FactoryGirl.create(:artigo, usuario: usuario)
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo { "Conteúdo do artigo #{titulo}. Ap...
aliases
factory_girl
spec/factories/artigos.rb
factory :usuario, aliases: [:autor] do
nome 'Mauro'
email { "#{nome}@helabs.com.br" }
end
strategies
factory_girl
console rails
pokemon = FactoryGirl.build(:pokemon)
console rails
pokemon = FactoryGirl.build_stubbed(:pokemon)
lint
factory_girl
spec/support/factory_girl.rb
RSpec.configure do |config|
config.before(:suite) do
begin
DatabaseCleaner.start
FactoryGirl....
timecop
app/models/pokemon.rb
class Pokemon < ActiveRecord::Base
scope :escolhidos_ontem, -> do
where(escolhido_em: 1.day.ago.midn...
spec/models/pokemon_spec.rb
describe '.escolhidos_ontem' do
let!(:pokemon_escolhido_ontem) do
create(:pokemon, escolhido_e...
spec/models/pokemon_spec.rb
describe '.escolhidos_ontem' do
# ...
it 'tem o pokemon escolhido ontem' do
Timecop.freeze(Tim...
simplecov
veri!cando a cobertura
simplecov
spec/spec_helper.rb
require 'simplecov'
SimpleCov.start 'rails'
Primeira linha do
spec_helper.rb
O falso 100%
simplecov
app/models/pokemon.rb
class Pokemon < ActiveRecord::Base
validates :nome, :id_nacional, presence: true
scope :escolhidos_o...
Não teste associações, validações ou
escopos do Active Record
simplecov
teste associações, validações e escopos do
Active Record
simplecov
devo ter 100% de cobertura de testes?
simplecov
shoulda-matchers
app/models/pokemon.rb
class Pokemon < ActiveRecord::Base
validates :nome, :id_nacional, presence: true
validates :id_nacio...
spec/models/pokemon_spec.rb
describe 'validações' do
it { should validate_presence_of(:nome) }
it { should validate_presen...
os matchers
shoulda-matchers
ActiveModel
os matchers
shoulda-matchers
ActiveModel
ActiveRecord
os matchers
shoulda-matchers
ActiveModel
ActiveRecord
ActionController
os matchers
shoulda-matchers
além do shoulda-matchers
shoulda-matchers
https://github.com/bmabey/email-spec
além do shoulda-matchers
shoulda-matchers
https://github.com/bmabey/email-spec
https://github.com/philostler/rspec-sidekiq
além do shoulda-matchers
shoulda-matchers
https://github.com/bmabey/email-spec
https://github.com/philostler/rspec-sidekiq
https://github.com/evansagge/mongoid-rspe...
Obrigado!
maurogeorge.com.br
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
Upcoming SlideShare
Loading in...5
×

RSpec Best Friends @ TDC Florianópolis 2014

722

Published on

Nesta palestra veremos:

- Boas práticas ao escrever testes utilizando o RSpec
- Como escrever testes que acessam rede utilizando o VCR e o WebMock
- Apresentando o factory_girl, comparando com as fixtures. E diversas dicas do factory_girl
- Testes que dependem de data utilizando o timecop
- Coverage de testes com o Simplecov e se devemos ou não atingir os 100% de cobertura de testes
- Evitando repetições durante os testes utilizando de matchers

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

No Downloads
Views
Total Views
722
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
14
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "RSpec Best Friends @ TDC Florianópolis 2014"

  1. 1. RSpec Best Friends
  2. 2. Mauro quem...
  3. 3. RSpec Best Friends
  4. 4. RSpec Best Friends
  5. 5. maurogeorge.com.br
  6. 6. RSpec
  7. 7. sintaxe de expectativa RSpec
  8. 8. spec/models/pokemon_spec.rb it 'exibe o nome e o id nacional' do pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) pokemon.nome_completo.should eq('Charizard - 6') end
  9. 9. spec/models/pokemon_spec.rb it 'exibe o nome e o id nacional' do pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) expect(pokemon.nome_completo).to eq('Charizard - 6') end
  10. 10. spec/models/pokemon_spec.rb it { expect(subject).to be_a(ActiveRecord::Base) }
  11. 11. spec/models/pokemon_spec.rb it { should be_a(ActiveRecord::Base) }
  12. 12. spec/models/pokemon_spec.rb it { is_expected.to be_a(ActiveRecord::Base) } Somente RSpec 3
  13. 13. spec/spec_helper.rb RSpec.configure do |config| # ... config.expect_with :rspec do |c| c.syntax = :expect end end
  14. 14. descrevendo melhor os testes RSpec
  15. 15. spec/models/pokemon_spec.rb it 'exibe o nome e o id nacional' do pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) expect(pokemon.nome_completo).to eq('Charizard - 6') end
  16. 16. spec/models/pokemon_spec.rb describe '#nome_completo' do it 'exibe o nome e o id nacional' do pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) expect(pokemon.nome_completo).to eq('Charizard - 6') end end
  17. 17. não teste apenas o happy path RSpec
  18. 18. spec/models/pokemon_spec.rb describe '#nome_completo' do it 'exibe o nome e o id nacional' do pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) expect(pokemon.nome_completo).to eq('Charizard - 6') end end
  19. 19. spec/models/pokemon_spec.rb describe '#nome_completo' do it 'exibe o nome e o id nacional quando possui os valores' do pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) expect(pokemon.nome_completo).to eq('Charizard - 6') end it 'é nil quando não possui o nome e o id nacional' do pokemon = Pokemon.new expect(pokemon.nome_completo).to be_nil end end
  20. 20. contextos para a melhor descrição RSpec
  21. 21. spec/models/pokemon_spec.rb describe '#nome_completo' do context 'quando possui nome e o id nacional' do it 'exibe o nome e o id nacional' do # ... end end context 'quando não possui o nome e o id nacional' do it 'é nil' do # ... end end end
  22. 22. de!nindo o sujeito RSpec
  23. 23. spec/models/pokemon_spec.rb context 'quando possui nome e o id nacional' do before do @pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6) end it 'exibe o nome e o id nacional' do expect(@pokemon.nome_completo).to eq('Charizard - 6') end end
  24. 24. spec/models/pokemon_spec.rb context 'quando possui nome e o id nacional' do let(:pokemon) do Pokemon.new(nome: 'Charizard', id_nacional: 6) end it 'exibe o nome e o id nacional' do expect(pokemon.nome_completo).to eq('Charizard - 6') end end
  25. 25. spec/models/pokemon_spec.rb context 'quando possui nome e o id nacional' do subject do Pokemon.new(nome: 'Charizard', id_nacional: 6) end it 'exibe o nome e o id nacional' do expect(subject.nome_completo).to eq('Charizard - 6') end end
  26. 26. utilize sempre os matchers RSpec
  27. 27. spec/models/pokemon_spec.rb it 'é nil' do expect(subject.nome_completo).to eq(nil) end
  28. 28. spec/models/pokemon_spec.rb it 'é nil' do expect(subject.nome_completo).to be_nil end
  29. 29. não use should RSpec
  30. 30. spec/models/pokemon_spec.rb it 'should have the name and the national_id' do expect(pokemon.full_name).to eq('Charizard - 6') end
  31. 31. spec/models/pokemon_spec.rb it 'does have the name and the national_id' do expect(pokemon.full_name).to eq('Charizard - 6') end
  32. 32. ordem aleatória nos testes RSpec
  33. 33. spec/spec_helper.rb RSpec.configure do |config| # ... config.order = "random" end
  34. 34. coding style RSpec
  35. 35. https://github.com/mongoid/mongoid coding style RSpec
  36. 36. https://github.com/mongoid/mongoid https://github.com/bbatsov/ruby-style-guide coding style RSpec
  37. 37. https://github.com/mongoid/mongoid https://github.com/bbatsov/ruby-style-guide https://github.com/bbatsov/rails-style-guide coding style RSpec
  38. 38. Testes que acessam rede
  39. 39. introdução Testes que acessam rede
  40. 40. Testes lentos introdução Testes que acessam rede
  41. 41. Testes lentos Testes quebradiços introdução Testes que acessam rede
  42. 42. Testes lentos Testes quebradiços Não poder testar sem rede introdução Testes que acessam rede
  43. 43. app/services/criador_pokemon.rb class CriadorPokemon # ... def criar Pokemon.create(nome: nome) end private # ... def cria_info resposta = Net::HTTP.get(endpoint) @info = JSON.parse(resposta) end end
  44. 44. spec/services/criador_pokemon_spec.rb describe 'pokemon criado' do before do criador_pokemon.criar end subject do Pokemon.last end it 'possui o nome correto' do expect(subject.nome).to eq('Charizard') end end
  45. 45. webmock Testes que acessam rede
  46. 46. webmock: feedback rápido Testes que acessam rede
  47. 47. bash Failure/Error: CriadorPokemon.new(6) WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: GET http:// pokeapi.co/api/v1/pokemon/6/ with headers {'Accept'=>'*/*', 'Accept- Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'pokeapi.co', 'User- Agent'=>'Ruby'} You can stub this request with the following snippet: stub_request(:get, "http://pokeapi.co/api/v1/pokemon/6/"). with(:headers => {'Accept'=>'*/*', 'Accept- Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'pokeapi.co', 'User- Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
  48. 48. webmock: forjando a resposta Testes que acessam rede
  49. 49. spec/services/criador_pokemon_spec.rb describe 'pokemon criado' do before do body = '{' ' "name": "Charizard"' '}' stub_request(:get, 'http://pokeapi.co/api/v1/pokemon/6/') .to_return(status: 200, body: body, headers: {}) criador_pokemon.criar end end
  50. 50. webmock: forjando com cURL Testes que acessam rede
  51. 51. bash $ curl -is http://pokeapi.co/api/v1/pokemon/6/ > spec/fixtures/services/criador_pokemon/resposta.txt
  52. 52. spec/services/criador_pokemon_spec.rb describe 'pokemon criado' do before do caminho_arquivo = 'spec/fixtures/services/criador_pokemon/resposta.txt' arquivo_resposta = File.new(caminho_arquivo) stub_request(:get, 'http://pokeapi.co/api/v1/pokemon/6/') .to_return(arquivo_resposta) criador_pokemon.criar end end
  53. 53. vcr Testes que acessam rede
  54. 54. vcr: con!guração Testes que acessam rede
  55. 55. spec/support/vcr.rb VCR.configure do |c| c.cassette_library_dir = 'spec/fixtures/vcr_cassettes' c.hook_into :webmock end
  56. 56. vcr: feedback rápido Testes que acessam rede
  57. 57. bash Failure/Error: CriadorPokemon.new(6) VCR::Errors::UnhandledHTTPRequestError: ===================================================================== An HTTP request has been made that VCR does not know how to handle: GET http://pokeapi.co/api/v1/pokemon/6/ There is currently no cassette in use. There are a few ways you can configure VCR to handle this request: ...
  58. 58. vcr: forjando a resposta Testes que acessam rede
  59. 59. spec/services/criador_pokemon_spec.rb describe 'pokemon criado' do before do VCR.use_cassette('CriadorPokemon/criar') do criador_pokemon.criar end end #... it 'possui o nome correto' do expect(subject.nome).to eq('Charizard') end end
  60. 60. vcr: RSpec metadata Testes que acessam rede
  61. 61. spec/support/vcr.rb VCR.configure do |c| # ... c.configure_rspec_metadata! end spec/spec_helper.rb RSpec.configure do |config| # ... config.treat_symbols_as_metadata_keys_with_true_values = true end
  62. 62. spec/services/criador_pokemon_spec.rb describe 'pokemon criado', :vcr do before do criador_pokemon.criar end #... it 'possui o nome correto' do expect(subject.nome).to eq('Charizard') end end
  63. 63. factory_girl
  64. 64. !xtures X factories factory_girl
  65. 65. criando uma factory factory_girl
  66. 66. spec/factories/usuarios.rb FactoryGirl.define do factory :usuario do nome 'Mauro' email 'mauro@helabs.com.br' end end
  67. 67. console rails FactoryGirl.create(:usuario) FactoryGirl.create(:usuario, email: 'mauro@helabs.com.br')
  68. 68. con!gurando factory_girl
  69. 69. spec/spec_helper.rb RSpec.configure do |config| # ... config.include FactoryGirl::Syntax::Methods end Em um teste qualquer let!(:artigo) do create(:artigo) end
  70. 70. attributes_for factory_girl
  71. 71. spec/controllers/posts_controller_spec.rb describe "POST 'create'" do let(:params) do { artigo: { titulo: 'Meu titulo', conteudo: 'Conteudo do artigo' } } end end
  72. 72. spec/controllers/posts_controller_spec.rb describe "POST 'create'" do let(:params) do { artigo: attributes_for(:artigo) } end end
  73. 73. herança factory_girl
  74. 74. spec/factories/artigos.rb factory :artigo do titulo 'Diversas dicas do RSpec' conteudo 'Conteúdo de Diversas dicas do RSpec' factory :artigo_aprovado do aprovado true end factory :artigo_nao_aprovado do aprovado false end end
  75. 75. console rails FactoryGirl.create(:artigo_aprovado) FactoryGirl.create(:artigo_nao_aprovado)
  76. 76. traits factory_girl
  77. 77. spec/factories/artigos.rb factory :artigo do titulo 'Diversas dicas do RSpec' conteudo 'Conteúdo de Diversas dicas do RSpec' trait :aprovado do aprovado true end trait :nao_aprovado do aprovado false end end
  78. 78. console rails FactoryGirl.create(:artigo, :aprovado) FactoryGirl.create(:artigo, :nao_aprovado)
  79. 79. dependent attributes factory_girl
  80. 80. spec/factories/artigos.rb factory :artigo do titulo 'Diversas dicas do RSpec' conteudo { "Conteúdo do artigo #{titulo}. Aprovado: #{aprovado}" } end
  81. 81. sequence factory_girl
  82. 82. spec/factories/artigos.rb factory :artigo do sequence(:titulo) { |n| "Diversas dicas do RSpec #{n}" } conteudo { "Conteúdo do artigo #{titulo}. Aprovado: #{aprovado}" } end
  83. 83. associações factory_girl
  84. 84. console rails usuario = FactoryGirl.create(:usuario) FactoryGirl.create(:artigo, usuario: usuario)
  85. 85. spec/factories/artigos.rb factory :artigo do titulo 'Diversas dicas do RSpec' conteudo { "Conteúdo do artigo #{titulo}. Aprovado: #{aprovado}" } usuario end
  86. 86. aliases factory_girl
  87. 87. spec/factories/artigos.rb factory :usuario, aliases: [:autor] do nome 'Mauro' email { "#{nome}@helabs.com.br" } end
  88. 88. strategies factory_girl
  89. 89. console rails pokemon = FactoryGirl.build(:pokemon)
  90. 90. console rails pokemon = FactoryGirl.build_stubbed(:pokemon)
  91. 91. lint factory_girl
  92. 92. spec/support/factory_girl.rb RSpec.configure do |config| config.before(:suite) do begin DatabaseCleaner.start FactoryGirl.lint ensure DatabaseCleaner.clean end end end
  93. 93. timecop
  94. 94. app/models/pokemon.rb class Pokemon < ActiveRecord::Base scope :escolhidos_ontem, -> do where(escolhido_em: 1.day.ago.midnight..Time.zone.now.midnight) end end
  95. 95. spec/models/pokemon_spec.rb describe '.escolhidos_ontem' do let!(:pokemon_escolhido_ontem) do create(:pokemon, escolhido_em: Time.zone.local(2014, 5, 16, 10, 45)) end subject do Pokemon.escolhidos_ontem end it 'tem o pokemon escolhido ontem' do expect(subject).to include(pokemon_escolhido_ontem) end end
  96. 96. spec/models/pokemon_spec.rb describe '.escolhidos_ontem' do # ... it 'tem o pokemon escolhido ontem' do Timecop.freeze(Time.zone.local((2014, 5, 17, 10, 45)) do expect(subject).to include(pokemon_escolhido_ontem) end end end
  97. 97. simplecov
  98. 98. veri!cando a cobertura simplecov
  99. 99. spec/spec_helper.rb require 'simplecov' SimpleCov.start 'rails' Primeira linha do spec_helper.rb
  100. 100. O falso 100% simplecov
  101. 101. app/models/pokemon.rb class Pokemon < ActiveRecord::Base validates :nome, :id_nacional, presence: true scope :escolhidos_ontem, -> do where(escolhido_em: 1.day.ago.midnight..Time.zone.now.midnight) end end
  102. 102. Não teste associações, validações ou escopos do Active Record simplecov
  103. 103. teste associações, validações e escopos do Active Record simplecov
  104. 104. devo ter 100% de cobertura de testes? simplecov
  105. 105. shoulda-matchers
  106. 106. app/models/pokemon.rb class Pokemon < ActiveRecord::Base validates :nome, :id_nacional, presence: true validates :id_nacional, numericality: { only_integer: true, greater_than: 0 } end
  107. 107. spec/models/pokemon_spec.rb describe 'validações' do it { should validate_presence_of(:nome) } it { should validate_presence_of(:id_nacional) } it { should validate_numericality_of(:id_nacional).only_integer .is_greater_than(0) } end
  108. 108. os matchers shoulda-matchers
  109. 109. ActiveModel os matchers shoulda-matchers
  110. 110. ActiveModel ActiveRecord os matchers shoulda-matchers
  111. 111. ActiveModel ActiveRecord ActionController os matchers shoulda-matchers
  112. 112. além do shoulda-matchers shoulda-matchers
  113. 113. https://github.com/bmabey/email-spec além do shoulda-matchers shoulda-matchers
  114. 114. https://github.com/bmabey/email-spec https://github.com/philostler/rspec-sidekiq além do shoulda-matchers shoulda-matchers
  115. 115. https://github.com/bmabey/email-spec https://github.com/philostler/rspec-sidekiq https://github.com/evansagge/mongoid-rspec além do shoulda-matchers shoulda-matchers
  116. 116. Obrigado!
  117. 117. maurogeorge.com.br
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×