專項練習 · 8 分鐘閱讀

Python assert 練習:用斷言測試函式

斷言是你對程式做出的聲明。聲明為假時,Python 會拋出 AssertionError 並停止目前路徑。只要不把它和輸入驗證混為一談,assert 就是很好的教學和測試工具。

寫出預期結果

assert add(2, 3) == 5 把預期變成可執行程式碼。實現變化時,檢查會在確切的行失敗。每個斷言只關注一個行為,失敗原因就更容易診斷。

def add(a, b):
    return a + b
assert add(2, 3) == 5
print("ok")

一個清楚的聲明

加上說明差距的訊息

斷言失敗時會顯示逗號後的訊息。寫清預期值,必要時也寫實際輸入。避免只寫 failed 之類的訊息,它只是重複例外已經表達的內容。

def double(n):
    return n * 2
try:
    assert double(3) == 7, "double(3) should be 6"
except AssertionError as error:
    print(error)

有用的失敗訊息

捕獲失敗來研究它

AssertionError 是普通例外,小範例可以捕獲它並列印訊息。真實測試中應讓失敗傳給測試執行器。把失敗藏起來,就失去了檢查的意義。

try:
    assert 1 == 2, "one is not two"
except AssertionError as error:
    print(error)

查看失敗,而不是掩蓋它

同時測試正常值和邊界值

對 2 和 3 正常的函式,遇到 0、空列表或負數仍可能出錯。每組小測試至少加一個邊界情況。斷言讓這些情況成為程式碼的一部分,而不是一句註解。

def total(values):
    return sum(values)
assert total([]) == 0
assert total([1, 2, 3]) == 6
print("boundary and normal cases pass")

加入一個邊界情況

知道 assert 不適合什麼

不要用 assert 驗證密碼、權限或使用者輸入。Python 的 -O 參數會移除 assert 語句,用這種方式寫的安全檢查可能直接消失。驗證時應拋出 ValueError 或自定義例外。

def positive(n):
    if n <= 0:
        raise ValueError("n must be positive")
    return n
print(positive(3))

驗證應該寫在 if 裡

你的練習清單

常見問題

assert 可以被禁用嗎?

可以。用 -O 執行 Python 會移除 assert 語句,所以不能用它保護安全或必需驗證。

assert 拋出什麼例外?

AssertionError。可選訊息會成為例外文字。

每個函式都應該寫斷言嗎?

不需要。把斷言放在假設重要、失敗必須明顯的地方,尤其是測試和內部輔助函式。

練習斷言

12 道題,覆蓋 assert、訊息、AssertionError、邊界情況和輸入驗證。

打開練習

繼續閱讀: