c++unit-testingrandom-seed

Is it safe to use std::mt19937 (with fixed seed) within unit tests?


I had written a unit test of a function that requires a Random Number Generator (RNG). The implementation of the tested function starts with the following lines:

const int nSeed = 0;
std::mt19937 randNbGen(nSeed);

and the randNbGen object is later used within that same function to perform calculations that eventually yield its return value.

By seeding the RNG, it generates the same sequence of numbers from a run to the next, which I need for the unit test to be consistent. Also, I assumed that by using an RNG from the std library (std::mt19937 in my case) I was guaranteed that the sequence of numbers generated wouldn’t be changing in the future.

However: 6 months later (ie now) the test fails. I checked out a previous commit that used to pass the test, now it fails the test with the same function output as it currently does. I also note that randNbGen generates the same sequence of numbers in both commits.

Is it indeed possible that the RNG (implementation) changed? Or do I must have skrewed up somewhere?
What is the recommended way to handle this situation?
Bonus question: is the RNG's behavior constant accross platforms?

PS: I'm using MSVC on Windows (Visual Studio 2022)


Solution

  • This answer is a summary of multiple contributions from various users that you will find in the comments of the original question: thanks to all who helped!

    Recall that the C++ standard offers:

    Also recall that we have three main implementations of the C++ library (amongst others):

    A first aspect of the question is whether the behavior of the Random Number Generator (RNG) may change through time:

    As a consequence:

    In my particular case, even though I thought I was using std::mt19937 directly, it turned out that I was actually using std::uniform_int_distribution<>. That is why unit tests that used to pass were now failing. Actually, rolling back from Visual Studio 2022 v17.7.4 to Visual Studio 2022 v17.4.2 made the tests pass. Hence it appears that the implementation of std::uniform_int_distribution<> changed in Visual Studio 2022 around version 17.5~17.6, as can be seen here and there. For instructions on how to rollback Visual Studio, see here.

    Can I use the distributions within unit tests, despite the risk that the sequence of numbers outputted might change?
    Yes, but consider the following precautions:

    Alternative solutions: