Saturday 7 July 2018

Junit: Theories

Theories are most powerful assertions, used to state our assumptions clearly.

Let me try to explain with an example,

A typical mathematical theory looks like below.
For every integer a and b, a + b = b + a is always true.

Since, integers are infinite, you can’t test for infinite number of integers. You may test the above theory with some sample data.

For example, for the below sample data, you will end up in testing 36 (Since there are 6 numbers, total combination = 6 * 6 = 36) combinations
-7, 9, 0, -8, 19, 4

TestApp.java
package com.sample.test;

import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class TestApp {

 @Test
 public void aPlusBIsCumulative() {
  assertTrue((-7 + -7) == (-7 + -7));
  assertTrue((-7 + 9) == (9 + -7));
  assertTrue((-7 + 0) == (0 + -7));
  assertTrue((-7 + -8) == (-8 + -7));
  assertTrue((-7 + 19) == (19 + -7));
  assertTrue((-7 + 4) == (4 + -7));
  assertTrue((9 + -7) == (-7 + 9));
  assertTrue((9 + 9) == (9 + 9));
  assertTrue((9 + 0) == (0 + 9));
  assertTrue((9 + -8) == (-8 + 9));
  assertTrue((9 + 19) == (19 + 9));
  assertTrue((9 + 4) == (4 + 9));
  assertTrue((0 + -7) == (-7 + 0));
  assertTrue((0 + 9) == (9 + 0));
  assertTrue((0 + 0) == (0 + 0));
  assertTrue((0 + -8) == (-8 + 0));
  assertTrue((0 + 19) == (19 + 0));
  assertTrue((0 + 4) == (4 + 0));
  assertTrue((-8 + -7) == (-7 + -8));
  assertTrue((-8 + 9) == (9 + -8));
  assertTrue((-8 + 0) == (0 + -8));
  assertTrue((-8 + -8) == (-8 + -8));
  assertTrue((-8 + 19) == (19 + -8));
  assertTrue((-8 + 4) == (4 + -8));
  assertTrue((19 + -7) == (-7 + 19));
  assertTrue((19 + 9) == (9 + 19));
  assertTrue((19 + 0) == (0 + 19));
  assertTrue((19 + -8) == (-8 + 19));
  assertTrue((19 + 19) == (19 + 19));
  assertTrue((19 + 4) == (4 + 19));
  assertTrue((4 + -7) == (-7 + 4));
  assertTrue((4 + 9) == (9 + 4));
  assertTrue((4 + 0) == (0 + 4));
  assertTrue((4 + -8) == (-8 + 4));
  assertTrue((4 + 19) == (19 + 4));
  assertTrue((4 + 4) == (4 + 4));

 }

}


What if you want to test for 100 samples, you will end up in writing 100 * 100 assert statements (or) you yourself code the logic like below.

TestApp.java
package com.sample.test;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class TestApp {

 private static int[] data = { -7, 9, 0, -8, 19, 4 };

 @Test
 public void aPlusBIsCumulative() {
  for (int i : data) {
   for (int j : data) {
    assertEquals((i + j), (j + i));
   }
  }

 }

}


Instead of writing all the testing logic, junit theories helps you to test above kind of scenarios in easy way.
package com.sample.test;

import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertTrue;

@RunWith(Theories.class)
public class TestApp {

 @DataPoints
 public static int[] integers() {
  return new int[] { -7, 9, 0, -8, 19, 4 };
 }

 @Theory
 public void aPlusBIsCumulative(Integer a, Integer b) {
  assertTrue((a + b) == (b + a));
 }

}

@DataPoints
When you annotate an array or iterable-typed field or method with @DataPoints annotation, then it will cause the values in the array or iterable given to be used as parameters for theories in that class when run with the Theories runner.

@Theory
If you mark any test method with @Theory annotation, then that test method should be read as theories by the 'org.junit.experimental.theories.Theories' runner.

Example 2: for any non-null string s, s = reverse(reverse(s))

TestApp.java
package com.sample.test;

import static org.junit.Assert.assertEquals;

import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

@RunWith(Theories.class)
public class TestApp {

 private static String reverse(String s) {
  String reverse = "";

  for (int i = s.length() - 1; i >= 0; i--) {
   reverse = reverse + s.charAt(i);
  }
  return reverse;
 }

 @DataPoints
 public static String input[] = {"Hello", "How", "Are", "You"};

 @Theory
 public void strReverseTwice(String s) {
  assertEquals(s, reverse(reverse(s)));
 }

}







Previous                                                 Next                                                 Home

No comments:

Post a Comment