当前位置: 首页 > 知识库问答 >
问题:

如何使用PowerMock和Jacoco离线仪表从Maven Multiproject获得SonarQube的覆盖范围

昌博易
2023-03-14

我正在进行Maven多项目构建。我正在使用Powermock模拟用于编写单元测试用例的类。因此,为了获得jacoco的覆盖范围,我正在使用jacoco离线仪器,并设置声纳。dynamicAnalysis=重用报告以获得声纳覆盖范围。当我尝试这样做时,我会收到来自Jacoco和Sonar的错误:

[INFO] Analysing C:\Program Files (x86)\Jenkins\workspace\Test\target\jacoco.exec
[WARNING] Exception during analysis of file C:\Program Files (x86)\Jenkins\workspace\Test\target\classes\cache\TestClass.class
java.io.IOException: Error while analyzing 
C:\Program Files (x86)\Jenkins\workspace\Test\target\classes\cache\TestClass.class
    at org.jacoco.core.analysis.Analyzer.analyzerError(Analyzer.java:155)
    at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:130)
    at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:147)
    at org.sonar.plugins.jacoco.JacocoReportReader.analyzeClassFile(JacocoReportReader.java:139)
    at org.sonar.plugins.jacoco.JacocoReportReader.analyzeFiles(JacocoReportReader.java:114)
    at org.sonar.plugins.jacoco.AbstractAnalyzer.readExecutionData(AbstractAnalyzer.java:133)
    at org.sonar.plugins.jacoco.AbstractAnalyzer.analyse(AbstractAnalyzer.java:102)
    at org.sonar.plugins.jacoco.JaCoCoSensor.execute(JaCoCoSensor.java:87)
    at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:53)
    at org.sonar.scanner.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:88)
    at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:82)
    at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:68)
    at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:88)
    at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:180)
    at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:144)
    at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:129)
    at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:286)
    at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:281)
    at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:279)
    at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:259)
    at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:144)
    at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:129)
    at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
    at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:84)
    at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:144)
    at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:129)
    at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:121)
    at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:118)
    at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:72)
    at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
    at com.sun.proxy.$Proxy19.execute(Unknown Source)
    at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:171)
    at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:128)
    at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:63)
    at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:108)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: java.lang.IllegalStateException:cache\TestClass is already instrumented.
    at org.jacoco.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:176)

我不知道为什么雅各科试图再次仪器类获得声纳覆盖。我被这个问题困扰了一段时间。任何帮助都会很棒。

共有2个答案

左丘兴生
2023-03-14

我不确定在您的案例中发生了什么,但我已经使用PowerMock模块javaagent成功地使用Jacoco生成了PowerMock覆盖率。

只需确保将powermock代理放在jacoco代理之后:

<artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <useSystemClassLoader>true</useSystemClassLoader>
                <argLine>${jacocoArgLine} -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/${powermock.version}/powermock-module-javaagent-${powermock.version}.jar -noverify</argLine>
...

如果要查看示例,请查看此项目:https://github.com/jfcorugedo/sonar-scanner

在这里,您可以看到sonar考虑了PowerMock模拟的静态方法和new语句:

如果要模拟new语句,请确保使用PowerMockRule而不是PowerMockRunner

看看这个测试

苏野
2023-03-14

根据http://www.jacoco.org/jacoco/trunk/doc/instrument-mojo.html :

执行脱机检测。请注意,在执行测试之后,您必须借助“恢复插入指令的类”目标来恢复原始类。

异常消息已插入指令具有误导性,但正是在尝试分析插入指令的类而不是原始类时生成了此消息。

 类似资料:
  • 我有一个问题,在声纳Qube v6.7中,线路覆盖范围低于哈科报告。 当我打开声纳时,我的类文件有很多未覆盖的行。打开 jacoco 报告时,它显示这些行已覆盖。 我正在使用gradle插件。(v2.6) 有什么想法可以是问题吗?

  • 当我的单元测试通过Emma被“覆盖”时,我试图让Sonar IT代码覆盖为我工作。 我的情况: (1)我有大量使用JMockit的单元测试。删除JMockit不是一个选项。我想获得这些测试的单元测试覆盖报告。 (2)我进行了集成测试,简单地用不同的输入场景运行应用程序的核心服务器端部分(这是一个Spring web应用程序)。我想要它的代码覆盖报告。 对于第(1)部分,我选择使用Emma进行单元测

  • 我一直在尝试在JBoss服务器中实现JaCoCo离线代码覆盖,使用仪表化的EAR进行部署和jacococagent.jar,以便跟踪针对所述JBoss运行的外部集成测试的代码覆盖。 我一直在关注这样的指南: http://www.eclemma.org/jacoco/trunk/doc/offline.html http://automationrhapsody.com/code-coverage

  • 我将sonarqube jacoco用于codecoverage,我有一个junit测试用例用于我的java代码,它采用的是下面的目录结构。 我希望在sonarqube仪表板上有一个代码覆盖率,我也在使用gradle。 我正在运行gradle sonarqube 我不知道我哪里做错了?如果有任何一个可以帮助从java代码中获得测试用例的覆盖面。

  • 我们有一个多模块的maven项目。 每个模块都有一对testng和powermock单元测试用例。我们正在使用jacoco进行代码覆盖率报告。但是,jacoco在分析单元测试复盖率时基于testng单元测试用例,而忽略了powermock单元测试用例。因此,总的代码覆盖率越来越低。 如何配置jacoco来同时获取testng和jacoco测试用例?