Skip to content

Test suite audit: remove dead E2E tests, run CI on dev, cover relay protocols - #292

Merged
chrisuthe merged 3 commits into
devfrom
chore/test-suite-cleanup
Aug 27, 2026
Merged

Test suite audit: remove dead E2E tests, run CI on dev, cover relay protocols#292
chrisuthe merged 3 commits into
devfrom
chore/test-suite-cleanup

Conversation

@chrisuthe

Copy link
Copy Markdown
Owner

Summary

Audits the test suite, removes dead weight, closes a CI gap, and adds coverage for the relay wire protocols.

1. Remove dead E2E tests

tests/MultiRoomAudio.E2ETests/ (1,141 lines, 34 [Fact]s) had no .csproj, so nothing ever compiled or ran it. It could not have compiled in any case: it references a PlaywrightFixture that exists nowhere in the repo, there is no Playwright package reference, and the files lack the Playwright and xunit usings.

More to the point, all 21 of its assertions were Assert.True(true, ...) — each test computed a real value, then discarded it into the failure message while asserting the literal true. Even fully wired up, all 34 would have passed against a completely broken app.

Also adds MultiRoomAudio.Tests.csproj to the solution's /tests/ folder, which was an empty placeholder. Without it, solution-level build and test silently skipped the entire suite.

2. Run CI on dev

lint.yml triggered only on main, and docker-publish.yml fires on push only — so a PR targeting dev ran no CI at all, and the suite first ran only after the merge had already landed. Adds dev to both triggers in lint.yml.

This also brings the dotnet format --verify-no-changes gate to dev PRs, where it previously fired only at the dev to main merge. The tree was verified format-clean first, so it introduces no pre-existing failure.

3. Relay wire protocol tests (+23)

The LCUS checksum, the Modbus LRC, and the Denkovi FTDI pin maps encode protocol details that cannot be verified without the physical boards, and an error in any of them silently switches the wrong relay. None had coverage.

Expected values come from the protocol tables documented in CLAUDE.md rather than from the implementations, so the tests fail if either side drifts. The Denkovi DAE-CB/Ro4-USB odd-pin map (D1/D3/D5/D7) is pinned explicitly, with a guard against "simplifying" it back to sequential pins.

Three pure functions were widened to internal so they can be exercised directly (InternalsVisibleTo for the test assembly already existed). Behavior is unchanged.

Verification

  • 246 tests pass (223 existing + 23 new)
  • Release build clean
  • dotnet format makes no changes to the edited files
  • Mutation-tested: breaking the odd-pin map, the LCUS checksum, and the LRC negation fails 18 of the 23 new tests

Note

This is the first PR in this repo that CI will actually run on.

The tests/MultiRoomAudio.E2ETests directory had no .csproj, so nothing
ever compiled or ran it. It could not have compiled in any case: it
references a PlaywrightFixture that exists nowhere in the repo, there is
no Playwright package reference, and the files lack the Playwright and
xunit usings. Every one of its 21 assertions was Assert.True(true, ...),
so all 34 tests would have passed unconditionally even once wired up.

Also add MultiRoomAudio.Tests.csproj to the solution's /tests/ folder,
which was an empty placeholder. Without it, solution-level build and test
silently skipped the entire suite; CI only worked because both workflows
invoke dotnet test against the csproj path directly.

Verified: Release build clean, 223 tests pass via both the csproj and the
solution.
Feature branches target dev, but nothing ran on a pull_request to dev:
lint.yml triggered only on main, and docker-publish.yml triggers on push
only. Every dev-targeted PR therefore opened with zero CI, and the test
suite first ran only after the merge had already landed on dev.

Add dev to both triggers in lint.yml so PRs to dev get the same
build/format/test gate that PRs to main already get.

This also brings the dotnet format --verify-no-changes gate to dev, where
it previously fired only at the dev->main merge. Verified the tree is
currently format-clean, so it introduces no pre-existing failure.
The LCUS checksum, the Modbus LRC, and the Denkovi FTDI pin maps encode
protocol details that cannot be verified without the physical boards, and
an error in any of them silently switches the wrong relay. None of the
three had any test coverage.

Expected values come from the protocols documented in CLAUDE.md rather
than from the implementations, so the tests fail if either side drifts.
The Denkovi DAE-CB/Ro4-USB odd-pin map (D1/D3/D5/D7) is pinned explicitly,
including a guard against "simplifying" it back to sequential pins.

Three pure functions were widened to internal so they can be exercised
directly; InternalsVisibleTo for the test assembly was already present.
Behavior is unchanged:
  - ModbusRelayBoard.BuildModbusCommand: private static -> internal static
  - FtdiRelayBoard.GetBitMaskForChannel: private instance -> internal
    static taking channelCount
  - LcusRelayBoard.BuildCommand: extracted from the inline frame build in
    SetRelay, which required an open serial port

Verified: 246 tests pass (223 + 23 new), Release build clean, dotnet
format makes no changes to the edited files. Mutating the odd-pin map,
the LCUS checksum, and the LRC negation fails 18 of the 23 new tests.
@chrisuthe
chrisuthe merged commit 0dea67d into dev Aug 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant