1

I have a function which is expected to randomly return one value from a collection of values. Is there a good way to test this random behavior with unit-test tools like JUnit etc.?

wxl24life
  • 683
  • 1
  • 7
  • 13
  • Unit Test: Define input set, pass to function, check return value in input set = Fun and Profit. – Mitch Wheat Aug 18 '13 at 04:08
  • @MitchWheat sorry for not having described the question clearly, the question has been edited, thanks for your kindly comment:-) – wxl24life Aug 18 '13 at 04:32
  • Dup http://stackoverflow.com/questions/311807/unit-testing-with-functions-that-return-random-results? – lreeder Aug 18 '13 at 05:28
  • Possible duplicate of [Unit testing - how do I test a function that returns random output?](http://stackoverflow.com/questions/2618043/unit-testing-how-do-i-test-a-function-that-returns-random-output) – Raedwald Jan 23 '16 at 15:55

4 Answers4

4

In situations that called for a lot of unit testing of code that normally behaves randomly, I've sometimes wrapped a stream of results from a java.util.Random in an Iterable<Integer>. The advantage is that, during unit testing, I can call the same method with an ArrayList<Integer> and get completely predictable behavior.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • This is the best approach. The unit test shouldn't testing the ramdomness of `java.util.Random`. – SimonC Aug 18 '13 at 04:26
2

No. By definition, the result is (or should be) indeterminate, so the usual concept of "expected result" doesn't apply.

However, you could write a fairly simple test using a statistical approach, perhaps that when called n times, the set (unique) of values returned is at least .75 n, or something similar.

Another approach may be to defer the "randomness" to a trusted and sufficient implementation, such as an algorithm based on Math.random(), meaning your unit test would not have to test the randomness, rather just the functionality.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
1

java.util.Random can probably be relied upon to be 'sufficiently random' for your purposes, so I assume what you're trying to test is that you get a proper random distribution among the items in your collection. It's true that there are a number of ways you could select an item out of a collection based on a random number and still end up biasing the results. For instance, iterating across the collection and using a random check at each stage will bias towards earlier items in the list.

If you want to test that your function actually produces random results you're going to need to find a statistical analysis toolkit which can do that. I'd suggest you fill up collections of various sizes with integer sequences, and then run tests of your random fetching code against those collections. You can feed the fetched values into the statistical analysis to determine if they're random or biased, and since they are linear sequences, the result should imply the same property for your fetching code as a whole.

Jherico
  • 28,584
  • 8
  • 61
  • 87
0

The standard way of testing random values is to generate a few thousand of them, enumerate how many of each you get, calculate the chi-square statistic of the data set, then the incomplete gamma function will give you the probability of that distribution occurring at random. If that probability is too close to 0, it is likely that your RNG is biased.

The classic example of this is the "dieharder" test suite. You might also check out the test code in my http://github.com/lcrocker/ojrandlib.

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55