BitzOrcas 的测试不是一条耗时不同的直线。解决方案同时包含纯逻辑测试、源码/项目结构合同、无容器 API 合同、真实基础设施合同、生成器消费、模板矩阵和现场 pack 的 Consumer Contract。先按改动风险选择证据,再逐步扩大范围,比从裸 dotnet test 开始更快、更容易解释。
选择入口
| 改动 | 最小反馈 | 合并前补充 |
|---|---|---|
| 聚合、值对象、纯策略 | Unit / Application 定向 filter | 两项目全量 + Architecture |
| Handler、pipeline、授权 | Application 定向类 | Application + 无 Docker Integration |
.csproj、目录、ADR/manifest | Architecture 定向类 | Architecture 全量 |
| API Shell/中间件 | 无 Docker Integration | Architecture + 相关 Unit/Application |
| ORM、schema、migration | 对应 Docker 类/分片 | 两 ORM parity + Architecture |
| CAP/Outbox | messaging 分片 | 无 Docker + messaging |
| Generator/模板 | CodeGeneration/Generator.Package/Template | verify-template.sh |
| 商业包/Profile | Consumer/Licensing 定向 | Commercial GA 证据链 |
快速本地反馈
# 纯领域和应用控制流;使用 Release 保持与主要门禁一致。dotnet test tests/BitzOrcas.Unit.Tests --configuration Releasedotnet test tests/BitzOrcas.Application.Tests --configuration Release
# 架构红线,以及不启动容器的 API/Host 合同。dotnet test tests/BitzOrcas.Architecture.Tests --configuration Releasedotnet test tests/BitzOrcas.Integration.Tests \ --configuration Release --filter 'Category!=Docker'同一次诊断保持 Commit、SDK、Configuration 和 filter 不变。若先前没有用相同配置构建,不要添加 --no-build;否则可能在运行旧二进制。
精确复现一个失败
优先复制 CI 日志里的 FullyQualifiedName 或 matrix filter。名称包含命名空间、类和方法,比只写一个常见方法片段更不容易误选。
# 单个架构规则类。dotnet test tests/BitzOrcas.Architecture.Tests \ --configuration Release \ --filter 'FullyQualifiedName~CommercialPackageCatalogTests'
# Website Docker 分片;本命令需要可用 Docker daemon。dotnet test tests/BitzOrcas.Integration.Tests \ --configuration Release \ --filter 'Category=Docker&FullyQualifiedName~BitzOrcas.Integration.Tests.Website.' \ --blame-hang-timeout 10m先列出测试可检查 filter 是否过宽:
# 只列出,不执行;确认结果属于预期项目和分类。dotnet test tests/BitzOrcas.Integration.Tests \ --configuration Release --list-tests \ --filter 'FullyQualifiedName~Website.'生成器与模板
生成器“在仓库项目内能编译”与“作为 NuGet analyzer 被隔离项目消费”是两项证据。模板还需要证明不同 Profile 能实例化、restore、build,且不回引产品源码。
# 编译期输出逻辑、打包消费、模板消费分别验证。dotnet test tests/BitzOrcas.CodeGeneration.Tests --configuration Releasedotnet test tests/BitzOrcas.Generator.Package.Tests --configuration Releasedotnet test tests/BitzOrcas.ConsumerTemplate.Tests --configuration Release
# 运行权威 canonical template matrix。scripts/build/verify-template.sh修改 Generator 包资产时,先执行仓库提供的 package preparation 流程;不要用本机全局 NuGet 缓存偶然存在的旧包解释成功。
Consumer Contract
本地 Consumer Contract 会现场 pack、创建隔离 Feed/缓存、生成消费项目并 restore/build/run 测试。它当前显式传入 /p:PublishTrimmed=false,所以证明 Release publish 消费,不证明每个 Profile 的 trimmed publish。
# 允许足够的 hang 诊断窗口;首次运行会创建包和隔离缓存。dotnet test tests/BitzOrcas.Framework.ConsumerContract.Tests \ --configuration Release \ --blame-hang-timeout 12m完整 API Host 的 trim 证据来自 verify-all.sh 第 12 步,两者不可互相替代。商业 GA 还需要 Consumer 合同 所列的 catalog/Profile/provenance 证据。
verify-all.sh 的 15 步
scripts/build/verify-all.sh 是合并前权威本地入口,步骤编号即脚本回显:
- Gitleaks 密钥扫描(本地安装时运行;CI 执行完整扫描)。
- Restore
BitzOrcas.Modern.slnx。 dotnet format --verify-no-changes加未用 using 门禁。- Release build。
- 解决方案级非集成测试(Consumer Contract 与 Architecture 由后续串行门禁负责)。
- 本地 PackageReference Consumer Contract(串行执行)。
- XML 文件检查。
- XML 注释检查。
- 架构 process profiles(cold/warm 各一遍)+ 完整架构套件(含浅模块删除门禁)。
Category!=Docker集成测试。- 按当前 RID restore,并对完整 API Host 执行
PublishTrimmed=true。 - Roslyn 语义反射门禁(ADR 0102/0103)。
- No T-SQL 门禁(ADR 0033)。
- 生产部署与可移植性资产检查。
- OpenAPI artifact 与 platform-sdk client 漂移门禁。
# 从仓库根目录运行;脚本遇到首个硬失败立即退出。scripts/build/verify-all.shDocker 合同不在这 15 步里,由 docker-integration-contracts workflow 的 13 个分片补齐。因此“本地 verify-all 通过”不等于“所有 Docker provider 合同已通过”。
生成可引用验收报告
report-acceptance.sh 把步骤、状态、耗时、命令和摘要写入 .verify-output/acceptance-report.md。它的步骤集合与 verify-all.sh 并不相同——例如分别运行 Unit/Application、串行跑架构 process profiles,且无 Docker Integration 排除 API namespace;不要把它描述成 verify-all 的日志包装器。
# 生成 Markdown 汇总和每步详细日志;目录不应提交 Git。scripts/build/report-acceptance.sh
# 失败后读取首个 FAIL 的日志,保留原命令和环境再复现。sed -n '1,220p' .verify-output/acceptance-report.mdPR 证据至少记录 Commit SHA、SDK/RID、命令、结果、运行时间和未覆盖项。只写“本地通过”无法复现。
失败处理
- 从第一个失败步骤开始,后续失败可能只是制品缺失的连锁反应。
- 用原 Configuration、RID、filter 和环境复现定向用例。
- Restore 失败检查隔离 Feed、
NuGet.Config与缓存路径,不要临时切到未知源。 - Consumer 失败区分 pack、restore、build、run、publish 哪一阶段。
- Docker 失败先检查 daemon、容器日志、readiness,再检查业务断言。
- hang 使用 blame 证据,检查取消令牌和无上限等待。
- 修复后先跑回归用例,再跑所属完整门禁。
证据清单
- 使用权威
BitzOrcas.Modern.slnx,而不是遗留 solution; - 记录是否包含 Docker,以及具体 11 分片中的哪些;
- 记录 Consumer publish 是否 trim,不能靠“Release”推断;
- 测试日志没有暴露 secret、license 或连接字符串;
- 临时 Feed、缓存、容器和
.verify-output未进入提交; - 全局 sweep 命令和预期零结果随改动一起记录。