Property Based Testing Java

An Intro to Property-based Testing

Featuring junit-quickcheck

–

What is property-based testing?

PBT is a way to write automated tests that focuses on a property of functionality

–

Why bother?

Typical unit tests with defined inputs are often called example-based tests

–

@Test
public void answer_invalid_from_long_value_example_based() {
  final String input = StringUtils.repeat("Hello world", 100);

  var result = BasicAnswerValidation.textIsValidLength()
    .apply(input);

  assertFalse(result.isValid());
  assertEquals(
      "Didn't fail validation as notValid",
      "answer.invalidSize",
      result.getReasons().iterator().next().getMessageKey());
}

–

@Test
public void answer_invalid_from_short_value_example_based() {
  final String input = "";

  var result = BasicAnswerValidation.textIsValidLength()
    .apply(input);

  assertFalse(result.isValid());
  assertEquals(
      "Didn't fail validation as notValid",
      "answer.invalidSize",
      result.getReasons().iterator().next().getMessageKey());
}

–

@Test
public void answer_invalid_from_null_value_example_based() {
  final String input = null;

  var result = BasicAnswerValidation.textIsValidLength().apply(input);

  assertFalse(result.isValid());
  assertEquals(
      "Didn't fail validation as notValid",
      "answer.invalidSize",
      result.getReasons().iterator().next().getMessageKey());
}

–

  • Data-driven test solve when you need to test for several different sets of input, but don’t want all the code of a test for each

  • With PBT, the inputs are more dynamic, and often based on the type of input

–

Generators

Input is created via generators. Many come OOTB, and you can make your own.

–

Introducing junit-quickheck

@Property
public void answer_invalid_from_invalid_value(
    @NullAllowed(probability = 1.0f) String input) {
  
  final String freeFormAnswer = input;

  var result = BasicAnswerValidation.textIsValidLength()
    .apply(input);

  assertFalse(result.isValid());
  assertEquals(
      "Didn't fail validation as notValid",
      "answer.invalidSize",
      result.getReasons().iterator().next().getMessageKey());
}

–

History

  • PBT came out of the functionality community
  • Haskell quickcheck
  • Pure functions are good candidates for PBT
  • Available in Java, Scala, Python, F#, Haskell…

–

When to use it

–

  • Numerous different combinations of inputs that may lead to unexpected behaviors. A lot of logic with a lot of various behaviors based on different inputs of the same type
  • Exploratory testing, legacy code

–

When not to use it

–

  • When examples are easy to define
  • When defined examples reliably cover the functionality
  • Integration testing with large number of inputs

–

Resources

  • junit-quickcheck, https://github.com/pholser/junit-quickcheck
  • Interview with Bill Venners on Property Based Testing, https://www.se-radio.net/2018/05/se-radio-episode-322-bill-venners-on-property-based-tests/
  • Blog on Property-based Testing against a Poker app, https://www.leadingagile.com/2018/04/step-by-step-toward-property-based-testing/

Thanks!

–

DEMO: Poker one, or Person, or Functional: scala with nomanclature

Marvelous List

  • No order here
  • Or here
  • Or here
  • Or here

Fantastic Ordered List

  1. One is smaller than…
  2. Two is smaller than…
  3. Three!

Written on January 27, 2020