应该增加一套分层测试体系,而不是只新增一个“大而全”的测试项目

发布时间:2026/10/9 5:36:30
应该增加一套分层测试体系,而不是只新增一个“大而全”的测试项目
应该增加一套分层测试体系而不是只新增一个“大而全”的测试项目。并且不要把现有的MaxWell.Driver.Test当成单元测试工程它目前是可部署的测试驱动程序集不是dotnet test项目。核心目标应是每一条业务需求、每个安全联锁、每种协议报文、每个故障恢复场景都有可重复执行的验证方式。测试结构tests/ ├─ MaxWell.Core.Tests/ 状态机、命令、结果模型 ├─ MaxWell.Workflow.Tests/ 工站流程、互锁、取消、恢复 ├─ MaxWell.Communication.Tests/ TCP、串口抽象、超时、重连 ├─ MaxWell.Automation.Tests/ JSON/TCP 协议解析与幂等 ├─ MaxWell.SecsGem.Tests/ SECS/GEM 指令与状态映射 ├─ MaxWell.Persistence.Tests/ SQLite、CSV、断电恢复、Outbox ├─ MaxWell.Configuration.Tests/ Stations.json、PLC.csv、配方校验 ├─ MaxWell.IntegrationTests/ 模拟多工站端到端流程 └─ MaxWell.HardwareTests/ 实验台真实硬件测试不进普通 CI测试层级应如下真实硬件在环测试 少量、受控、实验室执行 端到端模拟测试 完整生产流程 组件集成测试 TCP / SQLite / 文件 / 协议 纯单元测试 状态机、校验、转换、工艺规则首先需要的架构调整当前项目中存在DeviceManager.Instance、UniverseData、LogHelper、DateTime.Now、AppContext.BaseDirectory、MessageBox等全局依赖。它们会让测试互相污染也无法构造稳定场景。测试前应优先抽象以下接口IClock// 替代 DateTime.NowIFileSystem// 替代 File / Directory 静态调用IStationDeviceFactory// 创建设备或模拟设备IPlcDriver// PLC 读写边界IMainBoardClient// 主控板边界IAlarmSink// 报警输出IOperationJournal// 审计与恢复记录IUserContext// 当前登录用户与权限例如PLCController当前直接依赖具体AuxPLC测试异常读写、寄存器变化和断线会很困难。应让控制器面向IPlcDriver再用真实AuxPLC或FakePlcDriver注入。StationWorkflowStateMachine、StationCommandMailbox等内部类可以在程序集增加[assembly:InternalsVisibleTo(MaxWell.Workflow.Tests)]这样可以测试内部核心逻辑而不必为了测试把实现类暴露为 public。每个核心模块的测试重点模块应测试内容工站状态机所有合法和非法状态迁移、状态版本递增、事件仅触发一次、停止/复位/恢复边界命令邮箱同站串行、跨站并行、高优先级复位取消普通命令、关闭时排队命令的结果PLC 控制器快照有效性、断线后旧快照失效、批量读取、地址映射、写入重试、轮询异常限频TCP 通信半包、粘包、远端关闭、超时、重连、部分发送、并发读写隔离主控板协议帧校验、校验和、非法长度、超时、迟到响应、命令与响应关联自动化协议JSON 格式错误、字段缺失、未知命令、重复 SN、响应回放、会话断开SECS/GEMSxFy 解析、控制状态、远程命令许可、S1F3 状态变量顺序、异常回包数据文件CSV 转义、异步队列背压、文件发布失败、临时文件恢复、重复写入SQLite新库建表、迁移、事务回滚、并发写、数据库锁、损坏数据库的安全降级配置JSON/INI/CSV Schema、重复工站、无效端口、重复 PLC 地址、配方越界权限操作员不能复位/改配方工程师不能管理用户协议调用不能绕过 UI 权限恢复程序中断、未完成产品、重新启动、人工清料、恢复确认后的状态变化当前 TestDataDbService.cs 中InitializeTable()被注释应新增“空目录首次运行可建库”的集成测试防止新机部署后首条数据失败。先实现的 12 个高价值测试工站不能从Offline直接进入WorkflowRunning。Reset到达时尚未执行的普通SOT命令必须被取消。PLC 断线后流程不能使用旧快照继续测试。PLC 一次读取失败后快照必须标记为IsValid false。TCPSend只发送部分字节时驱动必须继续发送至完整报文。TCP 对端关闭后下一条安全命令可重连非幂等命令不得盲目重试。Automation 同一Station SN Command重复提交时不得重复驱动硬件。SECS/GEM 在OnlineLocal状态下必须拒绝远程控制命令。CSV 发布失败时缓存文件必须保留且可重试发布。SQLite 新建数据库时必须完成 schema 初始化和索引创建。应用异常退出后存在未完成操作时工站必须进入RecoveryRequired。未授权用户即使通过 Automation/EAP 入口提交命令也必须被拒绝并审计。测试项目配置由于当前公共构建配置默认使用net8.0-windows和 WPF第一阶段测试项目可以同样定位到 WindowsProjectSdkMicrosoft.NET.SdkPropertyGroupTargetFrameworknet8.0-windows/TargetFrameworkIsTestProjecttrue/IsTestProjectUseWPFfalse/UseWPFNullableenable/Nullable/PropertyGroupItemGroupProjectReferenceInclude..\..\MaxWell.Driver.M\MaxWell.Driver.M.csproj/PackageReferenceIncludeMicrosoft.NET.Test.Sdk/PackageReferenceIncludexunit/PackageReferenceIncludexunit.runner.visualstudioPrivateAssetsall/PackageReferenceIncludecoverlet.collectorPrivateAssetsall//ItemGroup/Project包版本应统一放到Directory.Packages.props。目前根目录的Directory.Build.props和Directory.Packages.props都维护了部分包版本开测前应先统一避免测试与生产引用不同版本。示例状态机测试风格publicsealedclassStationWorkflowStateMachineTests{[Theory][InlineData(StationButtonState.Offline,StationButtonState.Initializing,true)][InlineData(StationButtonState.Offline,StationButtonState.WorkflowRunning,false)][InlineData(StationButtonState.WorkflowRunning,StationButtonState.Resetting,true)]publicvoidTransition_should_follow_lifecycle_rules(StationButtonStatecurrent,StationButtonStatenext,boolexpected){varresultStationWorkflowStateMachine.CanTransition(current,next);Assert.Equal(expected,result);}}测试名称建议统一使用Given_前置条件_When_执行动作_Then_预期结果例如Given_plc_snapshot_is_invalid_When_start_test_Then_command_is_rejected Given_duplicate_automation_sn_When_sot_received_Then_hardware_is_invoked_once Given_database_write_fails_When_test_completed_Then_station_enters_data_storage_fault模拟器比 Mock 更重要工业软件仅靠 Mock 不足以验证流程。需要提供可执行的模拟设备FakePlcDriver ├─ 预置寄存器值 ├─ 模拟地址变化 ├─ 模拟超时、断线、错误码 └─ 记录写命令顺序 FakeMainBoardClient ├─ 模拟测试启动 ├─ 模拟采样数据 ├─ 模拟迟到响应 └─ 模拟板卡报警 FakeBarcodeScanner ├─ 成功扫码 ├─ 空码 ├─ 重复码 └─ 超时 FakeLoadUnitDriver ├─ 正常状态 ├─ 温度异常 ├─ 通信失败 └─ 运行中断有了这些模拟器就可以运行完整流程开批 → 上料 → 扫码 → 预测试 → 正式测试 → 数据落库 → CSV 发布 → 下料 → 结批这类测试放在MaxWell.IntegrationTests不连接真实硬件。UI 和硬件测试策略WPF 不应成为最先投入自动化的层。优先测试 ViewModel、命令和状态绑定页面本身只做少量冒烟测试。真实硬件测试必须独立MaxWell.HardwareTests只允许在实验台运行并通过环境变量显式启用RUN_HARDWARE_TESTStrue普通开发机、PR CI、发布 CI 一律不运行硬件测试避免误动作。CI 门禁当前完整MaxWell.sln受 .NET Framework 工具项目影响不能稳定构建。建议新增MaxWell.CI.sln先只包含 SDK 风格项目和测试项目旧工具迁移完成后再回归主解决方案。每次 Pull Request 至少执行dotnet restore dotnet build MaxWell.CI.sln -c Release dotnet test MaxWell.CI.sln -c Release dotnet test --collect:XPlat Code Coverage生成trx测试报告Cobertura 覆盖率报告构建日志失败时的协议报文、SQLite 数据库和流程事件日志建议指标状态机、互锁、权限、协议解析分支覆盖率 100%新增流程功能必须带自动化测试核心 Runtime逐步达到 80% 行覆盖率、70% 分支覆盖率每个已修复生产问题必须新增回归测试UI 覆盖率不作为主指标业务与安全行为覆盖率优先实施顺序新建tests/、xUnit 基础设施、CI 专用解决方案。先测状态机、命令邮箱、配置解析和协议解析等纯逻辑。抽象 PLC、文件、时钟、数据库和用户上下文移除关键流程对静态对象的直接依赖。加入模拟 PLC、主控板、扫码器完成工站端到端模拟流程。增加 SQLite、CSV、恢复和断电场景。最后增加 WPF 冒烟测试与实验台硬件在环测试。“测试每个功能”不应理解为测试每一行私有实现而应建立需求到测试的追踪表每项功能、每条安全规则、每种报警、每个外部协议命令都至少有一个可重复的自动化验收测试。