我可以在 PowerMock 的单元测试中使用 Cobertura 吗?
Posted
技术标签:
【中文标题】我可以在 PowerMock 的单元测试中使用 Cobertura 吗?【英文标题】:Can I use Cobertura on Unit Tests with PowerMock? 【发布时间】:2016-07-17 01:21:34 【问题描述】:问题
我正在为一个 android 库设置单元测试代码覆盖率,该库使用 Robolectric 运行测试并使用 PowerMock/Mockito 进行模拟测试。
但是,使用 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* 的情况下运行相同的测试用例,测试运行良好,覆盖率报告生成成功:
* 即使用 PowerMock 注释测试,删除 PowerMockIgnore
注释、PowerMockRule
和 MockitoAnnotations.initMocks(this);
调用。
调查
我看到一些用户 fixed a similar issue 通过在他们的测试套件中设置forkmode="once"
。
但是,这不是解决方案,因为我使用 Gradle which defaults on Java projects 到 ForkMode.ONCE
。
其他用户报告了类似问题fixed it by updating PowerMock to 1.5.4。
我尝试降级到此版本,但问题仍然存在。
最后,explicitly specifying a dependency to cobertura-runtime
修复了一个类似的问题,但添加它也没有改变任何东西。
问题
是否可以将 Cobertura 与 PowerMock 结合使用?
那么,我错过了什么? 否则,我应该如何使用这样的设置测量代码覆盖率(Android Library + Robolectric + PowerMock)?【问题讨论】:
我遇到了同样的问题。 Gradle 构建,Powermock 测试以 0% 的覆盖率显示。很想解决这个问题。 +1 对于您非常明确的问题。您能否分享一个重现该问题的基本项目(例如在 github 上)? 在您的测试用例中,您是否从 PowerMockTestCase 扩展类? @gontard:我可以这样做,但是从当前项目中提取相关部分需要一些时间。它会帮助您解决此问题吗?如果这是您希望看到的,我还可以创建构建脚本和测试用例的要点。 @MoralesBatovski:不是真的,因为我遵循 robolectric 的指示 (github.com/robolectric/robolectric/wiki/Using-PowerMock)。你会建议另一种方法吗? 【参考方案1】:目前,Android Studio 自动集成了 jacoco 来进行代码覆盖。
你只需要添加几行代码:
apply plugin: 'jacoco-android'
android
buildTypes
debug
testCoverageEnabled = true
更多信息在这里:
http://blog.wittchen.biz.pl/test-coverage-report-for-android-application/【讨论】:
我尝试了您的解决方案,但添加 jacoco 并运行 createDebugCoverageReport 会生成 [空报告](i.stack.imgur.com/ACTcY.png)。除此之外,您确定 jacoco 适用于单元测试 (test
) 而不仅仅是仪器测试 (androidTest
)?您链接的文章是后者,而我正在尝试使用 Robolectric 实现前者。以上是关于我可以在 PowerMock 的单元测试中使用 Cobertura 吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Powermock 在 Sonarqube 中配置 jacoco 以进行集成和单元测试报告
配置同时使用PowerMock和Robolectric对Android进行单元测试