无人机智能硬件【免费下载链接】qgroundcontrolCross-platform ground control station for drones (Android, iOS, Mac OS, Linux, Windows)项目地址https://gitcode.com/gh_mirrors/qg/qgroundcontrol点击查看免费下载导读Qt Quick Testqmltestrunner/ CTest 驱动的 QML 测试运行结束后如何把机器可读的 JUnit XML 转化为一份可供人直接阅读、可复现、可追踪回归根因的结构化 Markdown 报告本文以qt-qml-test-run技能配套的报告格式规范文档为主体完整讲解这份报告八个章节的定义、省略条件与内容规则并结合仓库中真实的 Qt Quick Test 基础设施QGCQmlQuickTests可执行程序、QmlTestFileValidator校验器与tst_Example.qml示例深入解析其背后的实现原理。读完本文你将掌握一套可移植的 QML 测试结果汇报规范报告如何定位、何时省略某章节、失败如何映射到源码变更、以及如何用一行命令让报告可复现。一、报告在测试流水线中的位置qt-qml-test-run技能SKILL.md共分十个步骤定位 Qt 工具链 → 发现测试目标 → 判断 CMake 测试接线 → 补线可选→ 构建 → 运行 →解析 JUnit XMLStep 8→写 Markdown 报告Step 9→ 控制台摘要Step 10。本文所述的报告格式规范即 Step 9 的执行标准是 qt-quick-test-report-format.md 的内容主体。每次运行会产生一对时间戳一致的文件且都落在构建目录内而非源码树中产物路径说明Markdown 报告build/tests/reports/test-report-YYYY-MM-DD-HHMMSS.md本文规范的对象JUnit XMLbuild/tests/reports/junit/qmltests-timestamp.xml报告的数据源同时充当下一轮 Section 4 的基线将报告放在build/下的原因是构建产物按惯例已被版本控制排除报告跟随构建产物存放就不会污染源码树也不会被误提交。二、报告的定位原则Framing报告格式规范首先明确了一条元规则报告是对本次运行的独立诊断standalone diagnostic不是与历史运行的质量对比。即使目录里存在更早的报告也不得写成比上次更好相比上次回归了 N 个测试之类的比较性表述。变更检测change detection是另一回事当出现失败时历史运行的时间戳是区分真实回归与环境偶发flakiness的有效信号因此报告专门设计了 Section 4 来承载这一信息。另一条规则面向读者定位报告是写给没有接触过 runner 技能的读者看的。正文中不得出现技能runner之类的元指称需要传达给读者的规则一律以事实陈述的方式写出。三、报告八个章节逐一详解1. Header报告头头部必须包含五项信息项目名取自根目录CMakeLists.txt的project()调用若无法解析则以目录名兜底Qt 版本从解析出的qt-path中提取例如/opt/Qt/6.11.0/gcc_64→6.11.0运行模式CMake / Standalone / Direct 三者之一调用时间戳invocation timestampJUnit XML 报告的路径。三种运行模式的含义来自技能的 Step 3/4/4b见 SKILL.mdStandalone项目完全没有 CMake直接调用qmltestrunner -input tests-dirCMake项目存在 CMake 测试接线运行的是构建出来的测试二进制Direct项目是 CMake 工程但尚未接线且用户选择了零文件修改的直接调用方式。2. Run setup运行环境用于复现这一节回答如何原样重跑本次运行需要记录以下内容没有则省略对应子项Invocation调用命令把完整命令行放在围栏代码块中包括前置的环境变量。规范给出了两类典型形式# CMake 路径直接运行测试二进制 QT_QPA_PLATFORMoffscreen ./build/tests/tst_qmltests -o report.xml,junitxml # Direct / Standalone 路径直接运行 qmltestrunner qt-path/bin/qmltestrunner -input tests-dir -o report.xml,junitxmlTest root测试根目录传给-input的目录或通过QUICK_TEST_SOURCE_DIR配置的目录。在 QGroundControl 仓库中这一宏的实际使用可见 test/UnitTestFramework/QmlTesting/CMakeLists.txt其中QUICK_TEST_SOURCE_DIR${CMAKE_CURRENT_SOURCE_DIR}/tests指向tests/子目录配置期即烘焙进二进制QUICK_TEST_SOURCE_DIR指向的目录在配置期固化进二进制之后移动测试文件需要重新 configure。Skipped subdirectories被跳过的子目录无则省略任何通过-input leaf-dir收窄作用域而排除的tests/skipped/、tests/disabled/等目录并附一行原因例如contains a hanging file——其中包含一个会挂起整个运行的测试文件。Extra-importpaths额外导入路径无则省略测试的 import 解析所需的所有-import path标志。3. Summary table汇总表汇总表给出五列总数 / 通过 / 失败 / 跳过 / 耗时秒。表首必须有一行结论verdict规范定义了三种情形0 失败、0 跳过 →All N tests passed.F 个失败 →F of N tests failed.仅 S 个跳过 →All non-skipped tests passed (S skipped).4. Source changes since prior run自上次运行以来的源码变更省略条件无失败或不存在历史 JUnit XML 报告时本节整体省略。生成方式分两步定位基线在build/tests/reports/junit/下找出最新的历史qmltests-*.xml排除本次运行的文件以其 mtime 作为基线枚举变更列出项目根下 mtime 新于基线、且扩展名属于*.qml、*.cpp、*.h、*.hpp、CMakeLists.txt的源码文件排除build*/其本身覆盖报告目录和.git/。把匹配结果渲染为相对路径的无序列表前导一行如Source files modified since the prior run at HH:MM:SS:。若检测到 Git 仓库存在.git还应补充git diff --stat能解析基线提交时先git log -1 --beforebaseline-mtime --format%H得到基线提交再对基线提交执行 diff无法解析时退化为git status --short。本节的关键作用在于失败归因只要本节列出了条目Section 5 的失败分析就必须先以likely regression in the listed files所列出文件中的疑似回归为前提框架通读 diff 寻找能解释每条失败断言的变更只有当没有任何源码变更能解释失败时才允许退回到环境 / 偶发假设。这一先源码、后环境的归因顺序是报告最有诊断价值的设计。5. Failed tests失败测试省略条件无失败时整节省略。每个失败用例需记录四项完整名称classname::namefailure_message原样verbatim放入围栏代码块不得改写sourcefile:line[:col]若存在格式化为 Markdown 链接行号必须可见一行建议的下一步规范给出两个模板Inspect the test function in sourceRe-run with QT_LOGGING_RULES*true to capture more context若 Section 4 列了变更文件优先写Inspect file at the lines changed since the prior run——把失败直接锚定到变更行。6. Slowest tests最慢的 10 个测试按time_ms降序取前 10并在列头标注一条重要提醒time_msincludes test setup and teardown, not just the assertion.time_ms包含测试的 setup 与 teardown不只是断言本身。任何超过1000 ms的用例须打上⏱若需规避 emoji 则用[slow]并附一行提示candidate for tryCompare audit — see the qt-qml-test skills pitfalls reference.候选对象建议做tryCompare审查——参见qt-qml-test技能的 pitfalls 参考。该参考即 tools/skills/qt-qml-test/references/qt-quick-test-pitfalls.md与之配套的 qt-quick-test-controls.md 也说明tryCompare以轮询方式工作默认 5 秒超时并运行事件循环动画/异步场景应优先用它而非裸wait。7. Skipped tests跳过的测试省略条件无跳过时整节省略。列出用例名以及 runner 若输出了跳过原因则一并列出。8. AI-assistance footerAI 协助声明脚注无论结果如何报告末尾必须原样包含这一行AI assistance has been used to create this output.规范强调always be present, regardless of result——这是不可省略的固定内容。四、Parser outputJUnit XML 到 JSON 的桥梁技能 Step 8 调用 parse-qmltestrunner-output.py 解析 JUnit XML并消费其打印到 stdout 的 JSON 摘要。该脚本自身的 docstring 是输出 schema 的权威定义{ total: 5, passed: 4, failed: 1, skipped: 0, duration_ms: 1250.5, cases: [ { name: test_initialState, classname: ExampleQmlTest, time_ms: 120.0, status: passed, failure_message: null, source: tst_Example.qml:21:5 } ], slowest: [] }几个值得注意的实现细节从脚本源码确认平台差异Windows 上解释器可能是python而非python3第一次尝试失败后用python重试非零退出时的错误契约解析器出错时向 stdout 输出{error: ...}调用方需把消息映射到原因见下表testcase遍历_walk_testcases()用root.iter(testcase)递归查找因此无论 JUnit 文档是testsuites/testsuite嵌套还是扁平结构都能正确工作时间换算JUnit 的time属性单位是秒float脚本乘 1000 得到毫秒并四舍五入保留 3 位source 提取用锚定的三段正则从失败消息中提取file.qml:line[:col]兼容 Windows 盘符路径C:\Program Files\foo.qml、绝对 Unix 路径含空格和无空格的相对路径三种形态并会把file:///foo.qml折叠为/foo.qml空文档保护找不到任何testcase时视为软错误soft error以便调用方把解析成功但零测试与真正的失败区分开。错误消息到原因的映射表错误消息原因处理Report file not found路径错误复查 Step 7 的 XML 路径Failed to parse XMLrunner 写了一半崩溃加 JUnit 格式标志重跑No testcase elements found测试目录为空或未被发现检查QUICK_TEST_SOURCE_DIR或-input每个用例都报Type X unavailable、qrc:/...的No such file or directory或SiblingType is not a typeURI import 命中了 module-on-executable 场景按 qt-quick-test-cmake.md 的 Module-on-executable refactor 重构相对 import 变体则核对路径与磁盘上的qmldir硬性前置条件解析结果为空时不得进入 Markdown 报告写作Do not proceed to the Markdown report with an empty parser result。五、仓库中的真实落地QGroundControl 的 QML 测试基建上述规范并非纸上谈兵QGroundControl 仓库内部就有一套与之同构的 Qt Quick Test 基建可作为理解报告数据从何而来的参照。5.1 专属测试可执行程序 QGCQmlQuickTeststest/UnitTestFramework/QmlTesting/CMakeLists.txt 展示了完整的 CMake 接线# 依赖 Qt6::QuickTest缺失则警告并禁用 QML 测试 if(TARGET Qt6::QuickTest) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt6::QuickTest) else() message(WARNING Qt6::QuickTest not found - QML testing disabled) return() endif() # 专用 out-of-process 测试可执行程序 add_executable(QGCQmlQuickTests ${CMAKE_CURRENT_SOURCE_DIR}/QmlQuickTestMain.cc ) target_link_libraries(QGCQmlQuickTests PRIVATE Qt6::QuickTest Qt6::Qml Qt6::Gui Qt6::Quick) # 测试源目录在配置期烘焙进二进制 target_compile_definitions(QGCQmlQuickTests PRIVATE QUICK_TEST_SOURCE_DIR${CMAKE_CURRENT_SOURCE_DIR}/tests ) add_test(NAME QmlQuickTests COMMAND $TARGET_FILE:QGCQmlQuickTests -platform offscreen WORKING_DIRECTORY ${CMAKE_BINARY_DIR} )其入口 QmlQuickTestMain.cc 只有三行走的是标准QUICK_TEST_MAIN(QGCQmlQuickTests)宏——这与报告格式规范 Step 7 中直接运行测试二进制而非ctest --output-junit的建议一脉相承二进制直接输出 JUnit 时一个testcase对应一个 QMLfunction test_*()粒度是单个测试函数而ctest --output-junit会把整个二进制聚合为单一testcase nametst_qmltests导致100 个测试函数显示为 1 个测试通过/失败的失真详见 qt-quick-test-cmake.md 的 Binary-direct JUnit invocation 一节。该 CTest 条目还设置了与规范 Section 3 相关的运行环境QT_QPA_PLATFORMoffscreen、QT_QUICK_BACKENDsoftware、QT_LOGGING_RULES*.debugfalse并用FAIL_REGULAR_EXPRESSION FAIL!;QFATAL;Segmentation fault;ASSERT把崩溃直接判为失败——这正是报告 Section 5 中失败消息的来源。5.2 测试文件形态tst_Example.qml仓库的示例测试 tst_Example.qml 展示了标准TestCase结构name属性、test_*函数、SignalSpy、cleanup()。其name: ExampleQmlTest会出现在 JUnit XML 的classname字段中从而在报告 Section 5 里以ExampleQmlTest::test_initialState这样的classname::name形式呈现——与报告格式规范的定义完全对应。5.3 结构校验器QmlTestFileValidatorQmlTestFileValidator.cc 是一个结构/健全性检查器它遍历测试目录、确认tst_*.qml文件存在且包含TestCase与function test_。由于quick_test_main()内部会调用exit()它无法在常规单元测试 harness 内联运行真正的 QML 执行必须走独立的 out-of-process 可执行程序QGCQmlQuickTests。这解释了报告格式规范为何将运行模式列为 Header 的必备字段——同一套 QML 测试执行路径不同产物与定位也截然不同。在 test/README.md 的 QML Test Split 一节中两条命令被明确区分# 真正的 QML 测试执行 ctest -R QmlQuickTests --output-on-failure # 进程内结构校验sanity check ctest -R QmlTestFileValidator --output-on-failure六、Console summary控制台摘要规范写完 Markdown 报告或按--no-report跳过后向用户展示的控制台摘要必须保持精简。规范规定输出以下内容结论行通过 / 失败 / 跳过计数与运行耗时前 3 个失败每个一行摘要完整细节在报告中回归前缀当存在失败且报告 Section 4 列出了变更文件时失败块前加一行Source files modified since prior run: file1, file2 — failures are likely regressions; inspect the diff first.报告路径Markdown 报告路径若传了--no-report则输出Markdown report skipped (--no-report); JUnit XML retained at junit-path.两条红线贯穿始终只报结果outcomes only——结论、失败、路径不得输出产生它们的工作流细节如per Step 4bapplying wire-up之类Framing 规则同样适用于控制台摘要不做与历史运行的整体质量对比即使被问到is it better now?也不得回应更好之类的比较性结论。七、报告相关的可选开关与积累策略报告写作是技能 Step 9 的默认行为但有两个开关允许按场景裁剪开关效果适用场景--no-report跳过 Markdown 报告写作但JUnit XML 仍然落盘紧凑的 test-fix-test 迭代循环控制台摘要已足够避免build/tests/reports/下堆积 Markdown 文件同时 XML 保留可为下一轮 Section 4 提供基线--no-build跳过构建步骤假设build/tests/tst_qmltests已是最新仅迭代报告格式时复用既有构建由于每次正常运行的报告与 XML 都带时间戳且技能不主动轮换清理长期项目下build/tests/reports/会持续增长——这是有意设计JUnit XML 是后续运行 Section 4 基线的输入若本地不想要报告积累就在迭代运行中加--no-report让 XML 继续小体积积累即可。总结qt-qml-test-run技能的报告格式规范给出了一个可直接照搬的 QML 测试汇报体系八个章节各有明确的必备字段与省略条件从可复现的运行环境Section 2、可追踪的源码变更基线Section 4、到可执行的失败处置建议Section 5层层递进地服务于快速定位真实回归这一核心目标。结合本仓库 QmlTesting 的真实接线QUICK_TEST_SOURCE_DIR烘焙、out-of-process 执行、JUnit 粒度选择与示例测试 tst_Example.qml你可以将此规范整体移植到自己的 Qt 6 / CMake QML 项目只需保证 runner 输出带时间戳的 JUnit XML、用规范中给出的解析脚本生成 JSON 摘要即可稳定产出结构一致、可读可引用的 Markdown 测试报告。赞分享无人机智能硬件【免费下载链接】qgroundcontrolCross-platform ground control station for drones (Android, iOS, Mac OS, Linux, Windows)项目地址https://gitcode.com/gh_mirrors/qg/qgroundcontrol点击查看免费下载相关推荐Vue.Draggable组件持续集成测试报告格式JUnit XMLVue.Draggable组件持续集成测试报告格式JUnit XML 在前端开发中持续集成CI已经成为保证代码质量的关键环节。对于Vue.Draggab前端UI组件如何扩展javascript-typescript-langserver添加自定义语言功能完整指南如何扩展javascript typescript langserver添加自定义语言功能完整指南 JavaScript和TypeScript语言服务器ja推荐XML报告配置组合推荐XML报告配置组合 基础配置 gtest_outputxml:reports/test_%g.xml 计时信息 gtest_print_time测试质量保障开发工具上一篇PolyFit性能优化大规模点云处理的10个实用技巧下一篇OpCore-Simplify5分钟搞定黑苹果EFI配置的智能神器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考