BitzOrcas tests are not one linear suite with different durations. The solution combines pure-logic tests, source/project structure contracts, container-free API contracts, real-infrastructure contracts, generator consumption, template matrices, and a Consumer Contract that packs locally. Select evidence by changed risk and then widen the scope; that is faster and easier to explain than starting with bare dotnet test.
Choose an entry point
| Change | Minimum feedback | Add before merge |
|---|---|---|
| Aggregate, value object, pure policy | focused Unit/Application filter | both projects + Architecture |
| Handler, pipeline, authorization | focused Application class | Application + container-free Integration |
.csproj, paths, ADR/manifest | focused Architecture class | all Architecture |
| API Shell/middleware | container-free Integration | Architecture + related Unit/Application |
| ORM, schema, migration | matching Docker class/shard | both ORM parity + Architecture |
| CAP/Outbox | messaging shard | container-free + messaging |
| Generator/template | CodeGeneration/Generator.Package/Template | verify-template.sh |
| Commercial package/Profile | focused Consumer/Licensing | Commercial GA evidence chain |
Fast local feedback
# Pure domain and application control flow; use Release like the main gates.dotnet test tests/BitzOrcas.Unit.Tests --configuration Releasedotnet test tests/BitzOrcas.Application.Tests --configuration Release
# Architecture boundaries and API/Host contracts that start no containers.dotnet test tests/BitzOrcas.Architecture.Tests --configuration Releasedotnet test tests/BitzOrcas.Integration.Tests \ --configuration Release --filter 'Category!=Docker'Keep commit, SDK, configuration, and filter stable during one diagnosis. Do not add --no-build unless the same configuration has already built; otherwise stale binaries can run.
Reproduce one failure precisely
Prefer the FullyQualifiedName or matrix filter from CI output. Namespace, class, and method identify intent better than a common method fragment.
# One architecture rule class.dotnet test tests/BitzOrcas.Architecture.Tests \ --configuration Release \ --filter 'FullyQualifiedName~CommercialPackageCatalogTests'
# Website Docker shard; this requires an available Docker daemon.dotnet test tests/BitzOrcas.Integration.Tests \ --configuration Release \ --filter 'Category=Docker&FullyQualifiedName~BitzOrcas.Integration.Tests.Website.' \ --blame-hang-timeout 10mList tests first when checking whether a filter is too broad:
# Discover without execution and confirm project plus category.dotnet test tests/BitzOrcas.Integration.Tests \ --configuration Release --list-tests \ --filter 'FullyQualifiedName~Website.'Generators and templates
“The generator builds inside the repository” and “an isolated project consumes it as a NuGet analyzer” are separate facts. Templates must also prove that Profiles instantiate, restore, and build without referencing product source.
# Verify generation logic, packaged consumption, and template consumption.dotnet test tests/BitzOrcas.CodeGeneration.Tests --configuration Releasedotnet test tests/BitzOrcas.Generator.Package.Tests --configuration Releasedotnet test tests/BitzOrcas.ConsumerTemplate.Tests --configuration Release
# Run the authoritative canonical template matrix.scripts/build/verify-template.shAfter changing generator package assets, use the repository’s package preparation flow. A stale package that happens to exist in the global NuGet cache is not evidence.
Consumer Contract
The local Consumer Contract packs on demand, creates isolated feeds/caches, generates a consumer project, and restores, builds, runs tests, and publishes. It currently passes /p:PublishTrimmed=false, so it proves Release publish consumption—not trimmed publish for every Profile.
# Allow a useful hang-dump window; first run creates packages and isolated caches.dotnet test tests/BitzOrcas.Framework.ConsumerContract.Tests \ --configuration Release \ --blame-hang-timeout 12mFull API Host trim evidence comes from step 12 of verify-all.sh; neither substitutes for the other. Commercial GA also requires the catalog, Profile, and provenance evidence in Consumer contracts.
The fifteen verify-all.sh steps
scripts/build/verify-all.sh is the authoritative local pre-merge entry point. Step numbers match its own log output:
- Gitleaks secret scanning when installed locally; CI keeps the full scan.
- Restore
BitzOrcas.Modern.slnx. dotnet format --verify-no-changesplus unused-using gates.- Release build.
- Solution-wide non-integration tests (Consumer Contract and Architecture run as serial gates afterwards).
- Local PackageReference Consumer Contract, serialized.
- XML file checks.
- XML comment checks.
- Architecture process profiles (cold and warm) plus the full architecture suite including shallow-module deletion gates.
Category!=Dockerintegration tests.- Per-RID restore and a
PublishTrimmed=truepublish of the full API Host. - Roslyn semantic reflection gate (ADR 0102/0103).
- No-T-SQL gate (ADR 0033).
- Production deployment and portability asset checks.
- OpenAPI artifact plus platform-sdk client drift gate.
# Run at repository root; the script exits on the first hard failure.scripts/build/verify-all.shDocker contracts sit outside those fifteen steps and run in the thirteen shards of the docker-integration-contracts workflow. “Local verify-all passed” therefore does not mean every Docker provider contract passed.
Generate a citable acceptance report
report-acceptance.sh writes step, status, duration, command, and summary to .verify-output/acceptance-report.md. It currently has thirteen report steps and is not identical to verify-all.sh: for example it runs Unit and Application separately and its container-free Integration step excludes the API namespace. Do not call it a logging wrapper around the fourteen-step script.
# Generate a Markdown summary and detailed per-step logs; do not commit them.scripts/build/report-acceptance.sh
# Read the first FAIL and reproduce with its original command and environment.sed -n '1,220p' .verify-output/acceptance-report.mdPR evidence should include commit SHA, SDK/RID, command, result, duration, and omitted gates. “Passed locally” is not reproducible evidence.
Handle failures
- Start with the first failed step; later failures may be missing-artifact cascades.
- Reproduce with the original configuration, RID, filter, and environment.
- For restore, inspect isolated feed,
NuGet.Config, and cache path; do not switch to an unknown source. - For Consumer failures identify pack, restore, build, run, or publish stage.
- For Docker inspect daemon, container logs, and readiness before assertions.
- For hangs retain blame evidence and inspect cancellation plus unbounded waits.
- After fixing, run the regression first and then the complete owning gate.
Evidence checklist
- Use authoritative
BitzOrcas.Modern.slnx, not a legacy solution. - Record whether Docker ran and which of the eleven shards were covered.
- Record whether Consumer publish was trimmed; never infer it from Release.
- Logs expose no secret, license material, or connection string.
- Temporary feed, cache, containers, and
.verify-outputstay out of commits. - Record global sweep commands and expected zero-result old patterns.