Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomized testing in Java

I write a lot of unit tests. Often, you need to write carefully considered test cases by hand, a form of whitebox testing. If you are lucky enough to work for a company with a separate quality assurance engineers, perhaps someone else writes test cases for you (kind of a mix between white and black box testing).

Many times, however, randomized testing would find many bugs and would serve as a great complement to hand-written cases.

For example, I might have a self-contained class and be able to express the invariants and broad-stroke behavior of the class simply (such as "this method never throws an exception" or "this method always returns a positive value"). I would like a test framework that just bashes on my class and checks the invariants.

A similar case: I often have a class which implements similar functionality to another class (but does it with different performance characteristics or with some added functionality). I would to A vs B test the two classes in a randomized way. For example, if I was implementing TreeMap, I could use HashMap as a comparable implementation (modulo a few differences due to the sorted behavior of TreeMap) and check most of the basic functionality in a randomized way. Simlarly, someone implementing LinkedList could use ArrayList as a comparable implementation and vice-versa.

I've written some basic stuff to do this in the past, but it is painstaking to set to up all the boilerplate to:

  1. Create objects with random initial state
  2. Apply random mutations
  3. Create mappings between "like" objects for A vs B testing
  4. Define invariants and rules such as "when will exceptions be thrown"

I still do it from time to time, but I want to reduce my effort level. For example, are there frameworks that remove or simplify the required boilerplate?

Otherwise, what techniques are used to do randomized testing in Java?

This is related, but not the same as fuzz testing. Fuzz testing seems to focus on random inputs to a single entity, in hope of triggering bad behavior, often with an adaptive input model based on dynamic coverage observations. That's covers a lot of the above, but doesn't cover, stuff like A vs B testing when comparable implementations exist, or invariant checking. In any case, I'm also interested in decent fuzz testing libraries for Java.

like image 289
BeeOnRope Avatar asked Sep 18 '25 13:09

BeeOnRope


1 Answers

I think what you're trying to find is a library for Property Based Testing in Java (see types of randomized testing). Shortly: instead of testing the value of the result you're testing a property of it. E.g. instead of checking that 2+2 is 4 you're checking properties like:

  • random1 + 0 = random1
  • random1 + random2 >= random1
  • ...

Take a look at this article that explains Property Based Testing in details.

Another option that you mention is to check with your Test Oracle - something that knows the true answer (e.g. old bullet-proof algorithm). So you pass a random variable both to old and new algorithm and you check that the results are equal.

Couple of Java libraries:

  • JUnit QuickCheck - a specialized lib for Property Based Testing. Allows you to define the properties and passes random values for these properties to check. So far (06/2016) it's pretty young, so you may want to check out ScalaCheck since it's possible to write Scala tests for Java code.
  • Datagen - random values generator for Java in case standard randomizers are not enough. Disclaimer: I'm the author.
like image 91
Stanislav Bashkyrtsev Avatar answered Sep 21 '25 06:09

Stanislav Bashkyrtsev