Skip to content

Persistence, migration, networking, and contract tests

Boundary tests prove translation and failure behavior that pure domain tests cannot see. They should use the smallest real boundary available: an in-memory container, temporary directory, intercepted URL request, or credential-free local service.

Run one storage contract everywhere

protocol NoteLibraryContract {
func makeLibrary() async throws -> any NoteLibrary
}
func verifyRoundTrip(using contract: NoteLibraryContract) async throws {
let library = try await contract.makeLibrary()
let note = Note.fixture(title: "Creek crossing")
try await library.save(note)
let loaded = try await library.note(id: note.id)
#expect(loaded == note)
}

Run the same identity, ordering, replacement, deletion, invalid-data, and read-after-write cases against memory and persistent adapters. Automated stores belong in unique temporary locations and clean themselves up.

Keep historical fixtures

A fresh latest schema does not test migration. Preserve small versioned stores created by supported old releases. Test successful migration, missing optional data, incompatible relationships, interruption, and recovery from corrupt or unreadable files. Never silently replace durable user data with an empty store.

Test the transport contract

Intercept requests below the client or point them at a deterministic local mock. Assert method, URL construction, headers without secret values, body encoding, status handling, DTO decoding, pagination, cancellation, and bounded retry. Production cloud services make poor default test dependencies.

Test multi-resource failure cleanup. If attachment bytes succeed but note metadata fails, the adapter must remove or reconcile the orphan according to an explicit transaction policy.

Validation boundary

The contract shape is instructional. SwiftData and Core Data migrations require their Apple frameworks and are not marked as executed by the site build.

Series navigation

References

  • SwiftData documents Apple’s modern persistence framework.
  • Core Data documents object graph persistence and migration capabilities.
  • URL Loading System covers requests, responses, sessions, and protocol loading.