Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JUnit or Hamcrest have tolerance assertions?

I want to do an assertion where the actual value is within either a fixed +/- value of the expected value or a percent +/- value of the expected value.

While googling I noticed that NUnit had a nice syntax for that :

Assert.That( 5.5, Is.EqualTo( 5 ).Within(0.075);
Assert.That( 5.5, Is.EqualTo( 5 ).Within(1.5).Percent;

Does JUnit or Hamcrest have something similar I can use? If not, is there a nice way to express this behavior?

like image 416
Krish Srinivasan Avatar asked Oct 28 '14 18:10

Krish Srinivasan


2 Answers

The short answer - yes.

Old fashioned org.junit.Assert has a method assertEquals(java.lang.String message, float expected, float actual, float delta), and a bunch of a similar method for doubles, overloaded variants wihout the message, and similar implementations of assertArrayEquals.

If you want to use Hamcrest, the closeTo matcher is what you're looking for.

EDIT:
To address the question in the comments about percentages - there isn't an out-of-box matcher for this, but you can gimmy-rig something yourself by dividing the two, and making sure they are between the desired ratio and its inverse. To take the example from the OP:

float expected = 5.0;
float actual = 5.5
float ratio = 1.0075;
float inverse = 1/ratio;

float div = actual/expected;

assertThat(div, allOf(greaterThan(inverse), lessThan(ratio)));

It's a bit (well, a lot) clunky, but it should do the trick.

like image 135
Mureinik Avatar answered Oct 02 '22 15:10

Mureinik


Complementing Mureinik's answer:

To assert with a relative tolerance / percentage, you can just multiply:

    double closeTo5 = 4.6;
    double relativeTolerance = 0.1;
    double expected = 5;

    assertThat(closeTo5, 
        is(closeTo(expected, expected*relativeTolerance)));

Or, if you want to get fancy, write your own matcher (which is not hard)...

like image 38
sleske Avatar answered Oct 02 '22 16:10

sleske