ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FreeCAD OpenSCAD 模块单元测试框架:继承自 FEM 的测试体系与运行指南

FreeCAD OpenSCAD 模块单元测试框架:继承自 FEM 的测试体系与运行指南 FreeCAD OpenSCAD 模块单元测试框架继承自 FEM 的测试体系与运行指南【免费下载链接】FreeCADOfficial source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.项目地址: https://gitcode.com/GitHub_Trending/fr/FreeCADFreeCAD 的 OpenSCAD 工作台src/Mod/OpenSCAD维护着一套完整的单元测试体系其测试信息文档明确交代了一个关键事实OpenSCAD 的测试框架基于 FEM 模块的测试构建。这意味着它的目录组织、测试运行方式、数据文件管理都与 FEM 测试一脉相承。读完本文你将掌握 OpenSCAD 测试代码的组织结构、每个测试用例验证的导入功能点、测试数据的来源与作用以及从 FreeCAD 内部或命令行运行这些测试的完整方法并了解如何参照这套体系扩展新的测试。一、框架来源FEM 测试体系的结构模板OpenSCAD 测试框架基于 FEM 模块的测试这一声明在仓库中可以直接得到印证两个模块的测试目录结构高度一致。FEM 模块的测试目录为src/Mod/Fem/femtest/包含app/—— 应用层无 GUI测试gui/—— GUI 测试data/—— 测试用数据文件FCStd、inp 等test_information.md—— 测试运行说明文档failing_tests.md、test_commands.sh等辅助文件OpenSCAD 模块的测试目录为 src/Mod/OpenSCAD/OpenSCADTest/结构完全对应app/test_importCSG.py—— 核心测试模块gui/test_dummy.py—— GUI 占位测试data/—— 测试数据CSG.scad、CSG.csg、Cube.stl、Square.dxf、Surface.dat、Surface2.dat、Surface.pngtest_information.md—— 本说明文档同时两个模块都采用顶层聚合文件 测试子包的组织方式FEM 用TestFemApp.py/TestFemGui.py聚合测试OpenSCAD 用 TestOpenSCADApp.py / TestOpenSCADGui.py 完成同样的职责。# src/Mod/OpenSCAD/TestOpenSCADApp.py # Unit test for the OpenSCAD module from OpenSCADTest.app.test_importCSG import TestImportCSG as OpenSCADTestImportCSGFEM 侧的TestFemApp.py采用完全相同的导入测试类并重命名模式。这就是基于 FEM 测试框架最直接的代码层证据。二、测试目录结构与 CMake 组织测试文件在构建系统中的归属由 src/Mod/OpenSCAD/CMakeLists.txt 定义它把测试分成三组SET(OpenSCADTests_SRCS OpenSCADTest/__init__.py OpenSCADTest/test_information.md ) SET(OpenSCADTestsApp_SRCS OpenSCADTest/app/__init__.py OpenSCADTest/app/test_importCSG.py ) SET(OpenSCADTestsGui_SRCS OpenSCADTest/gui/__init__.py OpenSCADTest/gui/test_dummy.py ) SET(OpenSCADTestsFiles_SRCS OpenSCADTest/data/__init__.py OpenSCADTest/data/CSG.scad OpenSCADTest/data/CSG.csg OpenSCADTest/data/Cube.stl OpenSCADTest/data/Square.dxf OpenSCADTest/data/Surface.dat OpenSCADTest/data/Surface2.dat OpenSCADTest/data/Surface.png )要点解读分组原则与 FEM 一致app对应无 GUI 的应用层测试gui仅在BUILD_GUI开启时纳入构建见 CMake 中IF (BUILD_GUI)分支测试数据随测试打包data/下的 SCAD、CSG、STL、DXF、DAT 文件通过fc_copy_sources复制到构建目录Mod/OpenSCAD/OpenSCADTest/data并在INSTALL阶段安装到Mod/OpenSCAD/OpenSCADTest/data。测试运行时通过FreeCAD.getHomePath()定位这些文件见下文测试代码test_information.md本身是交付物说明文档随测试一起安装供开发者在安装后的 FreeCAD 中查阅。gui/test_dummy.py是一个最小占位测试仅断言True作用是验证 GUI 测试基础设施可正常加载——这与 FEM 测试体系先搭骨架、再填充用例的演进路径一致。三、核心测试模块test_importCSG.py 逐项解析应用层核心测试位于 src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py由 Chris Hennes 于 2021 年编写全部继承自unittest.TestCase。测试对象是 OpenSCAD 模块的 CSG/SCAD 导入器 importCSG.py。3.1 测试基座与数据定位class TestImportCSG(unittest.TestCase): MODULE test_importCSG # file name without extension temp_dir tempfile.TemporaryDirectory() def setUp(self): self.test_dir join(FreeCAD.getHomePath(), Mod, OpenSCAD, OpenSCADTest, data)MODULE属性是 FreeCAD 测试框架识别测试类的约定字段setUp通过FreeCAD.getHomePath()定位测试数据目录与 CMake 安装路径Mod/OpenSCAD/OpenSCADTest/data对应临时生成的 SCAD 文件写入tempfile.TemporaryDirectory()保证测试可并行、可重复。3.2 文件导入测试固定数据文件test_open_scad与test_open_csg分别打开 CSG.scad 和 CSG.csg断言导入后的文档中存在名为union、intersection、difference的三种布尔结果对象。这两个数据文件内容一一对应// CSG.scad —— 源脚本 translate([-24,0,0]) { union() { cube(15, centertrue); sphere(10); } } intersection() { cube(15, centertrue); sphere(10); } translate([24,0,0]) { difference() { cube(15, centertrue); sphere(10); } }// CSG.csg —— OpenSCAD 导出的中间表示部分 multmatrix([[1, 0, 0, -24], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { union() { cube(size [15, 15, 15], center true); sphere($fn 0, $fa 12, $fs 2, r 10); } }测试同时覆盖两条导入路径.scad文件会先调用外部 OpenSCAD 可执行文件将其编译为临时 CSG 再解析而.csg文件直接解析。这对应 importCSG.py 中open()的分支逻辑def open(filename): docname os.path.splitext(os.path.basename(filename))[0] doc FreeCAD.newDocument(docname) if filename.lower().endswith(.scad): tmpfile callopenscad(filename) # 调用外部 openscad 编译 processcsg(tmpfile) os.unlink(tmpfile) else: processcsg(filename) # 直接解析 CSG return doc3.3 基础几何体导入测试通过utility_create_scad辅助方法将内联 SCAD 代码写入临时文件再导入逐项断言几何参数测试方法SCAD 代码断言要点test_import_spheresphere(10.0);Radius 10.0test_import_cylindercylinder(50.0,d10.0);直径转半径Radius 5.0Height 50.0test_import_cubecube([1.0,2.0,3.0]);Length/Width/Height三向尺寸test_import_circlecircle(10.0);2D 圆Radius 10.0test_import_squaresquare([1.0,2.0]);2D 矩形尺寸test_import_texttext(X);等文本导入依赖 DXF 导入器异常时静默跳过注意cylinder的d直径参数被转换为r半径语义这是 CSG 解析器参数归一化的一个典型细节。3.4 2D/3D 高级构造导入测试test_import_polygon_nopath/test_import_polygon_path多边形导入paths参数存在时生成 wire并断言面积5000.0test_import_polyhedron多面体导入断言体积1333.3333精度 4 位小数test_import_rotate_extrude旋转体导入覆盖angle正负角度、$fn低分段数回归 FreeCAD issue #4353断言体积9.0test_import_linear_extrude线性拉伸覆盖twist扭曲、scale缩放参数并用棱台体积公式(h/3)*(a1a2sqrt(a1*a2))计算期望值验证。3.5 布尔运算与边界条件测试test_import_difference/test_import_intersection/test_import_union对cube(15, centertrue)与sphere(10)的三种布尔组合分别断言体积266.1323、3108.8677、4454.9224——这些期望值是经过验证的几何事实test_empty_union导入一个包含大量嵌套空union()的复杂 SCAD 树模拟真实导出文件断言根对象数量为 1验证解析器对空操作符的容错对应 importCSG.py 中的p_empty_union_actiontest_complex_fuse_no_placement回归 FreeCAD issue #7878验证带multmatrix变换的复杂 CSG 融合后根对象 Placement 为恒等变换FreeCAD.Placement()。3.6 外部文件与特殊操作测试test_import_import_stl导入 STL 文件Cube.stl但读取transfermechanism偏好设置管道模式值为 2下跳过——因为沙箱环境下 OpenSCAD 无法通过管道访问外部文件test_import_surface导入高度场数据Surface.dat、Surface2.dat断言体积275.0/24.55及center参数导致的包围盒偏移测试中临时切换工作目录以规避绝对/相对路径问题test_import_resizeresize操作覆盖零尺寸分量、autotrue、非均匀缩放以及球体非盒体场景下先tessellate再校验包围盒的用例test_import_projectionprojection(cuttrue)投影切片断言投影面积含打孔场景0.75² - 0.25²cutfalse场景在源码中以注释形式保留为未实现功能标记test_import_hull/test_import_minkowski/test_import_offset目前为空实现pass作为未来用例的占位符而 importCSG.py 中已存在p_hull_action、p_minkowski_action、p_offset_action等解析函数test_import_rotate_extrude_file空测试注释注明 OpenSCAD 当时2021 年 3 月尚无此功能。四、测试与 importCSG 实现的呼应关系测试并非孤立存在它与导入器实现形成用例 ↔ 解析规则的对应关系。processcsg()用 PLYPython Lex-Yacc构建词法/语法分析器def processcsg(filename): lex.lex(moduletokrules) # 词法规则来自 tokrules.py parser yacc.yacc(debugFalse, write_tablesFalse) ...test_importCSG.py中的每个用例几乎都能在 importCSG.py 中找到对应的解析函数union/intersection/difference→p_boolean、p_union_action、p_empty_union_actionpolygon/polyhedron→p_points_list_2d、p_points_list_3d、p_path_pointsresize→p_resize_action内部用resize辅助函数处理零值与autooffset/hull/minkowski→p_offset_action、p_hull_action、p_minkowski_actioncolor→p_color_action配合setColorRecursively设置颜色此外STL/Surface 测试中读取的transfermechanism偏好设置其语义在 OpenSCADUtils.py 的callopenscad()中有明确定义transferMechanism preferences.GetInt(transfermechanism,0) if transferMechanism 0: # 使用 Python 临时目录 transferDirectory tempfile.gettempdir() elif transferMechanism 1: # 用户指定传输目录 transferDirectory preferences.GetString(transferdirectory) elif transferMechanism 2: # 使用管道通信 return call_openscad_with_pipes(...)其中管道模式要求 OpenSCAD 2021.01 以上版本且因沙箱限制无法读取外部文件——这正是测试中 STL/Surface 用例在transfermechanism 2时跳过、而纯代码生成的 SCAD 用例不受影响的原因。五、如何运行 OpenSCAD 单元测试由于框架基于 FEM 测试体系运行方式完全沿用 FEM 测试说明 中给出的模式并遵循 FreeCAD 统一的测试基础设施src/Mod/Test。以下命令均在 FreeCAD 构建目录下执行。5.1 从 FreeCAD 内部运行在 FreeCAD 的 Python 控制台或 Python 脚本中# 运行整个 OpenSCAD App 测试模块 import Test, TestOpenSCADApp Test.runTestsFromModule(TestOpenSCADApp) # 运行指定测试类 import Test, OpenSCADTest.app.test_importCSG Test.runTestsFromClass(OpenSCADTest.app.test_importCSG.TestImportCSG) # 运行单个测试方法标准 unittest 方式 import unittest thetest OpenSCADTest.app.test_importCSG.TestImportCSG.test_import_union alltest unittest.TestLoader().loadTestsFromName(thetest) unittest.TextTestRunner().run(alltest)5.2 从命令行shell运行# 运行 OpenSCAD App 测试对应 TestFemApp 的用法 ./bin/FreeCADCmd --run-test TestOpenSCADApp # 带 GUI 环境运行时 ./bin/FreeCAD --run-test TestOpenSCADApp # 指定模块/类/方法 ./bin/FreeCAD --run-test OpenSCADTest.app.test_importCSG ./bin/FreeCAD --run-test OpenSCADTest.app.test_importCSG.TestImportCSG ./bin/FreeCAD --run-test OpenSCADTest.app.test_importCSG.TestImportCSG.test_import_union也可以先运行 FreeCAD 内置的测试工具集--run-test 0运行全部测试再根据输出定位 OpenSCAD 相关用例。5.3 让测试文档保持打开以便调试参照 FEM 文档的调试技巧在 FreeCAD 内部运行某个测试方法后若希望保留导入的文档以便检查可以在测试的清理阶段临时注释掉FreeCAD.closeDocument(...)调用并改为pass。test_importCSG.py中每个用例末尾都有FreeCAD.closeDocument(doc.Name)或FreeCAD.closeDocument(CSG)修改后重新运行即可在文档树中观察导入结果。六、扩展新测试的实践建议结合现有框架为 OpenSCAD 导入器新增用例的推荐路径是纯代码用例在 test_importCSG.py 中新增测试方法用utility_create_scad(...scad 代码..., 描述名)内联生成输入断言导入对象的几何属性Shape.Volume、Shape.Area、BoundBox、Placement等数据文件用例若需要固定数据在 src/Mod/OpenSCAD/OpenSCADTest/data/ 放置文件并在 CMakeLists.txt 的OpenSCADTestsFiles_SRCS中登记确保构建与安装时被正确复制数据文件通常由真实 OpenSCAD 导出或精心的最小复现构造如 CSG.scad 配套 CSG.csg回归用例参考test_complex_fuse_no_placementissue #7878与test_import_rotate_extrudeissue #4353的写法在用例注释中标注对应的 issue 编号便于追溯几何期望值的获取可以先运行importCSG.open()导入目标模型在 FreeCAD 中查询Shape.Volume/Shape.Area得到参考值再固化为断言测试中大量使用assertAlmostEqual配合精度参数容忍浮点误差。七、总结FreeCAD OpenSCAD 工作台的单元测试框架虽然只在一行文档中声明基于 FEM 模块的测试但这一设计贯穿了整个测试体系目录结构、聚合导入方式、CMake 组织、运行机制均与 FEM 测试一脉相承。围绕 test_importCSG.py 展开的 30 余个用例覆盖了 CSG/SCAD 导入、基础几何体、2D/3D 构造、布尔运算、旋转/线性拉伸、resize、surface 高度场、projection 投影以及多个历史 issue 的回归场景与 importCSG.py 的解析规则形成一一对应的验证闭环。掌握这套框架后无论是排查导入问题、验证新几何类型支持还是为 OpenSCAD 互操作功能贡献测试都有清晰的入手路径。【免费下载链接】FreeCADOfficial source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.项目地址: https://gitcode.com/GitHub_Trending/fr/FreeCAD创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表