Can I use Cobertura on Unit Tests with PowerMock?
Problem
I am setting-up unit-test code coverage for an Android library which uses Robolectric to run the tests and PowerMock/Mockito for mock-testing.
However, running unit-tests with Cobertura results in the following Exception...
: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
...and the generated Cobertura report shows no coverage at all.
Running the same testcase without PowerMock*, the tests run fine and the coverage report is generated successfully:
* i.e. commenting the tests using PowerMock, removing the PowerMockIgnore
annotation, the PowerMockRule
and the MockitoAnnotations.initMocks(this);
invocation.
Investigation
- I see that some users fixed a similar issue by setting
forkmode="once"
in their testsuite.
However, this is not the solution as I am using Gradle which defaults on Java projects toForkMode.ONCE
. - Other users reporting a similar issue fixed it by updating PowerMock to 1.5.4.
I tried downgrading to this version, but the issue remains. - Finally, a similar issue was fixed by explicitly specifying a dependency to
cobertura-runtime
, but adding it didn't change anything either.
Question
Is it possible to use Cobertura in conjunction with PowerMock?
- In that case, what am I missing?
- Otherwise, how should I measure code coverage with such a setup (Android Library + Robolectric + PowerMock)?
Solution 1:
Right now, Android Studio integrates jacoco automatically to do code coverage.
You just need to add a few lines of code:
apply plugin: 'jacoco-android'
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
More information here:
- http://blog.wittchen.biz.pl/test-coverage-report-for-android-application/