測試不變式

2006 年 1 月 5 日

契約設計 (DbC) 和測試驅動開發 (TDD) 的倡導者之間一直存在一場長期的、低調的爭論。我現在不想深入探討這一點,但我會傳達一個將兩者合併的想法,這個想法是在我與 Daniel Jackson 交談時提出的。

在 DbC 中,您為每個類別定義一個不變式。此不變式說明了類別中必須始終為真的屬性。物件必須始終滿足其不變式(除非它正在執行某些操作)。使用 Eiffel,在呼叫方法(在前提條件檢查中)之前和之後(在後置條件檢查中),會自動檢查類別不變式。不變式失敗會擲出例外狀況。(如果為了效能而需要,可以在生產使用中關閉此檢查。)

將這個想法應用於 TDD,表示您定義一個共通的方法來測試生產類別中的不變式,並在測試程式碼中測試它。

現在是提供一個常見的範例的時候了。

public class Bowler ...
    int overs, runs, wickets;

保齡球員的簡單不變式是這些值都應該是正數。因此,您可以定義一個像這樣的不變式。

    public boolean passesInvariant() {
        return (runs >= 0 && overs >= 0 && wickets >= 0);
    }

然後,您將在測試的設定和執行階段後使用它。

    public void testConcedingRunsAddsToRunsScore() {
        Bowler botham = new Bowler();       // setup - showing my age
        assert botham.passesInvariant();
        botham.concedeRuns(4);              //exercise
        assert botham.passesInvariant();
        assertEquals(4, botham.getRuns());  //verify
    }

我自己沒有嘗試過這個方法,我也沒有聽說其他人這樣做。但我認為這是一個有趣的思考,所以提出來分享。