swift-testing
swift-testing copied to clipboard
Improve diffing of collections and structured values.
This PR improves the test output when comparing collections and structured values (using #expect()) when the comparison fails. Previously, we'd just the insertions and deletions as arrays, which was potentially hard to read and didn't show the test author where these changes occurred. Now, we convert the compared values into something similar to multi-line diff output. Consider the following test function:
@Test func f() {
let lhs = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
let rhs = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
potato salad. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non dentistry, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
#expect(lhs == rhs)
}
The output will now be:
◇ Test f() started.
✘ Test f() recorded an issue at MyTests.swift:45:5: Expectation failed: lhs == rhs
± 2 changes:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod"
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,"
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo"
+ "potato salad. Duis aute irure dolor in reprehenderit in voluptate velit esse"
- "consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse"
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat"
+ "non dentistry, sunt in culpa qui officia deserunt mollit anim id est laborum."
- "non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
✘ Test f() failed after 0.001 seconds with 1 issue.
Similarly, with this test:
struct S: Equatable {
var x: Int
var y: String
}
@Test func f() {
let lhs = S(x: 123, y: "abc")
let rhs = S(x: 123, y: "def")
#expect(lhs == rhs)
}
The output should appear similar to:
◇ Test f() started.
✘ Test f() recorded an issue at MyTests.swift:36:5: Expectation failed: lhs == rhs
± 1 change:
MyTests.S(
x: 123
- y: "abc"
+ y: "def"
)
✘ Test f() failed after 0.001 seconds with 1 issue.
Resolves rdar://66351980.
So many thank yous are in order for you, @grynspan.
It's probably worth updating the docs for this change to mention that the diffing logic uses CustomStringConvertible and CustomDebugStringConvertible via String(describing:) under the hood, which can lead to unexpected diffs if the user does something unique or hard to diff.
Still working on the exact semantics of this change, since the exploded view of a value is not always the right view for comparison. But yes, we'll want to amend documentation at the same time.
@swift-ci please test
@swift-ci please test
@swift-ci please test
Not pursuing at this time—a good implementation probably will look a little different anyway.