{{ currentPost.title }}
{{ currentPost.datetime }}

前言

這是 Test Prescription 這本書部分內容的筆記整理,如果你對這篇文章有興趣,強烈建議你去讀讀這本書。

Fixtures的特性

  • fixtures適用在任何的test framework。
  • fixtures定義在測試一開始時測試資料的初始狀態,也就是每跑完一個測試案例就會恢複測試資料變成初始狀態。
  • fixtures是全域的,也就是所有的測試案例都共用相同的fixtures。

Fixtures的使用範例

下面是一些fixtures的範例:(時間格式、斷行、支援association、支援erb語法但要注意縮排)

spec/fixtures/projects.yml

book:
  name: Write the book
  due_date: 2014-04-14

runway:
  name: Project Runway
  due_date: <%= 1.month.from_now %>
  description: |
    The awesomest project ever.
    It's really, really great.

spec/fixtures/tasks.yml

chapter:
  title: Write a chapter
  project: book

<% 10.times do |i| %>
task_<%=i%>:
  name: "Task <%= i %>"
<% end %>

下面是一個在測試中使用fixture的範例:

spec/models/product_spec.rb

it "should have a default name" do
  project = projects(:book)
  expect(project.name).to eq("Write the book")
end

fixture的載入行為

fixtures預設在跑完每個測試案例就會恢複測試資料,假如想要測試案例之間資料的變換,這個行為就變的很麻煩。你可以在spec/spec_helper.rb中加上config.use_transactional_fixtures = false關閉這個行為,但因為這個設定是全域設定,這會變成所有的測試資料都不會復原,反而失去「復原功能」的好處。簡而言之,如果要測試案例之間資料的變換,不要用fixtures來做這件事。

fixture的優點

  • 快,因為它不做資料庫的insert,而是直接將資料載入到ActiveRecord的object中。
  • 每個測試案例都可以使用它,對於要設定全域資料(全域資料:雖然是為了方便修改而儲存在資料庫中,但很少變動的資料)非常好用。

fixture的缺點

  • 它是全域的,如果你設定了很多的fixtures,表示跑每一個測試案例都要重複載入這些fixtures。
  • 它是擴散的,如果你在model中加入了新的association,這意味著你必須要去修改對應的fixtures將這些association設定好。
  • 無法一眼就就能從測試檔案中得知fixtures定義的值,也就是還要把fixtures檔案翻出來看。
  • 一旦加入了新的測試資料到原本fixtures,因為它的全域的,所以有可能會破壞原本已經通過的測試。