Repository navigation
Testing
How Bòcan is tested, and which command to run. The detail is in DEVELOPMENT.md.
| Layer | Where | Command | Runs in CI |
|---|---|---|---|
| Module unit and integration tests | Modules/<Name>/Tests/ |
make test-<module> |
Five of the twelve: audio-engine, persistence, metadata, library, ui
|
| App unit tests |
Tests/AppTests (the BocanTests Xcode target) |
make test |
Yes |
| Snapshot tests | The UI package |
make test-ui |
No, the snapshot suite is disabled when CI is set |
| Script tests | Scripts/tests |
make test-scripts |
Yes, on Linux |
| End-to-end tests |
UITests (XCUITest) |
make test-e2e, make test-e2e-smoke
|
No, opt-in |
| When | Command |
|---|---|
| During work on one module | make test-<module> |
| Before each commit | make format && make lint && make build && make test-coverage |
| Before a pull request |
make tests (format, lint, and the full matrix) |
| Before a release, quick |
make test-e2e-smoke (about ten minutes) |
| Before a release, full |
make test-e2e (about thirty minutes; do not touch the Mac while it runs) |
Each module is a Swift package with its own tests. The module names for make test-<module> are:
observability, persistence, metadata, library, acoustics, audio-engine, playback, scrobble, subsonic, podcasts, sync-server, ui
make test-audio-engine needs FFmpeg from Homebrew.
The BocanTests Xcode target runs in a standalone process with no host app. AppKit rendering is not available there, so the snapshot tests are in the UI package.
| Target | Command | Includes |
|---|---|---|
BocanTests (Xcode) |
make test |
View model tests, Observability tests, App source-convention tests |
UI package |
make test-ui |
View model tests and snapshot tests |
-
make test-coveragefails if line coverage is below 80%. CI applies the same gate. -
make coverage-allruns the module tests with coverage and applies a floor for each module.
The E2E suite starts the real app many times and drives it through XCUITest. It contains:
- Journeys through the main user flows
- Menu crawls and shortcut-parity tests
- Settings and window crawls
- Visualizer liveness checks
- Accessibility identifier audits
- Loopback servers that stand in for radio stations and podcast feeds, so no test uses the network
The suite is opt-in. It is not part of make test and it does not run on pull requests. The design is in ADR-079 to ADR-086.
Audio fixtures are checked in. They are never generated when a test runs, so the results do not depend on the encoders on a machine. Each set has a generator script:
| Script | Produces |
|---|---|
Scripts/gen-audio-fixtures.sh |
Single-file format samples for the tag reader and writer tests |
Scripts/gen-library-fixtures.sh |
A small untagged library tree with edge cases (hidden file, corrupt file, unicode name) |
Scripts/gen-picard-fixtures.sh |
A Picard-tagged library tree with MusicBrainz ids, sort tags, release types, and cover art |
Run a script only when you must change a fixture. Delete the affected files first, because the scripts skip files that exist. Then commit the output.
-
A new database column needs fixture data.
ColumnPopulationGuardTestsrequires each column oftracks,albums,artists, andcover_artto have a value on at least one fixture row, or an entry in the allow-list with a reason. -
The in-app help has two guards. The help text is in
Modules/UI/Sources/UI/Help/.HelpContentTestsfails when a help string has no String Catalog entry. The E2EShortcutParityTestschecks each shortcut the help mentions against the menus. If you change a shortcut, change the help too. - Replace fixed sleeps with bounded waits in UI tests.
- Read the Testing section of GOTCHAS.md before you debug an E2E failure. It lists the known causes of whole-suite failures.
| Event | Checks |
|---|---|
| Push to a branch | Light CI: lint, format, build, secret scan |
| Pull request | Full suite: build and test, coverage, script tests, Conventional Commit title, release note present |
See The Bòcan Release Process for the full flow.
bocan.app · Source · Report an issue · Releases · Apache 2.0
Features
- Overview
- Playback and Sound
- Formats
- Library
- Browsing and Playlists
- Interface
- Sources and Sync
- Privacy and Engineering
User Guide
In-App Help
- Getting Started
- Podcasts
- Internet Radio
- Subsonic Servers
- Keyboard Shortcuts
- Mouse Buttons
- Supported Formats
Developer Documentation
Design Notes
Links