news 2026/10/9 5:36:26

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
应该增加一套分层测试体系,而不是只新增一个“大而全”的测试项目

应该增加一套分层测试体系,而不是只新增一个“大而全”的测试项目。并且不要把现有的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 个高价值测试

  1. 工站不能从Offline直接进入WorkflowRunning。
  2. Reset到达时,尚未执行的普通SOT命令必须被取消。
  3. PLC 断线后,流程不能使用旧快照继续测试。
  4. PLC 一次读取失败后,快照必须标记为IsValid = false。
  5. TCPSend只发送部分字节时,驱动必须继续发送至完整报文。
  6. TCP 对端关闭后,下一条安全命令可重连,非幂等命令不得盲目重试。
  7. Automation 同一Station + SN + Command重复提交时,不得重复驱动硬件。
  8. SECS/GEM 在OnlineLocal状态下必须拒绝远程控制命令。
  9. CSV 发布失败时,缓存文件必须保留且可重试发布。
  10. SQLite 新建数据库时必须完成 schema 初始化和索引创建。
  11. 应用异常退出后,存在未完成操作时工站必须进入RecoveryRequired。
  12. 未授权用户即使通过 Automation/EAP 入口提交命令,也必须被拒绝并审计。

测试项目配置

由于当前公共构建配置默认使用net8.0-windows和 WPF,第一阶段测试项目可以同样定位到 Windows:

<ProjectSdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net8.0-windows</TargetFramework><IsTestProject>true</IsTestProject><UseWPF>false</UseWPF><Nullable>enable</Nullable></PropertyGroup><ItemGroup><ProjectReferenceInclude="..\..\MaxWell.Driver.M\MaxWell.Driver.M.csproj"/><PackageReferenceInclude="Microsoft.NET.Test.Sdk"/><PackageReferenceInclude="xunit"/><PackageReferenceInclude="xunit.runner.visualstudio"PrivateAssets="all"/><PackageReferenceInclude="coverlet.collector"PrivateAssets="all"/></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){varresult=StationWorkflowStateMachine.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_TESTS=true

普通开发机、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 覆盖率不作为主指标,业务与安全行为覆盖率优先

实施顺序

  1. 新建tests/、xUnit 基础设施、CI 专用解决方案。
  2. 先测状态机、命令邮箱、配置解析和协议解析等纯逻辑。
  3. 抽象 PLC、文件、时钟、数据库和用户上下文,移除关键流程对静态对象的直接依赖。
  4. 加入模拟 PLC、主控板、扫码器,完成工站端到端模拟流程。
  5. 增加 SQLite、CSV、恢复和断电场景。
  6. 最后增加 WPF 冒烟测试与实验台硬件在环测试。

“测试每个功能”不应理解为测试每一行私有实现,而应建立需求到测试的追踪表:每项功能、每条安全规则、每种报警、每个外部协议命令都至少有一个可重复的自动化验收测试。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 5:34:51

GitHub热榜解读:从AI Agent到本地优先,如何看趋势选项目

GitHub热榜的日榜&#xff08;2026-10-02&#xff09;出来了。我从几年前开始养成了每天早晨刷一遍热榜的习惯&#xff0c;不为别的&#xff0c;就想看看社区里最近在折腾什么。今天这份榜单挺有意思&#xff0c;AI Agent类的项目依然强势&#xff0c;但中间混进去好几个做本地…

作者头像 李华
网站建设 2026/10/9 5:32:44

VS Code接入Claude第三方API:Base URL、API Key与settings.json配置指南

1. 先理清思路&#xff1a;扩展、API 与模型服务之间到底怎么配合这两年用 VS Code 做 AI 辅助开发&#xff0c;几乎成了不少开发者的日常。尤其是 Claude 这类模型能力强、代码理解度高的助手&#xff0c;集成进编辑器之后&#xff0c;写代码、改 bug、补测试的效率提升非常明…

作者头像 李华
网站建设 2026/10/9 5:31:58

C++ 编程与 STL 模板:从泛型编程到内存安全详解

1. 引言C 作为一门兼具高性能与灵活性的编程语言&#xff0c;其模板机制和标准模板库&#xff08;STL&#xff09;是每一位开发者都必须掌握的核心知识。模板让代码具备泛型能力&#xff0c;STL 则提供了大量现成的容器、算法和迭代器&#xff0c;而智能指针则帮助我们更安全地…

作者头像 李华