news 2026/9/3 6:13:49

Pelco KBD300A 模拟器:20.搭建pytest集成测试基础框架 + 模拟器闭环测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pelco KBD300A 模拟器:20.搭建pytest集成测试基础框架 + 模拟器闭环测试

第 20 篇:搭建集成测试基础框架 + 模拟器闭环测试

下面我们将一步一步详细完成集成测试基础框架搭建,并实现模拟器闭环测试(串口收到数据 → 协议解析 → VirtualDevice 状态更新 → 可选返回响应)。

目标:

  • 不依赖真实串口硬件
  • 使用 mock 完全控制输入/输出
  • 验证 Pelco-D/P 命令到达 VirtualDevice 后状态是否正确变化
  • 为后续宏 → 串口 → 模拟器链路打基础
20.1 项目结构调整(添加 integration 目录)

在项目根目录下创建以下结构(如果还没有):

KBD300A/ ├── core/ │ ├── protocol/ │ ├── macro/ │ ├── serial/ │ ├── simulator/ │ └── ... ├── ui/ ├── config/ ├── resources/ ├── tests/ ← 新建 │ ├── unit/ ← 已有的单元测试 │ ├── integration/ ← 集成测试放这里 │ │ ├── test_simulator_loop.py │ │ ├── test_macro_to_serial.py │ │ └── ... │ ├── conftest.py ← 全局 fixture │ └── test_data/ ← 测试用 Pelco 命令样本 └── requirements-dev.txt ← 测试依赖

requirements-dev.txt(安装这些包,Python 3.7 兼容):

pytest==6.2.5 pytest-mock==3.6.1 pytest-qt==4.0.2 # 如果涉及 Qt 信号等待 coverage==5.5 # 可选,覆盖率统计

安装:

pipinstall-r requirements-dev.txt
20.2 创建 conftest.py(全局 fixture)

tests/conftest.py

# tests/conftest.pyimportpytestfromunittest.mockimportMagicMockfromcore.simulator.virtual_deviceimportVirtualDevicefromcore.protocolimportget_protocolfromcore.serial.managerimportSerialManager@pytest.fixturedefvirtual_device():"""每个测试一个干净的虚拟设备"""returnVirtualDevice(cam_id=1)@pytest.fixturedefmock_serial():"""模拟 serial.Serial 对象"""mock_ser=MagicMock()mock_ser.is_open=Truemock_ser.in_waiting=0mock_ser.read.side_effect=lambdasize:b""# 默认返回空mock_ser.write=MagicMock()returnmock_ser@pytest.fixturedefmock_serial_manager(mock_serial):"""模拟 SerialManager,注入 mock 串口"""manager=SerialManager(port="COMfake",baud=9600,protocol="D")manager._ser=mock_serial# 直接替换底层串口manager.is_open=Truereturnmanager@pytest.fixturedefpelco_d_protocol(mock_serial_manager):"""Pelco-D 协议实例"""returnget_protocol(mock_serial_manager,"D")@pytest.fixturedefpelco_p_protocol(mock_serial_manager):"""Pelco-P 协议实例"""returnget_protocol(mock_serial_manager,"P")
20.3 准备测试数据(Pelco 命令样本)

tests/test_data/pelco_commands.json中保存一些典型命令(方便复用):

{"pelco_d":{"ptz_right_fast":{"bytes":"FF0100001020004F","description":"地址1,右转速度32","expected_pan":32.0},"call_preset_5":{"bytes":"FF010000071F0067","description":"调用预置位5","preset_id":5},"aux_on_2":{"bytes":"FF0100000B02000E","description":"AUX2 开"}},"pelco_p":{"ptz_up_medium":{"bytes":"A0010008100800AF","description":"地址1,上仰速度8"}}}

加载方式示例:

importjsonfrompathlibimportPath TEST_DATA=json.loads(Path("tests/test_data/pelco_commands.json").read_text())
20.4 实现模拟器闭环测试(核心文件)

tests/integration/test_simulator_loop.py

# tests/integration/test_simulator_loop.pyimportpytestimporttimefromunittest.mockimportcallfromcore.serial.workerimportSerialWorkerfromcore.protocol.pelco_dimportPelcoDProtocolfromcore.simulator.virtual_deviceimportVirtualDevicefromtests.conftestimportmock_serial_manager# 如果需要defload_command_hex(hex_str):"""将 hex 字符串转为 bytes"""returnbytes.fromhex(hex_str)@pytest.mark.integrationdeftest_pelco_d_ptz_command_updates_virtual_device(virtual_device,mock_serial,pelco_d_protocol):""" 测试:收到 Pelco-D 右转命令 → VirtualDevice pan 角度增加 """# 准备输入:右转速度 32 的命令cmd_hex="FF 01 00 00 20 00 21"# 校验和 0x21 = 1+0+0+32+0cmd_bytes=load_command_hex(cmd_hex.replace(" ",""))# 模拟 SerialWorker 收到数据(直接注入 buffer)worker=SerialWorker(port="COMfake",baud=9600,protocol="D")worker._ser=mock_serial worker._buffer=bytearray(cmd_bytes)# 关键:注入 VirtualDevice 到协议层(需要小改 protocol 代码支持)# 临时方案:在测试中 monkey-patch 或直接调用 processpelco_d_protocol.virtual_device=virtual_device# 假设已添加属性# 模拟一次数据处理(实际项目中可调用 worker._process_buffer())parsed=pelco_d_protocol.parse_response(cmd_bytes)# 或者更真实:模拟 worker 处理流程worker._buffer.extend(cmd_bytes)worker._process_buffer()# 如果 _process_buffer 是 public 或可访问# 检查 VirtualDevice 状态status=virtual_device.get_status_dict()assert"pan"instatus pan_value=float(status["pan"].rstrip("°"))assertpan_value>0,"右转命令应使 pan 角度增加"# 可选:验证具体角度(根据 VirtualDevice 内部实现比例)# 假设 VirtualDevice 将 speed 32 映射为 +32 度assertabs(pan_value-32.0)<5.0,f"预期 pan ≈32,实际{pan_value}"@pytest.mark.integrationdeftest_pelco_d_call_preset_triggers_action(virtual_device,mock_serial,pelco_d_protocol):"""测试调用预置位命令是否触发 VirtualDevice 相应逻辑"""cmd_hex="FF 01 00 00 07 05 0D"# 调用预置位 5,校验和 1+0+0+7+5=13=0x0Dcmd_bytes=load_command_hex(cmd_hex.replace(" ",""))# 注入pelco_d_protocol.virtual_device=virtual_device# 处理命令worker=SerialWorker(port="COMfake",baud=9600,protocol="D")worker._ser=mock_serial worker._buffer=bytearray(cmd_bytes)worker._process_buffer()# 或直接调用协议 parse# 假设 VirtualDevice 在 process_command 中记录 preset 调用# 你可以添加断言,例如检查日志或状态# 或者临时添加一个调用计数器属性到 VirtualDeviceasserthasattr(virtual_device,"last_preset_called")assertvirtual_device.last_preset_called==5@pytest.mark.integrationdeftest_pelco_p_aux_on_updates_aux_state(virtual_device,mock_serial):"""Pelco-P 打开 AUX2 测试"""cmd_hex="A0 01 00 0B 02 00 0E AF"# AUX2 ONcmd_bytes=load_command_hex(cmd_hex.replace(" ",""))protocol=PelcoDProtocol(mock_serial)# 改用 P 协议protocol.virtual_device=virtual_device# 处理parsed=protocol._parse_response(cmd_bytes)assertparsed.get("type")=="aux"assertparsed.get("aux_id")==2assertparsed.get("state")=="on"# 验证虚拟设备状态assertvirtual_device.aux_states[2]isTrue
20.5 小幅修改生产代码以便测试

core/simulator/virtual_device.py中添加:

classVirtualDevice:def__init__(self,cam_id:int=1):...self.last_preset_called=None# 测试用defprocess_command(self,data:bytes)->Optional[bytes]:parsed=parse_pelco_packet(data)ifparsed.get("type")=="preset"andparsed.get("operation")=="call":self.last_preset_called=parsed.get("preset_id")# ... 原有逻辑

core/protocol/base.py或具体协议类中添加:

classProtocolBase(ABC):def__init__(self,serial_mgr):self.serial_mgr=serial_mgr self.virtual_device=None# 测试时注入
20.6 运行测试
# 在项目根目录执行pytest tests/integration/ -v --tb=short# 只跑模拟器闭环测试pytest tests/integration/test_simulator_loop.py -v# 带覆盖率pytest --cov=core --cov-report=html tests/integration/

👉上一篇 :pytest集成测试(serial + protocol + macro)

👉总目录:Python开发软键盘全程总览

👉下一篇:

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

IMU如何成为机器人自主移动的核心传感器

IMU是机器人感知自身运动状态的核心传感器&#xff0c;通过内置的加速度计与陀螺仪测量机器人的加速度与角速度&#xff0c;经算法解算后为机器人的控制、导航、平衡等功能提供关键数据&#xff0c;广泛应用于轮式机器人、足式机器人、无人机、机械臂等各类机器人系统中。核心功…

作者头像 李华
网站建设 2026/9/2 21:06:30

解析得物商品详情:API 接口调用实践与数据结构分析

得物平台&#xff08;原毒APP&#xff09;作为国内领先的潮流电商平台&#xff0c;其商品数据具有很高的价值。对于开发者而言&#xff0c;了解如何通过其提供的 API 接口获取商品详情信息&#xff0c;是进行数据分析、比价工具开发、库存监控等应用的基础。本文将聚焦于得物平…

作者头像 李华
网站建设 2026/9/2 12:48:25

车辆轨迹系统设计与实现

车辆轨迹系统设计与实现 一、设计背景与意义 车辆轨迹追踪在智能交通、物流车队管理、私家车防盗、网约车监管等领域具有重要应用价值。传统轨迹记录方式依赖车载终端与后台服务器简单交互&#xff0c;存在定位精度低、数据传输延迟、轨迹补全能力弱等问题&#xff0c;难以满足…

作者头像 李华
网站建设 2026/9/2 21:02:06

黑芝麻智能华山A2000 BaRT工具链:全场景智驾模型高效编译与部署

一、引言 随着智驾模型参数规模与计算复杂度指数级增长&#xff0c;大模型应用与车端硬件、性能功耗的矛盾愈发凸显&#xff0c;成为技术量产的关键瓶颈。在此背景下&#xff0c;黑芝麻智能华山A2000 BaRT 工具链以 MLIR 框架为基础&#xff0c;为辅助驾驶模型规模化、高性能、…

作者头像 李华
网站建设 2026/9/2 22:01:54

本年度必看!最佳信息登记二维码推荐榜单

在数字化的时代&#xff0c;信息登记二维码扮演着越来越重要的角色。通过二维码&#xff0c;企业、政府和个人可以高效管理信息&#xff0c;提升登记的便捷性和准确性。本文将从多个角度分析最佳信息登记二维码工具。每种工具都有其独特的功能和适用场景&#xff0c;让我们轻松…

作者头像 李华
网站建设 2026/9/2 13:31:41

django+Pythonuniapp的鲜花知识分享与销售商城系统的设计与实现小程序

文章目录 系统概述技术架构核心功能模块创新点应用价值 系统设计与实现的思路主要技术与实现手段源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 系统概述 该系统基于Django后端框架与Python语言开发&#xff0c;结合UniApp跨平台前端技…

作者头像 李华