我需要一個單元測試來確保我正確地累計休假時間。但假期時間根據商業規則積累,如果規則改變,則單元測試會中斷。如何測試業務規則?
這是可以接受的嗎?我應該通過一種方法公開規則,然後從我的代碼和我的測試中調用該方法,以確保單元測試不那麼脆弱?
我的問題是:單元測試可能會改變的業務規則的正確方法是什麼?
我需要一個單元測試來確保我正確地累計休假時間。但假期時間根據商業規則積累,如果規則改變,則單元測試會中斷。如何測試業務規則?
這是可以接受的嗎?我應該通過一種方法公開規則,然後從我的代碼和我的測試中調用該方法,以確保單元測試不那麼脆弱?
我的問題是:單元測試可能會改變的業務規則的正確方法是什麼?
您的測試應確保代碼正確遵守業務規則。因此,我不會編寫圍繞業務規則的測試或依賴業務規則代碼本身。相反,當業務規則發生變化時,我會首先更改測試以反映新的業務規則,然後當我的代碼不再通過測試時,請去修復代碼,使其通過測試。
你不想發生的事情就是編寫你的測試,這樣當你改變如何應用相同的業務規則時,測試就會中斷。說起來容易做起來難,但基本上你想測試的是實現規則所需的最低要求,而不是過分狹窄地規定代碼的實現。但是,如果規則的結果不同,那麼您應該先更改測試,然後再更改代碼以匹配它。
您也不希望測試與特定數據耦合。假設在進行稅務計算時,不應將您的測試寫爲假設受測班級使用5%作爲稅收。相反,您應該編寫測試,以便提供稅率,然後檢查計算是否正確完成。據推測,你將有一系列的值來測試,以確保超出範圍的值也被捕獲。這樣做的一個結果是,您將擁有更好的設計,因爲這將幫助您避免硬編碼值,並使生產代碼更靈活地適應數據更改。
我有一個類似的設置 - 但是我的業務規則已編譯,但具有可配置的選項(您可能會有所不同)。當業務規則改變其運作的核心方式時,我的單元測試就會中斷。這實際上是預期的 - 而且很好!這意味着我可以隔離整個系統中的任何意外漣漪,並更新測試以匹配更改。
如果您的規則是外部的(某種腳本語言或數據庫存儲過程),那麼您將需要將它們包裝在集成測試中,並將自動執行的集成測試連接起來。雖然不再是單元測試,但集成測試也相當重要,並將以與單元測試相同的方式幫助您,以防止由於業務規則更改而導致的意外漣漪。
如果規則發生變化,測試就會失敗 - 這是可以預料的。
如果您在測試本身中使用數據夾具而不是硬編碼值,那麼您可以更容易地在將來維護測試。例如,如果你的方法應該返回foo,你可以在燈具中找到它。當您更改業務邏輯時,只需更改燈具,而不必通過單元測試。
當然,這很大程度上取決於您正在測試的邏輯類型,可能並不總是適用。
這聽起來像你有業務規則,然後你有這些業務規則的客戶端。如果這兩者可以獨立變化,那麼相應地設計您的API將是明智的。
如上所述,您的問題聽起來像是可以通過適當使用策略模式來解決。該策略代表您的業務規則,因此您可以在純粹的環境中對其進行單元測試,而無需擔心客戶端。
當業務規則發生變化時,將原有策略保持原樣(以備日後再次使用時),並編寫(和單元測試)代表新業務的全新策略規則。
當您完全使用新策略時,您可以在客戶端中替換策略。
當單元測試客戶端時,您應該對測試雙重策略(如模擬或存根)執行此操作,以驗證客戶端與策略正確交互而不依賴任何特定的策略實施。
通過這種方式,您可以清晰地分離問題並保持單元測試的可維護性。你也遵守開放/封閉原則。
我認爲這是不正確的問題 業務規則和單元測試處於不同的抽象級別。 業務規則處於最高抽象層次(業務建模),但是單元測試用於測試處於最低抽象級別的代碼單元,因此您不能使用單元測試來驗證或驗證業務規則。 此外,分析和設計後的業務規則可能會影響多個代碼單元,因此不能使用單元測試來驗證或驗證業務規則。 我認爲您可以使用測試用例或BDD方案來驗證和驗證業務規則。
這是完全錯誤的,通過嘲笑應用業務規則的對象下的圖層,您可以完全將業務層隔離爲單個單元,因此單元測試它。 – Walfrat 2016-06-28 08:22:08
當您更改規則時,您將更改預期結果。這意味着過去通過的一些正面的單元測試失敗了,並且一些曾經通過的負面測試(通過檢測錯誤)現在可能會失敗(儘管這通常不太常見)。單元測試只能驗證當前的規則 - 在規則更改之前,它們無法驗證規則的所有更改。當規則發生變化時,單元測試也可能會發生。 – 2009-06-20 22:03:18