[unit-testing] 單元測試中的隨機數據?


Answers

這種測試稱為猴測試 。 如果做得對,它可以從真正黑暗的角落吸出蟲子。

為了解決您對可重複性的擔憂:正確的方法是記錄失敗的測試條目,生成一個單元測試,該測試針對特定錯誤的整個家族 ; 並在單元測試中包含導致初始故障的一個特定輸入(來自隨機數據)。

Question

我有一位同事為對象填寫單元測試,這些對象使用隨機數據填充字段。 他的理由是它提供了更廣泛的測試,因為它會測試很多不同的值,而正常測試只使用一個靜態值。

我給了他很多不同的原因,主要的原因是:

  • 隨機值意味著測試不是真正可重複的(這也意味著如果測試可以隨機失敗,它可以在構建服務器上這樣做並打破構建)
  • 如果它是一個隨機值,並且測試失敗,我們需要a)修復這個對象,並且b)強迫我們每次都測試這個值,所以我們知道它是有效的,但是因為它是隨機的,所以我們不知道這個值是什麼

另一位同事補充說:

  • 如果我正在測試異常,則隨機值不能確保測試以預期狀態結束
  • 隨機數據用於清除系統和加載測試,而不是用於單元測試

任何人都可以添加額外的理由,我可以給他讓他停止這樣做嗎?

(或者,這是一種寫入單元測試的可接受的方法,而且我和我的其他同事是錯誤的?)




對於查看測試的人來說,一個好處是任意數據顯然並不重要。 我看過太多涉及數十個數據的測試,可能很難說出需要怎樣的方式以及恰恰如此。 例如,如果地址驗證方法使用特定的郵政編碼進行測試,並且所有其他數據都是隨機的,那麼您可以確定郵政編碼是唯一重要的部分。




在“ 美麗的代碼 ”一書中,有一章叫做“美麗的測試”,他在那里通過二進制搜索算法的測試策略。 其中一段被稱為“隨機測試行為”,其中他創建隨機數組以徹底測試算法。 您可以在谷歌圖書網頁上閱讀第95頁的在線書籍,但這是一本值得擁有的好書。

所以基本上這只是表明生成隨機數據進行測試是一個可行的選擇。




如果你的傢伙沒有看到他是否已經修好了,你怎麼能再次進行測試? 即他失去了測試的可重複性。

雖然我認為在測試中扔掉大量隨機數據可能有一定的價值,正如其他回復中提到的,它在負載測試的標題下比其他任何內容都要多。 這幾乎是一種“希望測試”的做法。 我認為,實際上,你的傢伙根本就沒有想到他想要測試什麼,並且通過希望隨機性彌補這種缺乏想法最終會陷入一些神秘的錯誤。

所以我和他一起使用的論點是他很懶惰。 或者換一種說法,如果他沒有花時間理解他想要測試的東西,那可能表明他並不真正了解他正在編寫的代碼。




你應該問自己什麼是你的測試的目標。
單元測試關於驗證邏輯,代碼流和對象交互。 使用隨機值試圖實現不同的目標,從而減少測試重點和簡單性。 出於可讀性的原因(生成UUID,ID,密鑰等)是可以接受的。
特別是對於單元測試,即使這種方法成功發現問題,我也無法回想起來。 但是我看到很多確定性問題(在測試中)試圖隨機取值,主要是隨機日期。
模糊測試是集成測試端到端測試的有效方法。




如果您使用隨機輸入進行測試,則需要記錄輸入,以便查看這些值。 這樣,如果遇到某種邊緣情況,您可以編寫測試來重現它。 我聽說過人們不使用隨機輸入的相同原因,但是一旦您了解了用於特定測試運行的實際值,那麼它就不是什麼問題。

“任意”數據的概念作為一種表示不重要的東西的方式也非常有用。 我們有一些可以接受的驗收測試,因為有很多噪聲數據與手頭測試無關。




我們今天剛碰到這個。 我想要偽隨機 (所以它看起來像壓縮音頻數據的大小)。 我想我也想要確定性 。 rand()在OSX上與Linux上不同。 除非我重播種子,否則它可能隨時改變。 所以我們將它改為確定性的,但仍然是隨機的:測試是可重複的,與使用罐裝數據一樣多(但更方便書寫)。

不是通過代碼路徑的一些隨機蠻力測試。 這就是區別:仍然是確定性的,仍然是可重複的,仍然使用看起來像真實輸入的數據來對複雜邏輯中的邊緣案例進行一系列有趣的檢查。 仍然是單元測試。

這仍然有資格是隨機的嗎? 我們來談談啤酒。 :-)




你的同事正在做fuzz-testing ,儘管他不知道。 它們在服務器系統中特別有用。




Related