<p>I have a coworker who writes unit tests for objects which fill their fields with random data. His reason is that it gives a wider range of testing, since it will test a lot of different values, whereas a normal test only uses a single static value.</p>

<p>I've given him a number of different reasons against this, the main ones being:</p>

<ul>
<li>random values means the test isn't truly repeatable (which also means that if the test can randomly fail, it can do so on the build server and break the build)</li>
<li>if it's a random value and the test fails, we need to a) fix the object and b) force ourselves to test for that value every time, so we know it works, but since it's random we don't know what the value was</li>
</ul>

<p>Another coworker added:</p>

<ul>
<li>If I am testing an exception, random values will not ensure that the test ends up in the expected state</li>
<li>random data is used for flushing out a system and load testing, not for unit tests</li>
</ul>

<p>Can anyone else add additional reasons I can give him to get him to stop doing this?</p>

<p>(Or alternately, is this an acceptable method of writing unit tests, and I and my other coworker are wrong?)</p>

[{'answer_id': 32482, 'author': 'EBGreen', 'author_id': 1358, 'author_profile': 'https://Stackoverflow.com/users/1358', 'pm_score': 0, 'selected': False, 'text': '<p>Depending on your object/app, random data would have a place in load testing. I think more important would be to use data that explicitly tests the boundary conditions of the data.</p>\n'}, {'answer_id': 32490, 'author': 'Tim Frey', 'author_id': 1471, 'author_profile': 'https://Stackoverflow.com/users/1471', 'pm_score': 2, 'selected': False, 'text': "<p>Can you generate some random data once (I mean exactly once, not once per test run), then use it in all tests thereafter?</p>\n\n<p>I can definitely see the value in creating random data to test those cases that you haven't thought of, but you're right, having unit tests that can randomly pass or fail is a bad thing. </p>\n"}, {'answer_id': 32496, 'author': 'EBGreen', 'author_id': 1358, 'author_profile': 'https://Stackoverflow.com/users/1358', 'pm_score': 3, 'selected': False, 'text': "<blockquote>\n  <ul>\n  <li>if it's a random value and the test fails, we need to a) fix the object and b) force ourselves to test for that value every time, so we know it works, but since it's random we don't know what the value was</li>\n  </ul>\n</blockquote>\n\n<p>If your test case does not accurately record what it is testing, perhaps you need to recode the test case. I always want to have logs that I can refer back to for test cases so that I know exactly what caused it to fail whether using static or random data.</p>\n"}, {'answer_id': 32521, 'author': 'Will Dean', 'author_id': 987, 'author_profile': 'https://Stackoverflow.com/users/987', 'pm_score': 5, 'selected': False, 'text': "<p>There is a half-way house here which has some use, which is to seed your PRNG with a constant.  That allows you to generate 'random' data which is repeatable.</p>\n\n<p>Personally I do think there are places where (constant) random data is useful in testing - after you think you've done all your carefully-thought-out corners, using stimuli from a PRNG can sometimes find other things.</p>\n"}, {'answer_id': 32531, 'author': 'mreggen', 'author_id': 613, 'author_profile': 'https://Stackoverflow.com/users/613', 'pm_score': 4, 'selected': False, 'text': '<p>In the book <a href="http://oreilly.com/catalog/9780596510046/" rel="noreferrer">Beautiful Code</a>, there is a chapter called "Beautiful Tests", where he goes through a testing strategy for the <a href="http://en.wikipedia.org/wiki/Binary_search" rel="noreferrer">Binary Search</a> algorithm. One paragraph is called "Random Acts of Testing", in which he creates random arrays to thoroughly test the algorithm. You can read some of this online at Google Books, <a href="http://books.google.com/books?id=gJrmszNHQV4C&amp;printsec=frontcover&amp;dq=beautiful+code&amp;sig=ACfU3U370KhEVM8EHhDI6SYDXmEzHwuAow#PRA1-PA95,M1" rel="noreferrer">page 95</a>, but it\'s a great book worth having.</p>\n\n<p>So basically this just shows that generating random data for testing is a viable option. </p>\n'}, {'answer_id': 32631, 'author': 'Apocalisp', 'author_id': 3434, 'author_profile': 'https://Stackoverflow.com/users/3434', 'pm_score': 7, 'selected': True, 'text': '<p>There\'s a compromise. Your coworker is actually onto something, but I think he\'s doing it wrong. I\'m not sure that totally random testing is very useful, but it\'s certainly not invalid.</p>\n\n<p>A program (or unit) specification is a hypothesis that there exists some program that meets it. The program itself is then evidence of that hypothesis. What unit testing ought to be is an attempt to provide counter-evidence to refute that the program works according to the spec.</p>\n\n<p>Now, you can write the unit tests by hand, but it really is a mechanical task. It can be automated. All you have to do is write the spec, and a machine can generate lots and lots of unit tests that try to break your code.</p>\n\n<p>I don\'t know what language you\'re using, but see here:</p>\n\n<p>Java\n<a href="http://functionaljava.org/" rel="noreferrer">http://functionaljava.org/</a></p>\n\n<p>Scala (or Java)\n<a href="http://github.com/rickynils/scalacheck" rel="noreferrer">http://github.com/rickynils/scalacheck</a></p>\n\n<p>Haskell\n<a href="http://www.cs.chalmers.se/~rjmh/QuickCheck/" rel="noreferrer">http://www.cs.chalmers.se/~rjmh/QuickCheck/</a></p>\n\n<p>.NET:\n<a href="http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx" rel="noreferrer">http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx</a></p>\n\n<p>These tools will take your well-formed spec as input and automatically generate as many unit tests as you want, with automatically generated data. They use "shrinking" strategies (which you can tweak) to find the simplest possible test case to break your code and to make sure it covers the edge cases well.</p>\n\n<p>Happy testing!</p>\n'}, {'answer_id': 33508, 'author': 'Greg Whitfield', 'author_id': 2102, 'author_profile': 'https://Stackoverflow.com/users/2102', 'pm_score': -1, 'selected': False, 'text': '<p>How can your guy run the test again when it has failed to see if he has fixed it? I.e. he loses repeatability of tests.</p>\n\n<p>While I think there is probably some value in flinging a load of random data at tests, as mentioned in other replies it falls more under the heading of load testing than anything else. It is pretty much a "testing-by-hope" practice. I think that, in reality, your guy is simply not thinkng about what he is trying to test, and making up for that lack of thought by hoping randomness will eventually trap some mysterious error.</p>\n\n<p>So the argument I would use with him is that he is being lazy. Or, to put it another way, if he doesn\'t take the time to understand what he is trying to test it probably shows he doesn\'t really understand the code he is writing.</p>\n'}, {'answer_id': 89136, 'author': 'Tim James', 'author_id': 17055, 'author_profile': 'https://Stackoverflow.com/users/17055', 'pm_score': 0, 'selected': False, 'text': "<p>We just ran into this today.  I wanted <strong>pseudo-random</strong> (so it would look like compressed audio data in terms of size).  I TODO'd that I also wanted <strong>deterministic</strong>.  rand() was different on OSX than on Linux.  And unless I re-seeded, it could change at any time.  So we changed it to be deterministic but still psuedo-random: the test is repeatable, as much as using canned data (but more conveniently written).</p>\n\n<p>This was <strong>NOT</strong> testing by some random brute force through code paths.  That's the difference: still deterministic, still repeatable, still using data that looks like real input to run a set of interesting checks on edge cases in complex logic.  Still unit tests.  </p>\n\n<p>Does that still qualify is random?  Let's talk over beer.  :-)</p>\n"}, {'answer_id': 89158, 'author': 'Silver Dragon', 'author_id': 9440, 'author_profile': 'https://Stackoverflow.com/users/9440', 'pm_score': 6, 'selected': False, 'text': '<p>This kind of testing is called a <a href="http://en.wikipedia.org/wiki/Monkey_test" rel="noreferrer">Monkey test</a>. When done right, it can smoke out bugs from the really dark corners.</p>\n\n<p>To address your concerns about reproducibility: the right way to approach this, is to record the failed test entries, generate a unit test, which probes for the <em>entire family</em> of the specific bug; and include in the unit test the one specific input (from the random data) which caused the initial failure.</p>\n'}, {'answer_id': 185830, 'author': 'craigb', 'author_id': 18590, 'author_profile': 'https://Stackoverflow.com/users/18590', 'pm_score': 2, 'selected': False, 'text': '<p>If you\'re using random input for your tests you need to log the inputs so you can see what the values are. This way if there is some edge case you come across, you <em>can</em> write the test to reproduce it. I\'ve heard the same reasons from people for not using random input, but once you have insight into the actual values used for a particular test run then it isn\'t as much of an issue.</p>\n\n<p>The notion of "arbitrary" data is also very useful as a way of signifying something that is <em>not</em> important. We have some acceptance tests that come to mind where there is a lot of noise data that is no relevance to the test at hand.</p>\n'}, {'answer_id': 641599, 'author': 'Robert Gould', 'author_id': 15124, 'author_profile': 'https://Stackoverflow.com/users/15124', 'pm_score': 4, 'selected': False, 'text': '<p>Your co-worker is doing <a href="http://en.wikipedia.org/wiki/Fuzz_testing" rel="noreferrer">fuzz-testing</a>, although he doesn\'t know about it. They are especially valuable in server systems.</p>\n'}, {'answer_id': 4492015, 'author': 'Trystan Spangler', 'author_id': 548014, 'author_profile': 'https://Stackoverflow.com/users/548014', 'pm_score': 4, 'selected': False, 'text': "<p>One advantage for someone looking at the tests is that arbitrary data is clearly not important. I've seen too many tests that involved dozens of pieces of data and it can be difficult to tell what needs to be that way and what just happens to be that way. E.g. If an address validation method is tested with a specific zip code and all other data is random then you can be pretty sure the zip code is the only important part.</p>\n"}, {'answer_id': 7905809, 'author': 'Tom W', 'author_id': 313414, 'author_profile': 'https://Stackoverflow.com/users/313414', 'pm_score': 0, 'selected': False, 'text': "<p>I can envisage three solutions to the test data problem:</p>\n\n<ul>\n<li>Test with fixed data</li>\n<li>Test with random data</li>\n<li>Generate random data <em>once</em>, then use it as your fixed data</li>\n</ul>\n\n<p>I would recommend doing <em>all of the above</em>. That is, write repeatable unit tests with both some edge cases worked out using your brain, and some randomised data which you generate only once. Then write a set of randomised tests that you run <em>as well</em>. </p>\n\n<p>The randomised tests should never be expected to catch something your repeatable tests miss. You should aim to cover everything with repeatable tests, and consider the randomised tests a bonus. If they find something, it should be something that you couldn't have reasonably predicted; a real oddball.</p>\n"}, {'answer_id': 17111058, 'author': 'Jimmy Bosse', 'author_id': 294245, 'author_profile': 'https://Stackoverflow.com/users/294245', 'pm_score': 4, 'selected': False, 'text': '<p>If you are doing TDD then I would argue that random data is an excellent approach. If your test is written with constants, then you can only guarantee your code works for the specific value. If your test is randomly failing the build server there is likely a problem with how the test was written. </p>\n\n<p>Random data will help ensure any future refactoring will not rely on a magic constant. After all, if your tests are your documentation, then doesn\'t the presence of constants imply it only needs to work for those constants?</p>\n\n<p>I am exaggerating however I prefer to inject random data into my test as a sign that "the value of this variable should not affect the outcome of this test".</p>\n\n<p>I will say though that if you use a random variable then fork your test based on that variable, then that is a smell.</p>\n'}, {'answer_id': 26207750, 'author': 'Ohad Bruker', 'author_id': 3950710, 'author_profile': 'https://Stackoverflow.com/users/3950710', 'pm_score': 3, 'selected': False, 'text': '<p>You should ask yourselves what is the goal of your test.<br>\n<strong>Unit tests</strong> are about verifying logic, code flow and object interactions. Using random values tries to achieve a different goal, thus reduces test focus and simplicity. It is acceptable for readability reasons (generating UUID, ids, keys,etc.).<br>\nSpecifically for unit tests, I cannot recall even once this method was successful finding problems. But I have seen many determinism problems (in the tests) trying to be clever with random values and mainly with random dates.<br>\nFuzz testing is a valid approach for <strong>integration tests</strong> and <strong>end-to-end tests</strong>.</p>\n'}, {'answer_id': 37848136, 'author': 'BeeOnRope', 'author_id': 149138, 'author_profile': 'https://Stackoverflow.com/users/149138', 'pm_score': 5, 'selected': False, 'text': '<p>I am in favor of random tests, and I write them. However, whether they are appropriate in a particular build environment and which test suites they should be included in is a more nuanced question.</p>\n\n<p>Run locally (e.g., overnight on your dev box) randomized tests have found bugs both obvious and obscure. The obscure ones are arcane enough that I think random testing was really the only realistic one to flush them out. As a test, I took one tough-to-find bug discovered via randomized testing and had a half dozen crack developers review the function (about a dozen lines of code) where it occurred. None were able to detect it.</p>\n\n<p>Many of your arguments against randomized data are flavors of "the test isn\'t reproducible". However, a well written randomized test will capture the seed used to start the randomized seed and output it on failure. In addition to allowing you to repeat the test by hand, this allows you to trivially create new test which test the specific issue by hardcoding the seed for that test. Of course, it\'s probably nicer to hand-code an explicit test covering that case, but laziness has its virtues, and this even allows you to essentially auto-generate new test cases from a failing seed.</p>\n\n<p>The one point you make that I can\'t debate, however, is that it breaks the build systems. Most build and continuous integration tests expect the tests to do the same thing, every time. So a test that randomly fails will create chaos, randomly failing and pointing the fingers at changes that were harmless.</p>\n\n<p>A solution then, is to still run your randomized tests as part of the build and CI tests, but <em>run it with a fixed seed, for a fixed number of iterations</em>. Hence the test always does the same thing, but still explores a bunch of the input space (if you run it for multiple iterations). </p>\n\n<p>Locally, e.g., when changing the concerned class, you are free to run it for more iterations or with other seeds. If randomized testing ever becomes more popular, you could even imagine a specific suite of tests which are known to be random, which could be run with different seeds (hence with increasing coverage over time), and where failures wouldn\'t mean the same thing as deterministic CI systems (i.e., runs aren\'t associated 1:1 with code changes and so you don\'t point a finger at a particular change when things fail).</p>\n\n<p>There is a lot to be said for randomized tests, especially well written ones, so don\'t be too quick to dismiss them!</p>\n'}, {'answer_id': 66378633, 'author': 'Leonardo Mangano', 'author_id': 11329909, 'author_profile': 'https://Stackoverflow.com/users/11329909', 'pm_score': 2, 'selected': False, 'text': "<p>I think the problem here is that the purpose of unit tests is not catching bugs. The purpose is being able to change the code without breaking it, so how are you going to know that you break\nyour code when your random unit tests are green in your pipeline, just because they doesn't touch the right path?\nDoing this is insane for me. A different situation could be running them as integration tests or e2e not as a part of the build, and just for some specific things because in some situations you will need a mirror of your code in your asserts to test that way.\nAnd having a test suite as complex as your real code is like not having tests at all because who\nis going to test your suite then? :p</p>\n"}, {'answer_id': 70786924, 'author': 'Keeely', 'author_id': 4627471, 'author_profile': 'https://Stackoverflow.com/users/4627471', 'pm_score': 1, 'selected': False, 'text': "<p>A unit test is there to ensure the correct behaviour in response to particular inputs, in particular all code paths/logic should be covered.  There is no need to use random data to achieve this.  If you don't have 100% code coverage with your unit tests, then fuzz testing by the back door is not going to achieve this, and it may even mean you occasionally don't achieve your desired code coverage.  It may (pardon the pun) give you a 'fuzzy' feeling that you're getting to more code paths, but there may not be much science behind this.  People often check code coverage when they run their unit tests for the first time and then forget about it (unless enforced by CI), so do you really want to be checking coverage against every run as a result of using random input data?  It's just another thing to potentially neglect.</p>\n<p>Also, programmers tend to take the easy path, and they make mistakes.  They make just as many mistakes in unit tests as they do in the code under test.  It's way too easy for someone to introduce random data, and then tailor the asserts to the output order in a single run.  Admit it, we've all done this.  When the data changes the order can change and the asserts fail, so a portion of the executions fail.  This portion needn't be 1/2 I've seen exactly this result in failures 10% of the time.  It takes a long time to track down problems like this, and if your CI doesn't record enough data about enough of the runs, then it can be even worse.</p>\n<p>Whilst there's an argument for saying &quot;just don't make these mistakes&quot;, in a typical commercial programming setup there'll be a mix of abilities, sometimes relatively junior people reviewing code for other junior people.  You can write literally dozens more tests in the time it takes to debug one non-deterministic test and fix it, so make sure you don't have any.  Don't use random data.</p>\n"}, {'answer_id': 70846231, 'author': 'maybesomename', 'author_id': 16045922, 'author_profile': 'https://Stackoverflow.com/users/16045922', 'pm_score': 2, 'selected': False, 'text': "<p>In my experience unit tests and randomized tests should be separated. Unit tests serve to give a certainty of the correctness of some cases, not only to catch obscure bugs.\nAll that said, randomized testing is useful and should be done, separately from unit tests, but it should test a series of randomized values.\nI can't help to think that testing 1 random value with every run is just not enough, neither to be a sufficient randomized test, neither to be a truly useful unit test.</p>\n<p>Another aspect is validating the test results. If you have random inputs, you have to calculate the expected output for it inside the test. This will at some level duplicate the tested logic, making the test only a mirror of the tested code itself. This will not sufficiently test the code, since the test might contain the same errors the original code does.</p>\n"}, {'answer_id': 71762174, 'author': 'armandino', 'author_id': 45112, 'author_profile': 'https://Stackoverflow.com/users/45112', 'pm_score': 2, 'selected': False, 'text': '<p>This is an old question, but I wanted to mention a library I created that generates objects filled with random data. It supports reproducing the same data if a test fails by supplying a seed. It also supports JUnit 5 via an extension.</p>\n<p>Example usage:</p>\n<pre class="lang-java prettyprint-override"><code>Person person = Instancio.create(Person.class);\n</code></pre>\n<p>Or a builder API for customising generation parameters:</p>\n<pre class="lang-java prettyprint-override"><code>Person person = Instancio.of(Person.class)\n    .generate(field(&quot;age&quot;), gen -&gt; gen.ints.min(18).max(65))\n    .create();\n</code></pre>\n<p>Github link has more examples: <a href="https://github.com/instancio/instancio" rel="nofollow noreferrer">https://github.com/instancio/instancio</a></p>\n<p>You can find the library on maven central:</p>\n<pre class="lang-xml prettyprint-override"><code>&lt;dependency&gt;\n    &lt;groupId&gt;org.instancio&lt;/groupId&gt;\n    &lt;artifactId&gt;instancio-junit&lt;/artifactId&gt;\n    &lt;version&gt;LATEST&lt;/version&gt;\n&lt;/dependency&gt;\n\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/32458', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/517/']