问题
我正在为一个使用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报告](https://istack.dev59.com/aej0B.webp)
运行相同的测试用例,不使用PowerMock*,测试可以正常运行并成功生成覆盖率报告:
![没有PowerMock的Cobertura报告](https://istack.dev59.com/mbPUS.webp)
PowerMockIgnore
注解、PowerMockRule
和MockitoAnnotations.initMocks(this);
调用。
调查
我看到一些用户通过在测试套件中设置forkmode="once"
来解决了类似的问题。然而,这不是解决方案,因为我正在使用Gradle默认为Java项目并且使用ForkMode.ONCE
。其他用户报告了类似的问题通过更新PowerMock到1.5.4版本解决了它。我尝试降级到此版本,但问题仍然存在。
最后,一个类似的问题是通过明确指定依赖项
cobertura-runtime
解决的,但添加它也没有改变任何东西。
问题
是否可以将 Cobertura 与 PowerMock 结合使用?
- 如果是这样,我错过了什么吗?
- 否则,如何在这种设置(Android 库 + Robolectric + PowerMock)中测量代码覆盖率?