Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XCTAssertEqual not working for double values

I am writing some unit tests for a map coordinate function that I am writing. Unfortunately, there's something going on with XCTest that I am unable to nail down that is causing my test to fail:

NSString *testValue = @"121°31'40\"E";

double returnValue = coordinateStringToDecimal(testValue);
static double expectedValue = 121.5277777777778;
XCTAssertEqual(returnValue, expectedValue, @"Expected %f, got %f", expectedValue, returnValue);

I did read this similar question to troubleshoot. However, I am able to validate that the numbers and types are the same. Here is the console output of checking the type of each value:

(lldb) print @encode(__typeof__(returnValue))
(const char [2]) $5 = "d"
(lldb) print @encode(__typeof__(expectedValue))
(const char [2]) $6 = "d"

The Variables View in the debugger is showing them to be the same:

enter image description here

The interesting thing is the console output of comparing them in lldb:

(lldb) print (returnValue == expectedValue)
(bool) $7 = false

The types are the same and the actual numbers are the same. Why else would my assert be failing???

like image 871
Wayne Hartman Avatar asked Jan 02 '14 21:01

Wayne Hartman


2 Answers

Because you are dealing with floating point numbers, there will always be a certain degree of inaccuracy, even between double values. In these cases, you need to use a different assertion: XCTAssertEqualWithAccuracy. From the docs:

Generates a failure when a1 is not equal to a2 within + or - accuracy. This test is for scalars such as floats and doubles, where small differences could make these items not exactly equal, but works for all scalars.

Change your assert to something like this:

XCTAssertEqualWithAccuracy(returnValue, expectedValue, 0.000000001);

Or in Swift 4:

XCTAssertEqual(returnValue, expectedValue, accuracy: 0.000000001, "expected better from you")

In Nimble:

expect(expectedValue).to(beCloseTo(returnValue, within: 0.000000001))
like image 179
Wayne Hartman Avatar answered Dec 31 '22 18:12

Wayne Hartman


In Swift 4 accuracy was removed from the function name - now its an overload of XCTAssertEqual:

XCTAssertEqual(returnValue, expectedValue, accuracy: 0.000000001, "expected better from you")
like image 34
Jochen Holzer Avatar answered Dec 31 '22 18:12

Jochen Holzer