我能在使用PowerMock的单元测试中使用Cobertura吗?

83

问题

我正在为一个使用Robolectric运行测试以及使用PowerMock/Mockito进行模拟测试的Android库设置单元测试代码覆盖率。

然而,使用Cobertura运行单元测试会导致以下异常...

:example:testDebugUnitTest
Exception in thread "Thread-5" java.lang.ExceptionInInitializerError
    at com.example.package.saas.Query$RemoveWordsType.__cobertura_init(Query.java)
    at com.example.package.saas.Query$RemoveWordsType.<clinit>(Query.java)
    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:498)
    at net.sourceforge.cobertura.coveragedata.TouchCollector.applyTouchesToSingleClassOnProjectData(TouchCollector.java:123)
    at net.sourceforge.cobertura.coveragedata.TouchCollector.applyTouchesOnProjectData(TouchCollector.java:110)
    at net.sourceforge.cobertura.coveragedata.ProjectData.saveGlobalProjectData(ProjectData.java:272)
    at net.sourceforge.cobertura.coveragedata.SaveTimer.run(SaveTimer.java:33)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Shutdown in progress
    at java.lang.ApplicationShutdownHooks.add(ApplicationShutdownHooks.java:66)
    at java.lang.Runtime.addShutdownHook(Runtime.java:211)
    at net.sourceforge.cobertura.coveragedata.ProjectData.initialize(ProjectData.java:239)
    at net.sourceforge.cobertura.coveragedata.ProjectData.getGlobalProjectData(ProjectData.java:209)
    at net.sourceforge.cobertura.coveragedata.TouchCollector.<clinit>(TouchCollector.java:45)
    ... 11 more

...并且生成的Cobertura报告完全没有覆盖率。 使用PowerMock的Cobertura报告
运行相同的测试用例,不使用PowerMock*,测试可以正常运行并成功生成覆盖率报告: 没有PowerMock的Cobertura报告 *即注释掉使用PowerMock的测试用例,移除PowerMockIgnore注解、PowerMockRuleMockitoAnnotations.initMocks(this);调用。

调查

我看到一些用户通过在测试套件中设置forkmode="once"解决了类似的问题。然而,这不是解决方案,因为我正在使用Gradle默认为Java项目并且使用ForkMode.ONCE
其他用户报告了类似的问题通过更新PowerMock到1.5.4版本解决了它。我尝试降级到此版本,但问题仍然存在。
最后,一个类似的问题是通过明确指定依赖项cobertura-runtime解决的,但添加它也没有改变任何东西。

问题

是否可以将 CoberturaPowerMock 结合使用?

  • 如果是这样,我错过了什么吗?
  • 否则,如何在这种设置(Android + Robolectric + PowerMock)中测量代码覆盖率?

3
我遇到了同样的问题。Gradle构建,Powermock测试的代码覆盖率显示为0%。希望能够解决这个问题。 - jjNford
3
谢谢你的清晰问题。您能分享一个基本的项目来复现问题吗(例如在Github上)? - gontard
1
你的测试用例中是否从PowerMockTestCase类继承? - Gustavo Morales
1
@gontard:我可以这么做,但需要一些时间从当前项目中提取相关部分。这会对你有帮助吗?如果您想要查看构建脚本和测试用例的gist,我也可以创建。 - PLNech
@MoralesBatovski:不是很清楚,因为我正在遵循Robolectric的指示(https://github.com/robolectric/robolectric/wiki/Using-PowerMock)。您会建议另一种方法吗? - PLNech
我同意@gontard的看法,一个 POC 将会是很棒的。由于这需要耗费时间,你能同时在问题中加入你的测试类吗?这也将有助于排除故障! - Marino
1个回答

1

1
我尝试了你的解决方案,但是添加jacoco并运行createDebugCoverageReport会生成一个空报告。除此之外,你确定jacoco适用于单元测试(test)而不仅仅是针对仪器测试(androidTest)吗?你提供的文章是针对后者,而我正在尝试使用Robolectric实现前者。 - PLNech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接