Document the recommended pattern for performing floating point equality-with-accuracy expectations, analogous to XCTAssertEqual(_:_:accuracy:)
Kyle-Ye opened this issue · comments
Description
What's the equivalents for XCTAssertEqual with accuracy in swift-testing
I do not find a Standard Library function to compare 2 Double with accuracy.
And the simplest way is we define one on client side. But I think this is a very common use case. Testing framework should support it out of box
Expected behavior
Support it directly in Testing framework the same as XCTest
Actual behavior
Write a compare(_ a: Double, _ b: Double, accuracy: Double) -> Bool
by hand, and use #expect(compare(a, b, accuracy: accuracy))
Or
#expect(abs(a-b) <= accuracy)
Other consideration
Keeps using #expect(abs(a-b) <= accuracy)
and add best practice suggestion to Migration documentation.
Steps to reproduce
No response
swift-testing version/commit hash
No response
Swift & OS version (output of swift --version && uname -a
)
No response
To perform approximate comparisons of floating-point values, use the swift-numerics package (in particular, the isApproximatelyEqual()
function.)
Our documentation doesn't currently list this alternative, but it could be added. It doesn't really fit in the table of XCTAssert
alternatives, but a paragraph after the table would do.
To perform approximate comparisons of floating-point values, use the swift-numerics package (in particular, the
isApproximatelyEqual()
function.)Our documentation doesn't currently list this alternative, but it could be added. It doesn't really fit in the table of
XCTAssert
alternatives, but a paragraph after the table would do.
Thanks. I have not used swift-numerics before. And I'll give it a try.
But this function/implementation is not in Swift nor Testing module and require the swift-testing user to manually add a dependency for a new package. I do not think this should be a final solution to the problem.
Tracked internally as rdar://113903882.
The solution we'd advise developers to use is isApproximatelyEqual()
. @stephentyrone Are you able to provide additional guidance? Is there any possibility of isApproximatelyEqual()
moving into the standard library?
It's worth mentioning as well that the exclusion of an #expect
/#require
overload for floating point comparisons is intentional, since floating point math is hard to get right in a cross-platform way, and any library made for Swift is ideally using a standardized implementation to ensure the comparison behavior is consistent across the ecosystem.
In turn, this creates an educational and organizational challenge for Swift since it means the swift-numerics
package needs to be evangelized as the ordained way to compare floating point numbers, which means that client libraries (like swift-testing
) need to communicate to clients which cases require it as a dependency.
I agree with @grynspan's idea that the documentation should be improved to address this issue; it's our best way to teach developers about the ideal way to handle this case. I totally get that it means we're not having the API self-document or self-disclose the ideas to a user, but this is a rare moment where I think that's ideal because it ensures we apply a lesson learned from XCTest, which is that floating point comparisons are hard and not something the testing library should be in the business of trying to get right with its own matchers.
Silly proof-of-concept adding ±
to the library here. 🙃
Took a stab at documenting this issue here
Tracked internally as rdar://122981969.