We have long maintained a tool that aids in exhaustively testing state in vanilla SwiftUI applications, but not many know about it. It's called 'expectDifference', and it allows you to capture a piece of state before and after a sequence of user actions takes place, and then it is your job to mutate the before value to equal the after:
@Test func addPlayer() async throws {
await expectDifference(model.rows) {
model.addPlayerButtonTapped()
model.newPlayerName = "Blob Esq"
model.saveNewPlayerButtonTapped()
try await model.$rows.load()
} changes: { rows in
rows.append(
GameModel.Row(
player: Player(
id: UUID(0),
gameID: UUID(-1),
name: "Blob Esq",
score: 0
)
)
)
}
}
This comes with a lot of benefits:
• Possible to assert on the minimal changes that occurred instead of repeating lots of unchanged data.
• Asserts on more of what actually happens in your logic.
• Less likely to take short cuts in asserting because it's so easy to write assertions.
• Great test failure messages!
We employ this technique to great success in this week's episode where we show how to write very strong tests against an app that uses SQLiteData for its persistence:
https://www.pointfree.co/episodes/ep353-tour-of-sqlitedata-advanced-testing
