撰寫測試的概念

Spy

功能和 Mock 類似,差別是 Spy 不預先設定驗證,而是事後自己去檢查。像是錄影下來,功能跑完之後,再回頭決定要查哪些部分。

from unittest.mock import MagicMock

db = MagicMock()

service.create_note(db, {"title": "測試"})

# The decision on what to check was made afterward
print(db.save.call_count)       # How many times were called?
print(db.save.call_args_list)   # What parameters are passed each time?

可測試的函式

寫 Unit Test 時,要先確保函式是可測試的。以下是兩個常見程式難以測試的主因:

  1. 與外部世界耦合太深(直接操作 DB、HTTP、檔案)
  2. 函式太長,包含多個邏輯責任

解決辦法主要就是重構,而方向可以規劃成:

這樣就能在測試時注入假的物件或 mock,而不用真的連外。而所有新開發的程式碼,如果都有預設要求 Unit Test 的覆蓋,則自然而然開發的函式就都會有這些可測試性了。$^{[1]}$

pytest 基礎概念

Pytest 是一個基於 Python 的測試框架。

測試框架

測試框架是一套幫你寫、組織、執行測試的工具。如果沒有測試框架,我們要自己測試一個函式,大概會這樣寫:

result = divide(6, 3)
if result != 2:
    print("Test Failed")
else:
    print("Test Passed")

這樣很麻煩,每個測試都要自己寫判斷、自己印結果,測試一多就會很難管理。測試框架幫我們解決這些問題,主要提供三件事: