Why do we still need custom assertions when #๐‘’๐‘ฅ๐‘๐‘’๐‘๐‘ก is already more informative than XCTest? The key: use ๐‘†๐‘œ๐‘ข๐‘Ÿ๐‘๐‘’๐ฟ๐‘œ๐‘๐‘Ž๐‘ก๐‘–๐‘œ๐‘› to report failures at the call site, not inside helpers. For complex validation, ๐ผ๐‘ ๐‘ ๐‘ข๐‘’.๐‘Ÿ๐‘’๐‘๐‘œ๐‘Ÿ๐‘‘ is the way to go.

๐Ÿ”—: https://qualitycoding.org/swift-testing-custom-assertions/ by Jon Reid (@qcoding)

#SwiftTesting #Swift #iOSDev

How to Make Custom Test Assertions in Swift Testing

Stop chasing test failures through helper functions. Here's how to write custom Swift Testing assertions that report errors exactly where they belong.

Quality Coding
How to Make Custom Test Assertions in Swift Testing https://qualitycoding.org/swift-testing-custom-assertions/ #SwiftTesting

#buildInPublic #iosDev #coreData #swiftTesting

So I now have a start at a merge strategy I can test. Note that in the case of UUID conflicts between inbound and existing entities Iโ€™m taking the inbound UUID, so that if I modify the local storage it doesn't trigger another modification on the remote - a โ€œsync loopโ€. It is still possible to get duplicates locally by creating a new Tune (with a UUID) and then modifying user data to be identical to an existing Tune with a different UUID.
8/n

#buildInPublic #iosDev #coreData #swiftTesting

new merge rule:

if inbound has UUID {
if there is existing with same UUID {
update existing with user data from most recently modified
} else { //no UUID match
if existing with same user data {
update existing with incoming UUID
} else { //no user data match
insert new with incoming UUID and user data
}
}
} else {//no incoming UUID
insert with new UUID
}
7/n

#buildInPublic #iosDev #coreData #swiftTesting

To see if inbound changes apply, I need an invariant identifier so I can tell if I've seen this object before. I don't have one, so I need to add a UUID

6/n

#buildInPublic #iosDev #coreData #swiftTesting

Directly editable attributes are displayName, isFavourite and Notes, others are set by the app. To properly merge logic I must decide
- is an inbound Tune identical to an existing one
- should changes to an inbound tune apply to an existing one.

The rule will be:
A - an inbound tune with identical displayName+notes to an existing one is considered identical
B - isFavourite will be set if either the existing or inbound tune has it set

5/n

#buildInPublic #iosDev #coreData #swiftTesting

So the obvious next step is to be able to import Tune - they're my first entity, and in the real app Tunes can be imported from existing datastores and edited via a text editor.

In my existing basic data model I have:

Tune (inherited from Searchable)
collatingName : String
createdDateTime : Date
displayName : String
isFavourite : Boolean
modifiedDateTime : Date
notes : String

Tune - extension
tuneSets : (many:many) to Set

4/n

#buildInPublic #iosDev #coreData #swiftTesting

I'm going to need test data for the obvious CRUD scenarios, but also special cases to support merging sets and collections, as well as modifying a previously synced entity. The ability to import a text/JSON file would allow me to test merge logic in a repeatable way without worrying about actually setting up cloud sync.

3/n

Parameterized test output in SwiftTesting can be opaque. Conforming to ๐ถ๐‘ข๐‘ ๐‘ก๐‘œ๐‘š๐‘‡๐‘’๐‘ ๐‘ก๐‘†๐‘ก๐‘Ÿ๐‘–๐‘›๐‘”๐ถ๐‘œ๐‘›๐‘ฃ๐‘’๐‘Ÿ๐‘ก๐‘–๐‘๐‘™๐‘’ produces clear descriptions of exactly which parameters caused a failure.

๐Ÿ”—: https://craftingswift.dev/articles/improve-swifttesting-parameterized-tests-with-customteststringconvertible/ by Felipe Espinoza

#SwiftTesting #Testing #iOSDev

Improve SwiftTesting Parameterized Tests with `CustomTestStringConvertible`

A small protocol conformance helps improve your test output.

CraftingSwift

#buildInPublic #iosDev #coreData #swiftTesting

Since Iโ€™m eventually going to have to take a populated database and convert it from the old model to the new model, Iโ€™m going to tag the current repo so I can come back to it and build my test data. I should build a test database now that covers all the cases, but I am pretty sure that Iโ€™ll think of more as I go along.

Nevertheless, first order of business is to build some infrastructure to populate the test database.

2/n