Do you know your random?
My previous post contained a bug:
Despite the fact that Random
gets created with every new test run, randomValue
will be the same. Why?
To answer this question we might want to get closer to how Random.Next()
works. I am not going to repeat internet, just TL;DR;: random generators generate pseudorandom sequences configured by initial seed
value. That said, two instances of Random
with the same seed will return the same sequences:
It can be handful when you need some level of predictability, e.g. you need to reproduce a bug. But what’s about default constructor new Random()
? What seed is used in this case? The expectation is that it should be something random to generate different sequences for different instantiations. But that does not happen. The default value is rather unfortunate. Consider following test:
r3
is not equal to r4
because of Thread.Sleep
. And everything gets clear after looking at default Random
constructor:
If we create several instances within a single Tick, that lasts ~10-16 milliseconds, they would return the same sequences. That behavior may cause hard to reproduce race condition bugs.
To mitigate that risk we need some more reliable random. And there is one! Remember Guids? They are unique and can be considered random enough for most scenarios, that regular developer meets in her life. But what if we need int? Here is a solution:
Yes. Guid.GetHashCode()
should be your friend if you need something more random than default new Random()
.
And if you need to generate random objects, for testing or any other purpose, consider using AutoFixture. It can create random object graphs, collections and many more.