簡體   English   中英

如何針對未定義的行為進行單元測試?

[英]How can I have unit tests for undefined behaviour?

我有一組相關的類,它們接受各種輸入並產生預期的輸出。 這些都是進行單元測試的理想低水平候選人,並且對於有效的輸入都非常有效。

困難來自於無效輸入,尤其是在嘗試從未添加的集合中刪除項目時,當前我們尚不確定行為:某些類只會產生垃圾結果(GIGO 1獲勝),而某些類會拋出異常(也許是KeyNotFoundException )。

鑒於這些無效輸入沒有有效且一致的行為(這意味着某些東西在其他地方被錯誤配置,並且不會產生任何有意義的結果),並且我們的API明確聲明調用者必須僅刪除他們添加的內容,如何這可以反映在我們的單元測試中嗎?

顯然,它不能作為“測試”,因為沒有定義的行為(如果將來對其中任何一種的實現進行更改,則記錄我們當前的行為將很脆弱),但是我想有一種方法來排除這種可能性一些熱心的團隊成員將來會增加一個,而不會意識到潛在的問題。

其中之一的單元測試方法當前看起來像這樣:

[TestCase("1", "2", "1", ExpectedResult = "|2|")]
[TestCase("1", "2", "2", ExpectedResult = "|1|")]
public object InsertTwoDeleteOne(string insertedValue1,
                                 string insertedValue2,
                                 string deletedValue1)
{
    // Apply tests here
}

我可以看到的兩種處理方式是在測試方法中按照以下方式添加顯式代碼:

    if (deletedValue1 != insertedValue1 &&
        deletedValue1 != insertedValue2)
    {
        Assert.Fail("Invalid inputs");
    }

但這是“脫節的”,並且在其他測試用例中不那么容易看到,或者通過添加一個TestCase ,該TestCase純粹用於說明“不要運行此文件”的文檔,例如:

[TestCase("1", "2", "3", Ignore = true, Reason = "Invalid inputs")]

但這會產生“跳過的測試”結果,這是不完整的。

有更好的嗎?


[編輯]所討論的API是一個公共接口,我們在產品中有許多實現:我正在更新這些測試的過程中正是這些實現。 但是,安裝可以自由地將自己的實現編寫為插件(通過創建自己的程序集,實現自己的對象並通過配置實例化它們),因此我們的框架將確保在調用它們之前數據是有效的。

在我們當前的模型中,安裝不太可能會重復使用對象並從自己的代碼中調用它們。

我們選擇不考慮驗證每個對象中數據的原因有兩個:

  1. 在我們的默認產品配置中,它將始終接收已由調用方驗證的數據。
  2. 性能:我們在此處存儲大量數據-當前限制為100,000行數據(該行中每個字段中有一個對象,因此總共可能有20到50個對象),但是我們的客戶已經在要求將該限制提高到1,000,000-因此我們已經在調用代碼中存儲了數據的字典,因此我們可以在此處進行驗證,我們將必須在這些對象中存儲數據的副本。 如果它們僅是當前限制的double則在20MB至50MB之間,或者在預計的未來需求上為200MB-500MB。

這是我們當前不需要做的事情的巨大開銷!


1警告:有些人可能不希望在辦公室使用Google搜索!

這可能取決於項目的關鍵性和質量標准,但是我的直覺是通常不要讓“不確定的行為”潛入您的系統中,尤其是在產生“垃圾結果”的情況下。

您說您擔心一個熱心的團隊成員會對該套件添加不一致的測試。 您可能會假設團隊成員將始終在編寫生產代碼之前添加測試,從而遇到“欄桿”測試,但是如果不這樣做,該怎么辦? 主要安全措施不是一開始就防止他們以錯誤的方式使用API (即正確處理邊緣情況)嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM