在 CAD 几何内核、数值计算库以及任何涉及浮点数序列化与几何变换的场景中,回归测试的核心挑战在于 “确定性输出” 的定义。传统单元测试通过断言具体值来验证行为,但几何计算中相同输入在不同平台、不同编译器版本甚至不同优化级别下都可能产生微小的数值差异。Golden Testing 正是为解决这一工程困境而设计的测试范式:它将预期输出以规范化文件的形式存储为基准(gold file),每次测试运行时将实际输出与基准进行容差比较,超出阈值的差异则报告为回归或变更。
为什么 CAD 几何库特别需要 Golden Testing
CAD 几何内核处理的数值问题具有鲜明的特殊性。首先,几何基元(点、线、曲面、实体)之间的拓扑关系对数值精度高度敏感 —— 两个相切圆的切点坐标在浮点运算中可能发生微小偏移,导致原本应当相连的边变为分离状态。其次,布尔运算、倒角、扫掠等复合操作的数值稳定性问题会在几何空间而非标量空间累积放大。此外,CAD 模型通常需要跨平台交换(STEP、IGES 等格式),同一实体的序列化表示在不同实现中可能因坐标顺序、精度格式或容差策略而产生差异。
通用测试框架在这些场景中的容差比较能力有限。传统断言要求精确相等或使用固定 epsilon 值,无法表达相对误差、ULP 差异或拓扑等价性。相比之下,Golden Testing 允许测试作者针对具体几何特征定义合理的容差策略 —— 坐标比较使用相对误差容差,拓扑验证使用集合相等性容差,体积面积等派生属性则可使用比例容差。这种灵活的性能与确定性之间的平衡,正是 CAD 几何库测试所必需的。
浮点容差比较的多层次策略
有效的浮点容差策略需要在检测真实回归与容忍合法数值差异之间找到精确的分界点。实践中推荐采用分层容差机制,针对不同几何特征类型配置差异化的比较参数。
基础层是坐标级容差。对于三维坐标点的 x、y、z 分量,建议采用相对误差与绝对误差的组合形式:比较结果必须同时满足 |actual - expected| <= max(relative_tolerance * |expected|, absolute_tolerance)。在 CAD 精度需求下,绝对容差通常设为 1e-9 到 1e-12 量级(取决于模型单位尺度),相对容差则设为 1e-9 到 1e-6。OpenCASCADE 等主流几何内核采用局部容差机制,将容差值附加到具体的顶点、边、面而非全局设置,这种设计反映了真实 CAD 场景中不同区域的精度需求确实存在差异。
拓扑级容差关注实体结构的稳定性而非单点精度。验证内容应包括面、边、顶点的数量匹配,连通性图的同构性,以及 Euler-Poincaré 不变量的一致性。当布尔运算的数值结果导致原本相邻的面被融合或分裂时,拓扑容差验证能够捕获这类结构性回归,尽管此时坐标容差可能仍然满足要求。
派生属性容差用于验证体积、表面积、质心等聚合计算的正确性。由于这些属性是多个坐标的函数,其数值敏感性可能高于或低于单点坐标。建议采用相对容差(通常设为 1e-6 到 1e-4)并结合绝对阈值,以避免在属性值接近零时相对误差定义失效。
高级场景中可考虑 ULP(Unit in Last Place)容差。在需要跨 ISA、跨编译器甚至跨语言实现保持位级一致性的场景中,可以将浮点数转换为整数 ULP 距离进行比较。这种方法能够检测到看似微小的数值差异背后可能存在的算法或实现层面的实质性改变,尽管其代价是测试用例的可移植性限制。
几何序列化一致性验证的实现路径
几何序列化一致性验证是 Golden Testing 在 CAD 场景中的核心应用之一。其目标不仅是检测已知回归,更关键的是确保几何数据在序列化与反序列化的往返过程中保持语义等价性。
序列化格式的选择直接影响比较策略的复杂度。文本格式(JSON、XML)便于人类阅读和调试,变更追踪成本低,但数值精度表达能力和文件大小都是其劣势。二进制格式在精度保持和文件效率上占优,但调试成本显著增加。实践中可以根据场景权衡:短期开发迭代阶段使用文本格式便于审查 diff,长期归档或性能敏感场景切换为二进制格式。无论采用何种格式,关键约束是序列化器必须产生确定性的输出 —— 元素顺序固定、浮点数格式化一致、不依赖运行时内存布局。
几何模型的规范化是实现有效比较的前提条件。同一 CAD 模型在内存中可能有多种等价表示方式(例如,面可以按不同顺序遍历顶点,边可以沿不同方向定义)。在进行序列化比较之前,必须将几何数据规范化为唯一的标准形式。具体技术包括:对顶点列表进行排序并建立规范索引,对拓扑连接关系进行正则化处理,对浮点数值按指定精度截断或舍入。对于需要支持跨版本兼容性的场景,还应在 gold 文件中嵌入元数据,包括几何内核版本、输入参数 hash、生成时间戳等信息,以便在比较失败时辅助定位根因。
往返测试(Round-trip Test)是验证序列化一致性的关键机制。标准流程是:加载参考几何、执行往返操作(序列化→反序列化)、比较往返前后的一致性。这个测试能够验证序列化格式的完整性以及解析器的正确性,是防止精度侵蚀的屏障。
CI 中 Gold 文件的生命周期管理
Gold 文件管理是 Golden Testing 能否真正融入 CI 流程的关键障碍。管理策略的核心问题有两个:何时更新 gold 文件,以及谁来审核更新。
自动更新机制适合非回归场景。当性能测试的基准发生合法变化(如硬件升级、编译器优化导致的预期提升)时,可以在 CI 中配置在特定分支或标签下自动更新 gold 文件。这种方式需要谨慎使用,因为自动更新可能掩盖真正的回归。更好的实践是将其限制在明确的性能回归排除列表范围内,并要求所有自动更新都必须生成可审计的 diff 记录。
人工审核更新适合功能变更场景。当几何内核的功能演进(如新增布尔运算算法、修改曲面离散化精度)导致预期输出发生合理变化时,必须由开发者提交 gold 文件更新并附带变更说明。这种 workflow 的关键是确保 gold 文件更新与代码变更处于同一个 Pull Request 中,避免两者分离导致的审计困难。
Gold 文件的版本控制策略需要考虑二进制内容的特殊性。对于文本格式的 gold 文件,可以直接存储在 git 仓库中进行 diff 追踪。对于二进制格式的 gold 文件,建议额外存储一份对应的 hash 清单文件,以便在 CI 中快速检测变更而无需传输完整的二进制文件。大型项目的 gold 文件库可以考虑拆分为多个子模块或采用 Git LFS 管理,以优化仓库体积和 checkout 速度。
CI job 的配置应遵循最小权限原则。Gold 文件的写入权限应当与代码写入权限分离 —— 开发者可以提交代码变更,但 gold 文件更新需要通过专门的 CI job 在受控环境下执行,并生成变更记录供 reviewer 审核。失败报告的格式设计同样重要:除了通过 / 失败的二元判定,应当提供结构化的 delta 报告,列明每个超差项的期望值、实际值、绝对误差和相对误差,以便开发者快速定位问题根源。
工程落地的关键参数建议
基于行业实践的总结,以下参数配置可以作为 CAD 几何库 Golden Testing 的起点。坐标比较容差推荐相对误差 1e-9、绝对误差 1e-12,适用于以米为单位的模型;拓扑比较要求面、边、顶点数量精确匹配且 Euler 特征数一致;派生属性容差推荐相对误差 1e-6。对于涉及 IGES、STEP 等标准格式交换的场景,还应额外验证公差带(tolerance band)内的几何等价性,而非简单的坐标相等性。
Gold 文件格式建议在开发阶段使用 JSON 并在 CI 中转换为紧凑的二进制格式存储;元数据应包含几何内核版本号、输入数据 hash、生成环境描述;文件命名遵循 test_case_name.variant.gold.json 的模式以支持变体测试。
测试用例的选择策略应遵循覆盖度与成本的平衡原则。初始阶段聚焦于核心几何基元(Box、Cylinder、Sphere、Torus)及其布尔组合的确定性输出;扩展阶段覆盖边界条件(相切、相交、几乎共面)、退化情况(零厚度、尖角)以及复杂扫掠与混合曲面的数值稳定性;最终阶段覆盖跨平台交叉验证子集,确保 gold 文件在目标部署环境中的有效性。
资料来源
本文档参考了浮点容差比较的技术文献与 CAD 几何内核测试实践,综合了 OpenCASCADE 自动化测试系统的组织结构与容差策略设计理念。数值容差参数的具体取值需根据实际项目的单位系统、精度需求和性能约束进行调整。
资料来源:Floating-point consistent cross-verification methodology(arXiv:2603.02871)、Boost Test Library 浮点比较文档、Open CASCADE Technology 自动化测试系统、libIGES 几何内核实现。
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。