Repository navigation
Testing and Quality
Herald uses Swift Testing (not XCTest). Tests are organized by feature, with injected fakes for all dependencies.
-
HeraldTests/— App-level tests (view models, compose, notifications, analytics) -
HeraldKit/Tests/HeraldKitTests/— Kit-level tests (sync, auth, API, drafts)
Test suites use the @Suite / @Test macro syntax. Each test file is a struct with test methods.
Swift Testing conventions:
- Swift Testing only (
@Suite/@Test/#expect); no XCTest - Protocol-oriented fakes (injected via
nonisolated protocols) - Protocols meant to be adopted by fakes are declared
nonisolated protocol … : Sendable - No mocking frameworks; hand-written fakes
- Assertions use
#expect(condition), notXCTAssertTrue
-
FakeMailAPIClient(HeraldKit/Tests/HeraldKitTests/Sync/FakeMailAPIClient.swift:9) — Records calls and returns fixtures -
FakeServer(HeraldKit/Tests/HeraldKitTests/Support/FakeServer.swift:55) — URLProtocol-based fake HTTP server -
FakeTokenProvider(HeraldKit/Tests/HeraldKitTests/Support/FakeTokenProvider.swift:8) — In-memory account and token store -
FakeOutbox(HeraldTests/ComposeViewModelTests.swift:10) — Records sent messages
From Xcode, select the test target and press Cmd+U.
From the command line:
xcodebuild test -project Herald.xcodeproj -scheme Herald -destination 'platform=macOS' -derivedDataPath DerivedDataThe Herald scheme runs both HeraldTests and HeraldKitTests (roughly 370 tests today). Analytics tests run inside the sandboxed host, so they use throwaway app ids and temp queue directories — never the production UserDefaults suite.
UI Tests — The herald-ui-tests scheme exercises the full app with keyboard and mouse automation. Do NOT run UI tests automatically or in CI; they take over the screen and keyboard. Run scripts/ui-tests.sh only with explicit approval from the project owner, as it locks the machine for the duration of the test.
Tests are "discriminating" — they exercise a real feature end-to-end using fakes at the boundary, not mocks scattered throughout. For example:
- An auth test uses a real
AuthCoordinatorwith aFakeAuthorizationPresenter - A sync test uses a real
SyncEnginewith aFakeMailAPIClient - A view-model test uses a real
MailViewModelwith aFakeMailAPIClientandFakeOutbox
This style catches integration bugs that mocks would hide.
Last updated: 2026-09-29 — testing and quality runbook; added UI test warning and runbook reference
Herald is AGPL-3.0. This wiki lives in the repo's wiki/ folder and is managed by Memophant — see Wiki Maintenance.