Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a method that can have random behaviour

I ran across this situation this afternoon, so I thought I'd ask what you guys do.

We have a randomized password generator for user password resets and while fixing a problem with it, I decided to move the routine into my (slowly growing) test harness.

I want to test that passwords generated conform to the rules we've set out, but of course the results of the function will be randomized (or, well, pseudo-randomized).

What would you guys do in the unit test? Generate a bunch of passwords, check they all pass and consider that good enough?

like image 405
Dana Avatar asked Dec 09 '22 23:12

Dana


2 Answers

A unit test should do the same thing every time that it runs, otherwise you may run into a situation where the unit test only fails occasionally, and that could be a real pain to debug.

Try seeding your pseudo-randomizer with the same seed every time (in the test, that is--not in production code). That way your test will generate the same set of inputs every time.

If you can't control the seed and there is no way to prevent the function you are testing from being randomized, then I guess you are stuck with an unpredictable unit test. :(

like image 154
Parappa Avatar answered May 21 '23 04:05

Parappa


The function is a hypothesis that for all inputs, the output conforms to the specifications. The unit test is an attempt to falsify that hypothesis. So yes, the best you can do in this case is to generate a large amount of outputs. If they all pass your specification, then you can be reasonably sure that your function works as specified.

Consider putting the random number generator outside this function and passing a random number to it, making the function deterministic, instead of having it access the random number generator directly. This way, you can generate a large number of random inputs in your test harness, pass them all to your function, and test the outputs. If one fails, record what that value is so that you have a documented test case.

like image 33
Apocalisp Avatar answered May 21 '23 03:05

Apocalisp