iT邦幫忙

2022 iThome 鐵人賽

DAY 10
1

前面介紹了 RSpec 的規格與測試,讓大家都能明白 TDD 的測試流程,紅燈、綠燈、優化與重構。接下來,我們會花好幾篇來介紹 RSpec 的 語法。

今天我們先來個簡單的,也是前面看過的基本語法:

describe method

RSpec.describe 主要是用來建立一個 example group,在這一個 example group 裡底下會有許多小 example 來進行測試。

RSpec.describe 後面接的,可以是這一個 example group 的主要目標的描述:

RSpec.describe "Quality Examination" do
	(略)
end

也可以是主要進行的測試功能、類別等、像是前面提到的:

RSpec.describe MobileWallet do
	(略)
end

在這裡,就是以 MobileWallet 這個類別為測試目標。

然後再接 do end 的 block。

因為 Ruby 的 method 慣例是可以省略括號的,所以本來應該是這樣:

RSpec.describe("Quality Examination")
RSpec.describe(MobileWallet)

it method

it 最主要的功能是讓你的測試項目辨識度大幅提升的好幫手,所以我們在寫 it 時,盡量言簡意賅,一句簡短的話就能把你要做的事情描述出來。

在剛剛提到的 describe 會建立一個 example group,而在這個 group 裡,則含有一個以上的 example。這些 examples 就是由 it 所構成:

RSpec.describe "example group" do
 it "example_one" do
 end
 
 it "example_two" do
 end
 
 it "example_three" do
 end
end

執行 rspec 後:

透過 it 的方法,可以很清楚的知道,每一個 example 是在做什麼,跑測試結果時,就能一看就知道是誰有過誰沒過,讓整體的可讀性上升。

it 後面打上 example 的描述後,加上一個 do end 的 block,然後在這個 block 裡,就是要打上測試用的 code:

it "軟體錢包原本有50元,扣款10元後,錢包顯示40元" do
  wallet = MobileWallet.new(50)
  wallet.cost 10
  expect(wallet.total).to be 40
end

expect method

expect 後面帶入受測項目,可以是物件(arr):

RSpec.describe "The length" do
 it "should be 7" do
   arr = [1, 2, 3, 4, 5, 6, 7].size
   expect(arr).to be (7)
 end
end

也可以是方法(two):

def two
 1 + 1
end
RSpec.describe ".two_method" do
  it "should be 2" do
    expect(two).to be (2)
  end
end

也可以是物件屬性:

RSpec.describe MobileWallet do
 describe "扣款功能" do
  it "軟體錢包原本有50元,扣款10元後,錢包顯示40元" do
    wallet = MobileWallet.new(50)
    wallet.cost 10
    expect(wallet.total).to be 40
  end
end

也可以是邏輯運算:

RSpec.describe "cal" do
 it "should be even" do
   expect((1 + (1 * 3) ** 2) % 2 ).to be (0)
 end
end

這些引數帶入 expect 後,expect 會進行運算,並回傳一個物件,這個物件則包含 @target 這個實體變數,而這個實體變數本身,帶有一些實體方法,像是 to, not_to。

to method

to 是 expect 產出的物件內包含的實體方法,用來承接 matcher method,讓expect 跟 matcher 可以互相比較。

另外還有一個叫 not_to,從字面上的意思就可以知道是 to 的反義。

matcher method

matcher method 是負責配對、比較 expect method 所生之物件與 matcher method 所生之物件是否一致。
我們前幾天測試用的 be 就是其中一個 matcher method,另外還有 eq 與 eql,三者在使用上有不同的差異。

依照嚴謹程度來區分:eq < eql < be。

eq:只要值一樣就好。
eql:值與型別都要一樣。
be / equal:不止值與型別,連記憶體位置都要一樣。

RSpec.describe "same or different" do
  let(:a) { 1234 }
  let(:b) { 1234.0 }
 
  let(:c) { [1234] }
  let(:f) { [1234.0] }
 
  it "should be the same" do
    expect(a).to eq(b)
    expect(a).to eql(b)
 
    expect(c).to eq(f)
    expect(c).to eql(f)
    expect(c).to equal(f)
  end
end

之後我們會提到 let method,先稍微知道一下,let 的小括號為變數,大括號為變數的值。

在這個測試第二個跟第四、五個測試會失敗。

第一個: eq 只在乎「值」,所以即便 a 是 integer,b 是 float,也沒關係。
第二個:但因為 eql 會比較型態,所以上面說的沒關係就有關係了,因此這裡就無法通過。
第三個:如第一個所述。
第四個:如第二個所述。
第五個:equal 還會在意記憶體位置是不是一樣,所以執行下去跑出的錯誤。

也把兩個記憶體位置表明出來,由此可知,equal 真的很挑惕(誤),所以 equal / be 比起外在,他也在意內在。

小結

今天介紹了前面測試用到的基本語法,接下來會再介紹其他好用的語法給大家。


上一篇
IT 邦鐵人賽 Day 9 - RSpec 測試完成
下一篇
IT 邦鐵人賽 Day 11 - RSpec 語法 before hook & after hook
系列文
新手也能懂的自動化測試,讓測試帶你飛!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言