SlideShare a Scribd company logo
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

More Related Content

What's hot

Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpec
Nascenia IT
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API Documentation
SmartLogic
 
TDD, BDD, RSpec
TDD, BDD, RSpecTDD, BDD, RSpec
TDD, BDD, RSpec
Nascenia IT
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Rails
benlcollins
 
TDD with phpspec2
TDD with phpspec2TDD with phpspec2
TDD with phpspec2
Anton Serdyuk
 
Clean Code
Clean CodeClean Code
Clean Code
Nascenia IT
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
CiaranMcNulty
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Stories
rahoulb
 
Introduction to Python decorators
Introduction to Python decoratorsIntroduction to Python decorators
Introduction to Python decorators
rikbyte
 
RSpec
RSpecRSpec
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
olegmmiller
 
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
Ryan M Harrison
 
Testing JS with Jasmine
Testing JS with JasmineTesting JS with Jasmine
Testing JS with Jasmine
Evgeny Gurin
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
Marco Otte-Witte
 
Excellent
ExcellentExcellent
Excellent
Marco Otte-Witte
 
Zero to Testing in JavaScript
Zero to Testing in JavaScriptZero to Testing in JavaScript
Zero to Testing in JavaScript
pamselle
 
Practical Ext JS Debugging
Practical Ext JS DebuggingPractical Ext JS Debugging
Practical Ext JS Debugging
Shea Frederick
 
Rspec
RspecRspec
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
CiaranMcNulty
 
Write codeforhumans
Write codeforhumansWrite codeforhumans
Write codeforhumans
Narendran R
 

What's hot (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
 

Similar to RSpec 3: The new, the old, the good

Introduction to unit testing
Introduction to unit testingIntroduction to unit testing
Introduction to unit testing
Artem Shoobovych
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
David 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 Thomas
intuit_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 Workshop
Wolfram 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 Forwarding
Francesco 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/presentation
M Sajid R
 
Good Coding Practices with JavaScript
Good Coding Practices with JavaScriptGood Coding Practices with JavaScript
Good Coding Practices with JavaScript
🏁 Pierre-Henry Soria 💡
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
noelrap
 
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
Daniel Spector
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
mod_rewrite
mod_rewritemod_rewrite
mod_rewrite
guest9912e5
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
taggg
 
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
Brian Sam-Bodden
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
Duda Dornelles
 
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
Tchelinux
 
Rspec
RspecRspec
Rails and security
Rails and securityRails and security
Rails and security
Andrey Tokarchuk
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
vilniusjug
 
Ruby on rails rspec
Ruby on rails rspecRuby on rails rspec
Ruby on rails rspec
Bindesh Vijayan
 

Similar to 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
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
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
 
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
 

Recently uploaded

International Conference on NLP, Artificial Intelligence, Machine Learning an...
International Conference on NLP, Artificial Intelligence, Machine Learning an...International Conference on NLP, Artificial Intelligence, Machine Learning an...
International Conference on NLP, Artificial Intelligence, Machine Learning an...
gerogepatton
 
Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...
Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...
Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...
University of Maribor
 
ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024
Rahul
 
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECTCHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
jpsjournal1
 
Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
mamamaam477
 
Casting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdfCasting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdf
zubairahmad848137
 
TIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEM
TIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEMTIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEM
TIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEM
HODECEDSIET
 
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have oneISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
Las Vegas Warehouse
 
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
insn4465
 
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsKuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
Victor Morales
 
Iron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdf
Iron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdfIron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdf
Iron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdf
RadiNasr
 
Question paper of renewable energy sources
Question paper of renewable energy sourcesQuestion paper of renewable energy sources
Question paper of renewable energy sources
mahammadsalmanmech
 
New techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdfNew techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdf
wisnuprabawa3
 
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.pptUnit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
KrishnaveniKrishnara1
 
Eric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball play
Eric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball playEric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball play
Eric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball play
enizeyimana36
 
Textile Chemical Processing and Dyeing.pdf
Textile Chemical Processing and Dyeing.pdfTextile Chemical Processing and Dyeing.pdf
Textile Chemical Processing and Dyeing.pdf
NazakatAliKhoso2
 
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesHarnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Christina Lin
 
A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...
nooriasukmaningtyas
 
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student MemberIEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
VICTOR MAESTRE RAMIREZ
 
5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...
5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...
5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...
ihlasbinance2003
 

Recently uploaded (20)

International Conference on NLP, Artificial Intelligence, Machine Learning an...
International Conference on NLP, Artificial Intelligence, Machine Learning an...International Conference on NLP, Artificial Intelligence, Machine Learning an...
International Conference on NLP, Artificial Intelligence, Machine Learning an...
 
Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...
Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...
Presentation of IEEE Slovenia CIS (Computational Intelligence Society) Chapte...
 
ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024
 
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECTCHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
 
Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
 
Casting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdfCasting-Defect-inSlab continuous casting.pdf
Casting-Defect-inSlab continuous casting.pdf
 
TIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEM
TIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEMTIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEM
TIME DIVISION MULTIPLEXING TECHNIQUE FOR COMMUNICATION SYSTEM
 
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have oneISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
 
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
哪里办理(csu毕业证书)查尔斯特大学毕业证硕士学历原版一模一样
 
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsKuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
 
Iron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdf
Iron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdfIron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdf
Iron and Steel Technology Roadmap - Towards more sustainable steelmaking.pdf
 
Question paper of renewable energy sources
Question paper of renewable energy sourcesQuestion paper of renewable energy sources
Question paper of renewable energy sources
 
New techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdfNew techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdf
 
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.pptUnit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
 
Eric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball play
Eric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball playEric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball play
Eric Nizeyimana's document 2006 from gicumbi to ttc nyamata handball play
 
Textile Chemical Processing and Dyeing.pdf
Textile Chemical Processing and Dyeing.pdfTextile Chemical Processing and Dyeing.pdf
Textile Chemical Processing and Dyeing.pdf
 
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesHarnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
 
A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...
 
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student MemberIEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
 
5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...
5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...
5214-1693458878915-Unit 6 2023 to 2024 academic year assignment (AutoRecovere...
 

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