apple / swift-testing

A modern, expressive testing package for Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Document the recommended pattern for performing floating point equality-with-accuracy expectations, analogous to XCTAssertEqual(_:_:accuracy:)

Kyle-Ye opened this issue · comments

commented

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.

commented

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.