xUnit assert two values are equal with some tolerance
Asked Answered
R

4

23

I'm trying to compare the precision of two numbers with some tolerance.

This is how it was being checked in nUnit:

Assert.That(turnOver, Is.EqualTo(turnoverExpected).Within(0.00001).Percent);

I'm trying to do the same in xUnit but this is all I've come up with:

double tolerance = 0.00001;
Assert.Equal(turnOver, turnoverExpected, tolerance);

This doesn't compile because Assert.Equal doesn't take a 3rd argument of type double.

Anyone got an idea of a nice way to do this in xUnit?

Rhine answered 9/8, 2019 at 10:48 Comment(0)
C
27

You probably slightly misunderstood the last parameter(precision) in Assert.Equal(expected, actual, precision) method.

 /// <param name="precision">The number of decimal places (valid values: 0-15)</param>

So, for instance, if you want to compare 0.00021 with 0.00022 and you are interested in comparing only 4 decimal places, you can do this (it will return true):

Assert.Equal(0.00021, 0.00022, 4); // true

This will return false:

Assert.Equal(0.00021, 0.00022, 5); // false
Cardew answered 9/8, 2019 at 10:59 Comment(3)
that makes more sense, I'm going to try that.Rhine
I think that is a sensible answer.Knighterrantry
That doesn't work! If the expected result is very close to the rounding point, it may differ by a very small amount, e.g. 1e-10, but fail for a precision of 1! (Sample: expected = 0.35, actual = 0.3499999999, but if rounded 0.4 != 0.3)Bailee
U
7

You could use FluentAssertions

float value = 3.1415927F;
value.Should().BeApproximately(3.14F, 0.01F);
Unmask answered 12/4, 2021 at 0:5 Comment(0)
D
6

You can use Assert.InRange(), where the signature is

public static void InRange<T>(T actual, T low, T high) where T : IComparable
Dunt answered 9/8, 2019 at 10:53 Comment(1)
Thats the one I was looking for, because in my case the tolerance had to be +- 4 and decimals were too precise in that case.Hamman
B
2

I was porting some tests from MS Test V1 to xUnit and noticed that the Assert with a Delta wasn't working the same as the one in xUnit.

To solve this, I decompiled the one from MS Test and made my own version:

internal static class DoubleAssertion
{
    const Double delta = 0.00001;

    public static void Equal(Double expected, Double actual, String message = null)
    {
        if (Math.Abs(expected - actual) > delta)
        {
            var deltaMessage = $"Expected a difference no greater than <{delta.ToString(CultureInfo.CurrentCulture.NumberFormat)}>";

            if (!String.IsNullOrWhiteSpace(message))
                message = message + Environment.NewLine + deltaMessage;
            else
                message = deltaMessage;

            throw new DoubleException(
                expected: expected.ToString(CultureInfo.CurrentCulture.NumberFormat),
                actual: actual.ToString(CultureInfo.CurrentCulture.NumberFormat),
                message: message);
        }
    }
}

public class DoubleException : AssertActualExpectedException
{
    public DoubleException(
        String expected,
        String actual,
        String message)
        : base(expected, actual, message)
    {
    }
}
Bowery answered 9/8, 2019 at 10:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.