SlideShare a Scribd company logo
1 of 52
Download to read offline
進擊的RSpec
by Fred Hung
測試撰寫要點
測試就是規格(readable)
先寫規格-> 再寫程式碼(TDD)
測試就是要定義安全範圍
RSpec 基本寫法
describe 描述
https://www.betterspecs.org/#describe
# instance method
describe `#full_name` do
end
# class method
describe `.activated`
require `spec_helper`
describe "User" do
end
# 可以直接改成 describe User
describe User do
# described_class 就變成 User
# 會⾃動宣告⼀個
# subject { User.new}
end
subject
有⼈建議subject 要定義在⼀開始,才知道你現在是在測什麼主題
describe User do
# subject 有沒有給名字都可以
subject(:user) { User.new(first_name: 'Fred', last_name: 'Hung')}
it 'is valid' do
expect(user).to be_valid
end
# 可以直接改成
it { is_expected.to be_valid }
end
context
# 不好的寫法
it 'if user without first name it is invalid' do
end
⽤context 把情境抽出來
context 'when user without first name' do
it { is_epected.to be_invalid }
end
let
lazy load
可以nested
https://www.betterspecs.org/#let
bad
describe '#type_id' do
before { @resource = FactoryBot.create :device }
before { @type = Type.find @resource.type_id }
it 'sets the type_id field' do
expect(@resource.type_id).to eq(@type.id)
end
end
good
describe '#type_id' do
let(:resource) { FactoryBot.create :device }
let(:type) { Type.find resource.type_id }
it 'sets the type_id field' do
expect(resource.type_id).to eq(type.id)
end
end
搭配 context ,蹦出好滋味
describe User do
subject(:user) { User.new(first_name: first_name)}
let(:first_name) { 'Fred' }
context 'when user without first name' do
let(:first_name) { nil }
it { is_epected.to be_invalid }
end
end
⼀般建議pattern
1. define subject
2. set the config values
3. assert a valid state
4. mutate (context)
Hook
https://relishapp.com/rspec/rspec-core/v/3-10/docs/hooks
設定資料/ 清理
around
before
after
around
⽤法: 例如Timecop
around { |example| Timecop.freeze(Time.zone.local(2020, 12, 9), &example) }
VCR
around(:each){ |example| VCR.use_cassette("adyen/doku_indomaret_payment_method"){ example.run } }
before / after
注意lifecycle
before :suite
before :context # 這就是 :all
before :example # 這就是 :each
after :example
after :context
after :suite
# hook 可以 nested
RSpec.describe "before and after callbacks" do
before(:context) do
puts "outer before context" # 1
end
example "in outer group" do
end
after(:context) do #4
puts "outer after context"
end
describe "nested group" do
before(:context) do
puts "inner before context" #2
end
example "in nested group" do
end
after(:context) do
puts "inner after context" #3
end
end
end
before(:all) 裡⾯不能⽤ let
before == before(:each) ,每次都會執⾏⼀遍,複層scope 也會依
序執⾏⼀遍
Rubocop RSpec 建議⼀個Group 只有⼀個before / after
Matcher
就是 be eq 這種⽤來比較的運算式
常⾒的資料型態都有matcher 可以⽤
基本款 be eq (注意是否需比對物件本⾝)
be_*
Array / Hash 的比對
物件的比對
json 的比對
be_*
# 只要物件本⾝可以⽀援 xxx?
# 例如 user.admin?
# 就可以⽤ be_xxx matcher
describe User do
subject { User.new(role: role) }
let(:role) { :normal}
context 'when user role is admin' do
let(:role) { :admin }
it { is_expected.to be_admin }
end
end
Array / Hash 比對
include
contain_exactly
物件比對
Person = Struct.new(:name, :age)
person = Person.new("Jim", 32)
expect(person).to have_attributes(:name => "Jim", :age => 32)
expect(person).to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) )
json 比對
https://relishapp.com/waterlink/rspec-json-expectations/docs/json-
expectations
RSpec.describe "A json response" do
subject { '%{SIMPLE_JSON}' }
it "has basic info about user" do
expect(subject).to include_json(
id: 25,
email: "john.smith@example.com",
name: "John"
)
end
end
其他
shoulda_macther
DRY
share example
share context
helper
shared example
# spec/support/shared_examples/some_examples.rb
RSpec.shared_examples "some example" do |parameter|
let(:something) { parameter }
it "uses the given parameter" do
expect(something).to eq(parameter)
end
end
RSpec.describe SomeClass do
include_examples "some example", "parameter1"
# 或
it_behaves_like "some example", "parameter1"
end
shared contex
要注意,使⽤shared context 的時候該執⾏的都會被執⾏(例如有
before(:context) / before 這種)
⾃訂helper
可以寫⾃⼰的helper method
或者⾃⼰定義matcher
如果比對很複雜,可以⽤helper 增加可讀性
# spec/support/helper/some_helper.rb
# note: 通常 在 spec_helper 會 require support 下的所有東⻄
module SomeHelper
extend ActiveSupport::Concern
class_method do
# 這裡就是 extend 啦
def say_class_method
puts "class_method!!!"
end
end
# 這裡就是 include 啦
def say_helper_method
puts "helper_method!!!"
end
end
RSpec.configure do |config|
config.include SomeHelper, :say_some_module
end
測試時候可以這樣⽤
RSpec.describe FredRock, :say_some_module do
say_class_method
it "some spec" do
say_helper_method
end
end
假物件
名詞解釋
stub
假物件,假⾏為,但是不會去測他
Mock
假物件,假⾏為,會去測是否有被呼叫到
spy
假物件,去測是否有收到messages
在rspec 中使⽤要注意scope 問題
FactoryBot
https://github.com/thoughtbot/factory_bot
FactoryBot
基本寫法
nested factory
trait
initialize_with
transient
callback
沒有需要存的可以⽤ build(:some_factory)
Timecop
⽤來時空旅⾏的,要注意 travel 和 freeze 的差別
describe "some set of tests to mock" do
before do
Timecop.freeze(Time.local(1990))
end
after do
Timecop.return
end
it "should do blah blah blah" do
end
end
Database cleaner
測試的隔離策略
Base ussage
https://github.com/DatabaseCleaner/database_cleaner
DatabaseCleaner.strategy = :transaction
# 設定刪除策略
DatabaseCleaner.start # usually this is called in setup of a test
dirty_the_db
DatabaseCleaner.clean # cleanup of the test
# OR
DatabaseCleaner.cleaning do
dirty_the_db
end
Strategy
deletion : 呼叫 DELETE FROM
Truncation : 呼叫 TRUNCATE TABLE
Transaction : BEGIN TRANSACTION ROLLBACK
設定⽅式要依據情況,搭配RSepc 的Hook 使⽤
Best Practice
VCR
錄request
設定
# spec/support/vcr.rb
VCR.configure do |c|
# 指定 cassettes 位置
c.cassette_library_dir = 'vcr/cassettes'
c.hook_into :webmock
# 這⾏可以直接在 rspec 在 describe 上⽤ :vcr
c.configure_rspec_metadata!
# filter 掉 api key
c.filter_sensitive_data('<SOME_API_KEY>') { ENV['SOME_API_KEY'] }
end
使⽤
把測試案例⽤block 包起來,通常可以搭配rspec hook
around(:each){|example| VCR.use_cassette("neweb/writeoff"){ example.run }}
或是直接錄⼀個test group, 但是記得打開configure_rspec_metadata!
# 或者直接錄⼀個 group
describe '#write_off', :vcr do
end
祕技:可以在⼀個測試中使⽤多筆錄製的mock
let(:payment_to_refund_cassettes) do
[
{ name: 'google_play_receipt_cancelled' },
{ name: 'refund_shopify_order' }
]
end
it 'refund payment that receipt is canncelled' do
VCR.use_cassettes(payment_to_refund_cassettes) do
expect { subject.perform }.to change { @payment.state }.from('active').to('cancelled')
end
end
SimpleCov
測試覆蓋率
注意要放在spec helper 最上⾯
unless defined? SimpleCov
# Start SimpleCov if one is not using Spring
require 'simplecov'
SimpleCov.start 'rails'
end
跑完測試後可以去 your_repo/coverage/index.html 看
複雜的service 可以看說測試有沒有蓋到⼀些edge case
Rspec 設定
spec_helper 裡⾯很多⼤秘寶
加速測試
本地端開發
⽤spring 啟動rspec
只執⾏某⼀個測試案例(指定⾏數)
我⽤vim-rspec,其他編輯器看有沒有相關套件好⽤?
CI
Speed up rspec tests
why your spec have slowed down: 有些妙招
How I got RSpec to boot 50 times faster
加速啟動時間
補充- RSpec 寫作風格
Taming Chaotic Specs: RSpec Design Patterns by Adam Cuppy
蒼時- 針對遺留代碼加入單元測試的藝術課程⼼得
蒼時- 撰寫⼀個合適的RSpec 測試
Better Specs
ihower
討論時間

More Related Content

What's hot

PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
julien pauli
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
julien pauli
 

What's hot (20)

Python Compiler Internals Presentation Slides
Python Compiler Internals Presentation SlidesPython Compiler Internals Presentation Slides
Python Compiler Internals Presentation Slides
 
Objective C for Samurais
Objective C for SamuraisObjective C for Samurais
Objective C for Samurais
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from inside
 
Inside Python [OSCON 2012]
Inside Python [OSCON 2012]Inside Python [OSCON 2012]
Inside Python [OSCON 2012]
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
How Xslate Works
How Xslate WorksHow Xslate Works
How Xslate Works
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Embed--Basic PERL XS
Embed--Basic PERL XSEmbed--Basic PERL XS
Embed--Basic PERL XS
 
Inside PHP [OSCON 2012]
Inside PHP [OSCON 2012]Inside PHP [OSCON 2012]
Inside PHP [OSCON 2012]
 
Php and threads ZTS
Php and threads ZTSPhp and threads ZTS
Php and threads ZTS
 
Perl Moderno
Perl ModernoPerl Moderno
Perl Moderno
 
Playfulness at Work
Playfulness at WorkPlayfulness at Work
Playfulness at Work
 
Using Jenkins for Continuous Integration of Perl components OSD2011
Using Jenkins for Continuous Integration of Perl components OSD2011 Using Jenkins for Continuous Integration of Perl components OSD2011
Using Jenkins for Continuous Integration of Perl components OSD2011
 
What's new in Perl 5.10?
What's new in Perl 5.10?What's new in Perl 5.10?
What's new in Perl 5.10?
 
PhpSpec: practical introduction
PhpSpec: practical introductionPhpSpec: practical introduction
PhpSpec: practical introduction
 
Ruby for Java Developers
Ruby for Java DevelopersRuby for Java Developers
Ruby for Java Developers
 
A(n abridged) tour of the Rust compiler [PDX-Rust March 2014]
A(n abridged) tour of the Rust compiler [PDX-Rust March 2014]A(n abridged) tour of the Rust compiler [PDX-Rust March 2014]
A(n abridged) tour of the Rust compiler [PDX-Rust March 2014]
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 

Similar to Better rspec 進擊的 RSpec

JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
Ankur Dongre
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
Ankur Dongre
 
Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02
Ramamohan Chokkam
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
elliando dias
 

Similar to Better rspec 進擊的 RSpec (20)

RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
Introduction to unit testing
Introduction to unit testingIntroduction to unit testing
Introduction to unit testing
 
tree-sitter-objc-slides.pptx
tree-sitter-objc-slides.pptxtree-sitter-objc-slides.pptx
tree-sitter-objc-slides.pptx
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
lab4_php
lab4_phplab4_php
lab4_php
 
lab4_php
lab4_phplab4_php
lab4_php
 
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
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
 
Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02
 
JavaScript Looping Statements
JavaScript Looping StatementsJavaScript Looping Statements
JavaScript Looping Statements
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
PHP-03-Functions.ppt
PHP-03-Functions.pptPHP-03-Functions.ppt
PHP-03-Functions.ppt
 
PHP-03-Functions.ppt
PHP-03-Functions.pptPHP-03-Functions.ppt
PHP-03-Functions.ppt
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 

Recently uploaded (20)

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 

Better rspec 進擊的 RSpec