2014-06-25 114 views
3

與編寫具有部分隨機性的代碼的測試相比,具有預定義輸入和輸出參數的測試代碼相對容易,因爲我們必須檢查隨機生成器是否存在偏差。如何編寫隨機輸出的jUnit測試?

使用隨機數的庫的一個示例是java.util.Collections.shuffle(List<?> list),後面是http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle後面的對象集合的混洗。

如何編寫具有隨機輸出的代碼的jUnit測試?不僅適用於洗牌,而且一般測試隨機性。

+1

http://stackoverflow.com/questions/56411/how-to-test-random-case-in-point-shuffling –

+0

stackoverflow.com/questions/56411/...是關於洗牌。這是這個問題的一個子部分。 –

+0

@AlexandreSantos爲什麼對於這個問題的接受答案仍然適用? – awksp

回答

2

除非您正在編寫一個實際的隨機數生成器或某種依賴於安全隨機數生成器的加密庫,否則不需要檢查隨機數生成器是否存在偏差。這是隨機數字生成器的作者的工作。

Collections.shuffle()的例子也是一個不好的例子,因爲它是一個內置的JDK方法。沒有理由測試內置的JDK方法,Java的作者已經爲您做了這些工作,加上過去20年來使用這些方法的數百萬用戶。您是否也有測試來確認System.out.print()的工作是否如預期的那樣?

單元測試應該是確定性的。每次重複運行相同的測試應該每次都會產生相同的結果。如果他們不這樣做並且測試失敗,是否因爲代碼錯誤或因爲非確定性輸出產生無效輸入而失敗?如果重新運行結果,測試通過,是因爲錯誤是固定的,還是因爲我們偶然得到了隨機輸入?

由於這些原因,您的單元測試應該嘗試模擬或者刪除任何隨機性。也許寫幾個測試來執行數據的特定轉換以測試邊界條件。例如,對於shuffle()可能有一個測試,按特定順序對元素進行重新排序,或者按照升序或降序對元素進行排序,或者對某個測試沒有進行任何轉換等。這些都是可以隨機發生的有效結果。

這種方式每次測試都會爲相同的輸入產生相同的輸出,並且您可以從不同的結果中獲益。

編輯 看來你真的想測試你自己的隨機數發生器。

這裏是描述統計檢驗環節,你應該做的,看看它是否真的是隨機的(或至少儘可能的隨機)

RANDOM.ORG statistical analysis

NIST statistical test suite

+0

我沒有表明我想測試洗牌。我相信Sun/Oracle已經做到了。我只是把它作爲一個隨機代碼的例子。但是,我可以使用另一個例子,例如在線遊戲網站的隨機數發生器。對於在線遊戲網站來說,隨機數發生器確實是隨機的是很重要的。 –

+0

@AlexandreSantos添加了實際測試RNG的鏈接 – dkatzel

+0

我想知道同樣的事情。我知道我的方法有效,因爲我看到了應用程序主要的結果。雖然,我是Junit測試的新手,但我想知道如何使用Junit測試來確定一副牌是否被洗牌。從你的回答中,似乎沒有辦法。對於有原始問題的人,我建議你使用main來運行該方法並查看輸出。這就是我如何檢查我的洗牌卡片方法 – Sedrick