【发布时间】:2021-05-06 09:12:10
【问题描述】:
我多年来一直使用 Sonar 没有任何问题,非常高兴……直到上周我遇到了一个非常奇怪的问题,我完全不知道发生了什么。
我正在使用 GitLab 的管道执行一些单独的单元测试和功能测试,然后合并 Sonar 的 2 个 lcov 和 2 个 xunit 报告,这给了我最后是 1 个 lcov 文件,其中列出了单元测试和功能测试所涵盖的代码,以及 1 个包含所有已执行测试的 xunit 文件。
然后我将这 2 个文件传递给我们的 SonarQube 8.6 - 开发者版和 sonar-scanner 4.5.0.2216。
这是我正在使用的声纳扫描仪参数:
sonar.projectKey=xxx
sonar.projectName=xxx
sonar.projectVersion=$CI_BUILD_ID
sonar.sources=src
sonar.tests=test
sonar.javascript.lcov.reportPaths=test-results/lcov-merged.info
sonar.testExecutionReportPaths=test-results/xunit-merged.xml
这是合并单元报告和功能报告后最终的 xunit-merged.xml 文件的内容。
<testExecutions version="1">
<file path="test\unit\index.test.ts">
<testCase name=": Save" duration="4"/>
<testCase name="Get functional logs: with empty query" duration="3"/>
<testCase name="Class: ManagementFormService: Function: get (GET handler)" duration="4"/>
<testCase name="Class: ManagementFormService: Function: update (POST handler)" duration="4"/>
<testCase name="Module: Export management form service, controller and externally injected config service" duration="29"/>
<testCase name="Class: ManagementFormService: Function: createForm" duration="1"/>
<testCase name="Class: ManagementFormService: Function: save (success) and createForm" duration="1"/>
<testCase name="Get functionals logs by origin: From valid queries and request" duration="2"/>
<testCase name="Get functionals logs by origin: From valid queries but no request" duration="4"/>
<testCase name="Get functionals logs by origin: From valid queries and request" duration="1"/>
<testCase name="Get functionals logs by origin: From valid queries but no request" duration="1"/>
<testCase name="Get functionals logs by origin: From valid queries and request" duration="0"/>
<testCase name="Get functionals logs by origin: From valid queries but no request" duration="1"/>
<testCase name="Module version: Cache ON, Repository ON, Amqp ON: From valid UUID and request" duration="1"/>
<testCase name="Module version: Cache ON, Repository ON, Amqp ON: From valid UUID but no request" duration="0"/>
<testCase name="Module version: Cache OFF, Repository ON, Amqp ON: From valid UUID and request" duration="0"/>
<testCase name="Module version: Cache OFF, Repository ON, Amqp ON: From valid UUID but no request" duration="0"/>
<testCase name="Module version: Cache OFF, Repository OFF, Amqp ON: From valid UUID and request" duration="1"/>
<testCase name="Module version: Cache OFF, Repository OFF, Amqp ON: From valid UUID but no request" duration="1"/>
<testCase name="Module version: Cache OFF, Repository OFF, Amqp OFF: From valid UUID and request" duration="0"/>
<testCase name="Module version: Cache OFF, Repository OFF, Amqp OFF: From valid UUID but no request" duration="1"/>
</file>
<file path="test\functional\index.test.ts">
<testCase name="Boot: Boot and log booting status" duration="163"/>
</file>
</testExecutions>
它包含 22 个测试,由一个测试文件 (test\unit\index.test.ts) 执行的 21 个单元测试和由另一个测试文件 (test\functional\index.test.ts) 执行的 1 个功能测试。
这里的问题是 Sonar 只计算 21 个单元测试并忽略最后一个(正如您在捕获中看到的那样)。
最后一个功能测试在 xml 中明确存在时被忽略。
以完全相同的方式减少代码覆盖率。单元测试覆盖的所有源代码都标记为已覆盖,但功能测试覆盖的源代码标记为未覆盖,而lconv-merged.info明确表明该文件已被正确测试。
正如您在此捕获中看到的,文件 src/technical/technical.controller.rest.ts 的第 45、46 和 49 行被标记为未覆盖。
虽然lconv-merged.info 报告清楚地表明这些行已被覆盖。
如果 Sonar 说没有测试也没有覆盖率,我会处理报告文件中格式错误的内容。但在这里,Sonar 似乎在挑选它想要显示的内容,我不知道为什么。
所有源代码都在同一个src 源路径中,可以通过声纳扫描器访问,并且可以在声纳中浏览(这表明它们已被正确分析)。
我一直在寻找一个漫长的一周,为什么在获取其余文件时会忽略这两个报告的一部分,但我仍然完全不知道。
有人可以帮我吗?
【问题讨论】:
-
为什么要合并文件? SQ 可能只需要一个
<file>标签,因此它只从第一个节点获取数据。那些reportPaths参数可以包含 glob 模式,所以最好有单独的文件来匹配 glob,我想这可能会有所帮助。 -
我尝试了多种变体:4 个单独的文件,一次直接执行所有测试,之后不必合并结果,只执行功能测试(在声纳中给出 0 个测试)等。 .我实际上是在尝试检查声纳是否没有查看测试的源代码来检测自己正在测试哪些类,这会自动拒绝所有功能和端到端测试。
标签: unit-testing sonarqube code-coverage functional-testing