[英]Best practice: testing code which uses a random number generator
在代碼中的某個地方(深層,深層)說一下,我正在使用隨機數來做一些很棒的事情。 測試通常應該是確定性的,而這部分代碼的發行版的行為明確地利用了隨機數生成器的不確定性/隨機性。
因此,要進行確定性(功能性)測試,我想設置一個固定的種子值:
size_t seed = 42;
std::mt19937 rng;
rng.seed(seed);
但是我還想確保當我使用隨機輸入和隨機種子時,不會發生任何奇怪的事情(即異常):
std::mt19937 rng;
rng.seed(std::random_device()());
顯然,有限數量的測試運行無法確定代碼是否正確; 但是,大量的測試運行至少可以使您放心。
我該如何最好地處理? 我想添加類似的內容:
size_t seed = std::random_device()();
#ifdef TESTING
seed = 42;
#endif
rng.seed(seed);
但是,然后,我無法獲得一個測試文件(使用gtest),該文件使用隨機種子進行某些測試,並使用常量種子進行其他測試(可以嗎?)。
¹以我為例:我從n中均勻且隨機地選擇一個元素來划分輸入。
編輯:我在問功能測試,而不是單元測試。
首先,為隨機數生成器創建一個接口,以便測試能夠將其替換為預定義的生成器。 如果在單元測試中使用隨機數生成器,則該單元不再是單元。
然后考慮一下您真正想測試什么。 我猜想應該對該算法進行測試:
為什么在功能測試中您會為隨機數生成器煩惱? 功能測試會檢查應用程序在被用戶使用時是否正常運行。 用戶將無權訪問隨機數生成器的種子,因此只需保持原樣並允許其按您設計的方式工作即可。 如果算法的結果不取決於隨機數生成器生成的值,請檢查它們在兩次測試之間是否沒有變化。 如果它們確實依賴於隨機數生成器,請檢查它們是否在兩次測試之間進行了更改(如果不更改,則表示代碼未執行應有的功能)。
這取決於您要進行哪種測試。
在單元測試中,種子應設置為固定值。
在某種功能測試中,您真的想使用隨機數來測試行為,而花多長時間都無關緊要,則可以設置隨機種子(也許使用time()),然后執行盡可能多的測試您想要的時間。
這意味着,您應該以相似的方式(使用gtest)創建兩組測試,其中單元測試的執行速度會更快。 使用單元測試,您將不會訪問文件和緩慢的資源(例如網絡和數據庫)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.