2017/10/19

Ruby - RSpec 的使用方法

RSpec 簡介

RSpec 在執行的時候不保證執行順序,每個測試產生的資料不會自動被清除。

新增測試的generator語法:

rails generate rspec:model user

這樣寫會建立一個檔案在 spec/models/user_spec.rb

執行測試的指令是在 rails 專案目錄下輸入以下指令:

# 這裡是 bash

# 執行所有測試
rspec

# 執行某個資料夾下的所有測試
rspec ./spec/models

# 執行某個檔案裡的所有測試
rspec ./spec/models/user_spec.rb

# 執行某個檔案裡的某個測試
rspec ./spec/models/user_spec.rb:8

簡單的範例

require 'rails_helper'

RSpec.describe "規格說明" do
  describe "處於某個狀態下" do
    # 設定狀態變數
    let(:a) { 1 }
    it "should be 1" do
      puts "should be 1"
      expect(a).to eq(1)
    end
  end
end

let 在每次測試裡,第一次存取變數時就會執行對應的程式

require 'rails_helper'

RSpec.describe "規格說明" do
  describe "處於某個狀態下" do
    let(:a) { puts "let a"; 1  }
    it "1" do
      puts "1"
      puts "a=#{a}"
    end
     it "2" do
      puts "2"
      puts "a=#{a}"
      puts "a=#{a}"
      puts "a=#{a}"
    end
  end
end

輸出

1
let a
a=1
.2
let a
a=1
a=1
a=1
.

before 和 after 會在所有測試的執行前後做事

RSpec.describe "規格說明" do
  describe "處於某個狀態下" do
    before { puts "before" }
    after { puts "after" }
    it "1" do
      puts "1"
    end
    it "2" do
      puts "2"
    end
  end
end

執行結果

before
1
after
.before
2
after
.

因為測試對資料庫的操作會互相影響,如果想要確保每個測試都是在資料庫乾淨的狀態下,可以使用 database_cleaner

require 'database_cleaner'
...
RSpec.configure do |config|
...
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
...
end

其中的 before、around 可以參考官網說明文件:https://relishapp.com/rspec/rspec-core/v/2-13/docs/hooks/before-and-after-hooks#before/after-blocks-defined-in-config-are-run-in-order

如果想要控制 rspec 執行每一個 test 的順序,可以這樣寫:

# 這裡是 bash
rspec --order defined
rspec --seed 1

詳細的介紹可以參考 https://relishapp.com/rspec/rspec-core/docs/command-line/order

如果想要把結果輸出到檔案,可以這樣寫:

# 這裡是 bash
rspec --out result.txt
rspec --format documentation --out result.txt

上面兩行會使檔案內容不同,詳細的介紹可以參考 https://relishapp.com/rspec/rspec-core/v/2-4/docs/command-line/format-option

沒有留言: