SlideShare ist ein Scribd-Unternehmen logo
1 von 70
Downloaden Sie, um offline zu lesen
RSpec 3
Contents
1. Changes from v2.14 to v3.y.z
2. Better Specs reviewed
Changes from
v2.14 to v3.y.z
Expect to not
‘should’ anymore
Changes
● New syntax does not use “monkey patching”
● Examples are based on “expectations” over objects
</>
What is it about?
# ‘should’ is “replaced” by ‘expect’
#
it ‘stores 5 in its attribute’ do
expect(subject.attribute).to eq 5
end
</>
In one line
# One-liner syntax changes accordingly
#
it { should eq 5 }
# Is written like...
#
it { is_expected.to eq 5 }
Migrating
● We can migrate our current specs to the new syntax
using github.com/yujinakayama/transpec
● In 3.1.z, there’s still a mechanism to work with the old
syntax
Don’t stub. Allow.
Changes
● New syntax to stub methods
● Also a new syntax to set expectations on method
calls
</>
How to stub
# Old
instance.stub(:method)
instance.stub(:method).with(<arguments>)
instance.stub(:method).with(<arguments>).and_return(<something>)
# New
allow(instance).to receive(:method)
allow(instance).to receive(:method).with(<arguments>)
allow(instance).to receive(:method).with(<arguments>)...
</>
stub on any instance
# Old
Object.any_instance.stub(:method)
Object.any_instance.stub(:method).with(<arguments>)
Object.any_instance.stub(:method).with(<arguments>).and_...
# New
allow_any_instance_of(Object).to receive(:method)
allow_any_instance_of(Object).to receive(:method).with...
allow_any_instance_of(Object).to receive(:method).with...
</>
stub chain
# Old
instance.stub_chain(:method_a, :method_b)
# New
allow(instance).to receive_message_chain(:method_a, :method_b)
</>
Method expectations
# Old
instance.should_receive(:method)
instance.should_receive(:method).with(<arguments>)
# New
expect(instance).to receive(:method)
expect(instance).to receive(:method).with(<arguments>)
</>
...on any instance
# Old
Object.any_instance.should_receive(:method)
Object.any_instance.should_receive(:method).with(<arguments>)
# New
expect_any_instance_of(Object).to receive(:method)
expect_any_instance_of(Object).to receive(:method).with...
Tools of trade
Skip it...
</>
Many ways to skip an example
# Common way
#
it ‘stores 5 in its attribute’, skip: true do
# Giving a reason for the output
#
it ‘stores 5 in its attribute’, skip: ‘reason’ do
# Shortcut
#
skip ‘stores 5 in its attribute’ do
...or leave it pending
Pending should make sense
● When an example inside a pending block passes,
RSpec will show an error
● This enforces that all pending blocks are pending for
a good reason
Matchmakers
Cha-cha-chain
</>
Chaining
# You can chain multiple ‘matchers’
#
expect(subject.attribute).
to start_with(‘hello’).and end_with(‘world’)
expect(subject.attribute).
to start_with(‘hello’).or start_with(‘goodbye’)
</>
The cooler way
# You can chain multiple ‘matchers’
#
expect(subject.attribute).
to start_with(‘hello’) & end_with(‘world’)
expect(subject.attribute).
to start_with(‘hello’) | start_with(‘goodbye’)
Structural matching
</>
A matcher for structures
# ‘match’ can validate Hash and Array object structures
#
let(:structure) { {key: :value, other_key: :other_value} }
expect(structure).
to match({key: :value, other_key: :other_value})
# Still works for strings and regexps as before
=~?
</>
Match arrays
# =~ does not work anymore as an array’s content matcher
# Now
expect(ary).to contain_exactly(1, 2, 3)
# Also in its explicit version
expect(ary).to match_array([1, 2, 3])
be_yourself
</>
Cambios en el ser
# ‘be_true’ becomes ‘be_truthy’
expect(true).to be_truthy
# ‘be_false’ becomes ‘be_falsey’ or ‘be_falsy’
expect(false).to be_falsey
expect(false).to be_falsy
# Having better semantics like in...
expect(nil).to be_falsey # instead of ‘be_false’
</>
Cambios en el ser
expect(nil).to be_false # Fails
expect(nil).to be_falsey # Passes
expect(‘hello world’).to be_true # Fails
expect(‘hello world’).to be_truthy # Passes
What’s gone
is kind of gone
The fired matchers
● its
github.com/rspec/rspec-its
● have, have_at_least, have_at_most
github.com/rspec/rspec-collection_matchers
Better Specs reviewed
Put some context
</>
Why, oh lord, why?
it ‘stores 5 in its attribute if attribute b is 6 and
attribute c is 7’ do
subject.attribute_b = 6
subject.attribute_c = 7
expect(subject.attribute).to eq 5
end
</>
Why not just...?
context ‘when attribute b is 6’ do
# ...
context ‘and attribute c is 7’ do
# ...
it ‘stores 5 in its attribute’ do
expect(subject.attribute).to eq 5
end
Analysis
● We can find good reasons not to do this:
○ It’s more code
○ It’s cumbersome
○ I’m just a lazy dog
● RSpec is about documentation.
● Documentation takes time.
● Good documentation takes even more time.
Isolation
VS
Combination
</>
This is not always a bad thing
it 'sets the attribute' do
subject.very_expensive_loading
expect(subject.attribute).to be_kind_of(Fixnum)
expect(subject.attribute).to eq(5)
end
</>
...but sometimes it’s unnecessary
it 'stores a fixnum in its attribute' do
expect(subject.attribute).to be_kind_of(Fixnum)
end
it 'its attribute’s fixnum is 5' do
expect(subject.attribute).to eq(5)
end
The right method
VS
The right result
</>
¿What should we test for?
it 'sets the attribute to 5' do
expect(subject).to receive(:=).with(5) # Dramatization
subject.set_attribute(5)
end
# Instead of
it 'sets the attribute to 5' do
subject.set_attribute(5)
expect(subject.attribute).to eq 5
end
Analysis
● Not always unnecessary.
● When it’s an expensive operations like the ones that
require access to an outside service, there’s no need
to test for its results. (Assume it’s already tested)
● Don’t be scared to raise the coverage of the same
method.
Change the subject
</>
Change the subject when you can
it 'returns an array’ do
expect(subject.method).to be_kind_of(Array)
end
it 'returns an array that includes ’foo’' do
expect(subject.method).to include(:foo)
end
it 'returns an array with something else' do
# ...
</>
Change the subject when you can
describe '#method’s return value' do
subject { instance.method }
it 'is an array’ do
expect(subject).to be_kind_of(Array)
end
it 'includes ’foo’' do
expect(subject).to include(:foo)
end
Let it be
</>
¡¡¡!!!
before do
@some_value = :foo
@some_other_value = :boo
@yet_some_other_value = :cmon_bro
@again_and_again = :you_are_killing_me
end
</>
And its little brother
it 'does something’ do
value_a = :foo
value_b = :boo
value_c = :cmon_bro
value_d = :you_are_killing_me
expect(instance.
method(value_a, value_b, value_c, value_d)).
to_not raise_error
end
</>
A relief in sight
let(:value_a) { :foo }
let(:value_b) { :boo }
let(:value_c) { :cmon_bro }
let(:value_d) { :you_are_killing_me }
it 'does something’ do
expect(instance.
method(value_a, value_b, value_c, value_d)).
to_not raise_error
end
Analysis
● Reuse of variables (DRY)
● Lazy loading
● Readability (Good documentation)
Avoid creating
a monster
</>
Don’t get excited about create
let(:model) { create(:model) }
# ORLY?
</>
Don’t get excited about create
let(:model) { build(:model) }
Analysis
● create stores in the database.
● I mean, it stores in the database.
● Do we really need to persist?
● build is new without save
● The bad thing is that we have to run callbacks
manually or setting up our Factory to do so
● Is that bad, anyway?
Stub when you have to
</>
Look what a pretty request
# Let’s pretend ‘instance.call_api’ is a very expensive call
it 'parses the api response’ do
expect(subject.parser(instance.call_api)).
to be_kind_of(Hash)
end
</>
Look what a pretty request
before do
allow(instance).to receive(:call_api).
and_return(<valid response from api>)
end
it 'parses the api response’ do
expect(subject.parser(instance.call_api)).
to be_kind_of(Hash)
end
Learn to share
</>
Inherited behavior
class Foo < Bar
# …
describe Foo do
it ‘serves drinks’
it ‘does whatever a foo does’
</>
Inherited behavior
class Foo < Bar
# …
shared_examples_for Bar do
it ‘serves drinks’
end
describe Foo do
it_behaves_like Bar
it ‘does whatever a foo does’
end
Analysis
● Reuse of examples (DRY).
● Consistent behavior across all subclasses.
● The idea is to only verify what’s inherited; we don’t
want to test private stuff.
Agree to disagree
David Heinemeier Hansson, creator of Ruby on Rails
David Heinemeier Hansson, creator of Ruby on Rails
David Heinemeier Hansson, creator of Ruby on Rails
David Heinemeier Hansson, creator of Ruby on Rails
myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3
betterspecs.org
rubyinside.com/dhh-offended-by-rspec-debate-4610.html
Sources
La fin

Weitere ähnliche Inhalte

Was ist angesagt?

Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpecNascenia IT
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API DocumentationSmartLogic
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Railsbenlcollins
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Storiesrahoulb
 
Introduction to Python decorators
Introduction to Python decoratorsIntroduction to Python decorators
Introduction to Python decoratorsrikbyte
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplicationolegmmiller
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with DreddRyan M Harrison
 
Testing JS with Jasmine
Testing JS with JasmineTesting JS with Jasmine
Testing JS with JasmineEvgeny Gurin
 
Zero to Testing in JavaScript
Zero to Testing in JavaScriptZero to Testing in JavaScript
Zero to Testing in JavaScriptpamselle
 
Practical Ext JS Debugging
Practical Ext JS DebuggingPractical Ext JS Debugging
Practical Ext JS DebuggingShea Frederick
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Write codeforhumans
Write codeforhumansWrite codeforhumans
Write codeforhumansNarendran R
 

Was ist angesagt? (20)

Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpec
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API Documentation
 
TDD, BDD, RSpec
TDD, BDD, RSpecTDD, BDD, RSpec
TDD, BDD, RSpec
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Rails
 
TDD with phpspec2
TDD with phpspec2TDD with phpspec2
TDD with phpspec2
 
Clean Code
Clean CodeClean Code
Clean Code
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Stories
 
Introduction to Python decorators
Introduction to Python decoratorsIntroduction to Python decorators
Introduction to Python decorators
 
RSpec
RSpecRSpec
RSpec
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd
 
Testing JS with Jasmine
Testing JS with JasmineTesting JS with Jasmine
Testing JS with Jasmine
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Excellent
ExcellentExcellent
Excellent
 
Zero to Testing in JavaScript
Zero to Testing in JavaScriptZero to Testing in JavaScript
Zero to Testing in JavaScript
 
Practical Ext JS Debugging
Practical Ext JS DebuggingPractical Ext JS Debugging
Practical Ext JS Debugging
 
Rspec
RspecRspec
Rspec
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Write codeforhumans
Write codeforhumansWrite codeforhumans
Write codeforhumans
 

Ähnlich wie RSpec 3: The new, the old, the good

Introduction to unit testing
Introduction to unit testingIntroduction to unit testing
Introduction to unit testingArtem Shoobovych
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 
Karate for Complex Web-Service API Testing by Peter Thomas
Karate for Complex Web-Service API Testing by Peter ThomasKarate for Complex Web-Service API Testing by Peter Thomas
Karate for Complex Web-Service API Testing by Peter Thomasintuit_india
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD WorkshopWolfram Arnold
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingFrancesco Casalegno
 
JavaScript / Web Engineering / Web Development / html + css + js/presentation
JavaScript / Web Engineering / Web Development / html + css + js/presentationJavaScript / Web Engineering / Web Development / html + css + js/presentation
JavaScript / Web Engineering / Web Development / html + css + js/presentationM Sajid R
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkDaniel Spector
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web frameworktaggg
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Brian Sam-Bodden
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Knowvilniusjug
 

Ähnlich wie RSpec 3: The new, the old, the good (20)

Introduction to unit testing
Introduction to unit testingIntroduction to unit testing
Introduction to unit testing
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
Karate for Complex Web-Service API Testing by Peter Thomas
Karate for Complex Web-Service API Testing by Peter ThomasKarate for Complex Web-Service API Testing by Peter Thomas
Karate for Complex Web-Service API Testing by Peter Thomas
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
 
JavaScript / Web Engineering / Web Development / html + css + js/presentation
JavaScript / Web Engineering / Web Development / html + css + js/presentationJavaScript / Web Engineering / Web Development / html + css + js/presentation
JavaScript / Web Engineering / Web Development / html + css + js/presentation
 
Good Coding Practices with JavaScript
Good Coding Practices with JavaScriptGood Coding Practices with JavaScript
Good Coding Practices with JavaScript
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
mod_rewrite
mod_rewritemod_rewrite
mod_rewrite
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
Rspec
RspecRspec
Rspec
 
Rails and security
Rails and securityRails and security
Rails and security
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
 
Ruby on rails rspec
Ruby on rails rspecRuby on rails rspec
Ruby on rails rspec
 

Kürzlich hochgeladen

Engineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesEngineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesRAJNEESHKUMAR341697
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Arindam Chakraborty, Ph.D., P.E. (CA, TX)
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Servicemeghakumariji156
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapRishantSharmaFr
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdfKamal Acharya
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueBhangaleSonal
 
Hospital management system project report.pdf
Hospital management system project report.pdfHospital management system project report.pdf
Hospital management system project report.pdfKamal Acharya
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Call Girls Mumbai
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.Kamal Acharya
 
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...drmkjayanthikannan
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayEpec Engineered Technologies
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARKOUSTAV SARKAR
 
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptxHOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptxSCMS School of Architecture
 
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments""Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"mphochane1998
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXssuser89054b
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 

Kürzlich hochgeladen (20)

Engineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesEngineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planes
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leap
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
Hospital management system project report.pdf
Hospital management system project report.pdfHospital management system project report.pdf
Hospital management system project report.pdf
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power Play
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptxHOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
 
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments""Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 

RSpec 3: The new, the old, the good

  • 2. Contents 1. Changes from v2.14 to v3.y.z 2. Better Specs reviewed
  • 5. Changes ● New syntax does not use “monkey patching” ● Examples are based on “expectations” over objects
  • 6. </> What is it about? # ‘should’ is “replaced” by ‘expect’ # it ‘stores 5 in its attribute’ do expect(subject.attribute).to eq 5 end
  • 7. </> In one line # One-liner syntax changes accordingly # it { should eq 5 } # Is written like... # it { is_expected.to eq 5 }
  • 8. Migrating ● We can migrate our current specs to the new syntax using github.com/yujinakayama/transpec ● In 3.1.z, there’s still a mechanism to work with the old syntax
  • 10. Changes ● New syntax to stub methods ● Also a new syntax to set expectations on method calls
  • 11. </> How to stub # Old instance.stub(:method) instance.stub(:method).with(<arguments>) instance.stub(:method).with(<arguments>).and_return(<something>) # New allow(instance).to receive(:method) allow(instance).to receive(:method).with(<arguments>) allow(instance).to receive(:method).with(<arguments>)...
  • 12. </> stub on any instance # Old Object.any_instance.stub(:method) Object.any_instance.stub(:method).with(<arguments>) Object.any_instance.stub(:method).with(<arguments>).and_... # New allow_any_instance_of(Object).to receive(:method) allow_any_instance_of(Object).to receive(:method).with... allow_any_instance_of(Object).to receive(:method).with...
  • 13. </> stub chain # Old instance.stub_chain(:method_a, :method_b) # New allow(instance).to receive_message_chain(:method_a, :method_b)
  • 14. </> Method expectations # Old instance.should_receive(:method) instance.should_receive(:method).with(<arguments>) # New expect(instance).to receive(:method) expect(instance).to receive(:method).with(<arguments>)
  • 15. </> ...on any instance # Old Object.any_instance.should_receive(:method) Object.any_instance.should_receive(:method).with(<arguments>) # New expect_any_instance_of(Object).to receive(:method) expect_any_instance_of(Object).to receive(:method).with...
  • 18. </> Many ways to skip an example # Common way # it ‘stores 5 in its attribute’, skip: true do # Giving a reason for the output # it ‘stores 5 in its attribute’, skip: ‘reason’ do # Shortcut # skip ‘stores 5 in its attribute’ do
  • 19. ...or leave it pending
  • 20. Pending should make sense ● When an example inside a pending block passes, RSpec will show an error ● This enforces that all pending blocks are pending for a good reason
  • 23. </> Chaining # You can chain multiple ‘matchers’ # expect(subject.attribute). to start_with(‘hello’).and end_with(‘world’) expect(subject.attribute). to start_with(‘hello’).or start_with(‘goodbye’)
  • 24. </> The cooler way # You can chain multiple ‘matchers’ # expect(subject.attribute). to start_with(‘hello’) & end_with(‘world’) expect(subject.attribute). to start_with(‘hello’) | start_with(‘goodbye’)
  • 26. </> A matcher for structures # ‘match’ can validate Hash and Array object structures # let(:structure) { {key: :value, other_key: :other_value} } expect(structure). to match({key: :value, other_key: :other_value}) # Still works for strings and regexps as before
  • 27. =~?
  • 28. </> Match arrays # =~ does not work anymore as an array’s content matcher # Now expect(ary).to contain_exactly(1, 2, 3) # Also in its explicit version expect(ary).to match_array([1, 2, 3])
  • 30. </> Cambios en el ser # ‘be_true’ becomes ‘be_truthy’ expect(true).to be_truthy # ‘be_false’ becomes ‘be_falsey’ or ‘be_falsy’ expect(false).to be_falsey expect(false).to be_falsy # Having better semantics like in... expect(nil).to be_falsey # instead of ‘be_false’
  • 31. </> Cambios en el ser expect(nil).to be_false # Fails expect(nil).to be_falsey # Passes expect(‘hello world’).to be_true # Fails expect(‘hello world’).to be_truthy # Passes
  • 33. The fired matchers ● its github.com/rspec/rspec-its ● have, have_at_least, have_at_most github.com/rspec/rspec-collection_matchers
  • 36. </> Why, oh lord, why? it ‘stores 5 in its attribute if attribute b is 6 and attribute c is 7’ do subject.attribute_b = 6 subject.attribute_c = 7 expect(subject.attribute).to eq 5 end
  • 37. </> Why not just...? context ‘when attribute b is 6’ do # ... context ‘and attribute c is 7’ do # ... it ‘stores 5 in its attribute’ do expect(subject.attribute).to eq 5 end
  • 38. Analysis ● We can find good reasons not to do this: ○ It’s more code ○ It’s cumbersome ○ I’m just a lazy dog ● RSpec is about documentation. ● Documentation takes time. ● Good documentation takes even more time.
  • 40. </> This is not always a bad thing it 'sets the attribute' do subject.very_expensive_loading expect(subject.attribute).to be_kind_of(Fixnum) expect(subject.attribute).to eq(5) end
  • 41. </> ...but sometimes it’s unnecessary it 'stores a fixnum in its attribute' do expect(subject.attribute).to be_kind_of(Fixnum) end it 'its attribute’s fixnum is 5' do expect(subject.attribute).to eq(5) end
  • 42. The right method VS The right result
  • 43. </> ¿What should we test for? it 'sets the attribute to 5' do expect(subject).to receive(:=).with(5) # Dramatization subject.set_attribute(5) end # Instead of it 'sets the attribute to 5' do subject.set_attribute(5) expect(subject.attribute).to eq 5 end
  • 44. Analysis ● Not always unnecessary. ● When it’s an expensive operations like the ones that require access to an outside service, there’s no need to test for its results. (Assume it’s already tested) ● Don’t be scared to raise the coverage of the same method.
  • 46. </> Change the subject when you can it 'returns an array’ do expect(subject.method).to be_kind_of(Array) end it 'returns an array that includes ’foo’' do expect(subject.method).to include(:foo) end it 'returns an array with something else' do # ...
  • 47. </> Change the subject when you can describe '#method’s return value' do subject { instance.method } it 'is an array’ do expect(subject).to be_kind_of(Array) end it 'includes ’foo’' do expect(subject).to include(:foo) end
  • 49. </> ¡¡¡!!! before do @some_value = :foo @some_other_value = :boo @yet_some_other_value = :cmon_bro @again_and_again = :you_are_killing_me end
  • 50. </> And its little brother it 'does something’ do value_a = :foo value_b = :boo value_c = :cmon_bro value_d = :you_are_killing_me expect(instance. method(value_a, value_b, value_c, value_d)). to_not raise_error end
  • 51. </> A relief in sight let(:value_a) { :foo } let(:value_b) { :boo } let(:value_c) { :cmon_bro } let(:value_d) { :you_are_killing_me } it 'does something’ do expect(instance. method(value_a, value_b, value_c, value_d)). to_not raise_error end
  • 52. Analysis ● Reuse of variables (DRY) ● Lazy loading ● Readability (Good documentation)
  • 54. </> Don’t get excited about create let(:model) { create(:model) } # ORLY?
  • 55. </> Don’t get excited about create let(:model) { build(:model) }
  • 56. Analysis ● create stores in the database. ● I mean, it stores in the database. ● Do we really need to persist? ● build is new without save ● The bad thing is that we have to run callbacks manually or setting up our Factory to do so ● Is that bad, anyway?
  • 57. Stub when you have to
  • 58. </> Look what a pretty request # Let’s pretend ‘instance.call_api’ is a very expensive call it 'parses the api response’ do expect(subject.parser(instance.call_api)). to be_kind_of(Hash) end
  • 59. </> Look what a pretty request before do allow(instance).to receive(:call_api). and_return(<valid response from api>) end it 'parses the api response’ do expect(subject.parser(instance.call_api)). to be_kind_of(Hash) end
  • 61. </> Inherited behavior class Foo < Bar # … describe Foo do it ‘serves drinks’ it ‘does whatever a foo does’
  • 62. </> Inherited behavior class Foo < Bar # … shared_examples_for Bar do it ‘serves drinks’ end describe Foo do it_behaves_like Bar it ‘does whatever a foo does’ end
  • 63. Analysis ● Reuse of examples (DRY). ● Consistent behavior across all subclasses. ● The idea is to only verify what’s inherited; we don’t want to test private stuff.
  • 65. David Heinemeier Hansson, creator of Ruby on Rails
  • 66. David Heinemeier Hansson, creator of Ruby on Rails
  • 67. David Heinemeier Hansson, creator of Ruby on Rails
  • 68. David Heinemeier Hansson, creator of Ruby on Rails