tags:

views:

105

answers:

7

Hello, I would like to know what are the downsides of using random values in some of the Unit Testing.


I'm talking about a large scales system, with many servers and non deterministic input in high capacity. when i say non deterministic i'm talking about messages that are sent and you catch what you can and do the best you can. There are many types of messages, so the input could be very complicated. I can't imagine writing the code for so many scenarios and a simple non random (deterministic) message's generator is not good enough. That's why i want to have a randomized unittest or server test that in case of a failure could write a log. And i prefer the unittest instead of a random injector because i want it to run as part of the night build automated tests.

+4  A: 

They are random.

(You test might randomly work, even if your code is broken.)

relet
i'm talking about additional testing to the non random tests
Adibe7
Your unit test is meant to prove, in a reproducible manner, if your unit works or not. If you do that in your other tests, you will not need an additional random test. You can use random values to scan your software for unknown security issues using random input. However with the result of that you should again write a reproducible unit test.
relet
Tnx for your answer, can you take another look now, after i added some more explenations?
Adibe7
+2  A: 

Also, you won't be able to reproduce tests many times over. A unit test should run exactly the same with given parameters.

Eric
Thats not always true, random inputs can increase code coverage in some cases.
NickLarsen
@NIckLarsen: They may *happen* to increase code coverage, for one particular test run... You cannot *rely* on it covering that code though. You've gotta open the box to know if the cat is dead or not.
Pete
@Nick - Then you should promote the value that increases code coverage.
mlk
While I agree with you guys, sometimes there are just too many cases to test all of them. Even if you limit it to exceptional cases, some systems just have too many. In those cases, testing against random inputs increases code coverage. The alternative in those situations is to prove your system for all classes of inputs.
NickLarsen
@pete: I'm not sure what you mean by `You've gotta open the box to know if the cat is dead or not` but hopefully you are not saying that implementation details should be tested!
NickLarsen
@NickLarsen: http://en.wikipedia.org/wiki/Schr%C3%B6dinger's_cat
Pete
+1  A: 

The results aren't repeatable, and you won't know what conditions caused the code to fail (thus making it tought to debug).

Kendrick
+1  A: 

It is much better to have unit tests that are 100% repeatable and include all the edge cases. For example, test zero, negatives, positives, numbers too big, numbers too small, etc. If you want to include tests with random values in addition to all the edge cases and normal cases that would be fine. However, I'm not sure you would get much benefit out of the time spent. Having all the normal cases and edge cases should handle everything. The rest is "gravy".

mpenrow
+1  A: 

As others have suggested, it makes your test unreliable because you don't know what's going on inside of it. That means it might work for some cases, and not for others.

If you already have an idea of the range of values that you want to test, then you should either (1) create a different test for each value in the range, or (2) loop over the set of values and make an assertion on each iteration. A quick, rather silly, example...

for($i = 0; $i < 10; $i++)
  $this->assertEquals($i + 1, Math::addOne($i));

You could do something similar with character encodings. For example, loop over the ASCII character set and test all of those crazy characters against one of your text manipulation functions.

Sam Bisbee
A: 

You need to remember which random numbers you generated during verification.

Example.

Username= "username".rand();
Save_in_DB("user",Username); // To save it in DB
Verify_if_Saved("user",Username); 
Akshar Prabhu Desai
+4  A: 

Downsides

Firstly, it makes the test more convoluted and slightly harder to debug, as you cannot directly see all the values being fed in (though there's always the option of generating test cases as either code or data, too). If you're doing some semi-complicated logic to generate your random test data, then there's also the chance that this code has a bug in it. Bugs in test code can be a pain, especially if developers immediate assume the bug is the production code.

Secondly, it is often impossible to be specific about the expected answer. If you know the answer based on the input, then there's a decent chance you're just aping the logic under test (think about it -- if the input is random, how do you know the expected output?) As a result, you may have to trade very specific asserts (the value should be x) for more general sanity-check asserts (the value should be between y and z).

Thirdly, unless there's a wide range of inputs and outputs, you can often cover the same range using well chosen values in a standard unit tests with less complexity. E.g. pick the numbers -max, (-max + 1), -2, -1, 0, 1, 2, max-1, max. (or whatever is interesting for the algorithm).

Upsides

When done well with the correct target, these tests can provide a very valuable complementary testing pass. I've seen quite a few bits of code that, when hammered by randomly generated test inputs, buckled due to unforeseen edge cases. I sometimes add an extra integration testing pass that generates a shedload of test cases.

Additional tricks

If one of your random tests fails, isolate the 'interesting' value and promote it into a standalone unit test to ensure that you can fix the bug and it will never regress prior to checkin.

Mark Simpson
If you're going to downvote me, say why. I've used these techniques to good effect in finding and fixing bugs.
Mark Simpson
sorry, it was a mistake. :)
Adibe7
thanks for replying :)
Mark Simpson