shink opened a new issue #5781:
URL: https://github.com/apache/dolphinscheduler/issues/5781
## Describe the bug
As we all know, dolphinscheduler uses `PowerMock` for unit testing, and uses
`Jacoco` to get code coverage which will be stored and managed by `Sonar`. But
in fact, some test conerages are always 0% in sonar. This seems to be caused by
Jacoco not getting the coverage of the class marked by `@PrepareForTest`.
## To Reproduce
When using the `@PrepareForTest` annotation only causes code coverage to
fail in some cases. If you want to write test for `Demo.java`, and you add the
`Demo.class` in `@PrepareForTest`, then the `Jacoco` will not count the
coverage in `Demo.java`.
```java
public class Demo {
public int method() {
// do something
return -1;
}
}
```
```java
@RunWith(PowerMockRunner.class)
@PrepareForTest({Demo.class})
public class DemoTest {
@Mock
private Demo demo;
@Test
public void testMethod() {
when(demo.method()).thenReturn(1);
Assert.assertEquals(1, demo.method());
}
}
```
If you add other class in `@PrepareForTest`, it will not affect the code
coverage in Demo.
## Cause analysis
> The simplest way to use JaCoCo it is — on-the-fly instrumentation with
using JaCoCo Java Agent. In this case a class in modified when it is being
loaded. You can just run you application with JaCoCo agent and a code coverage
is calculated. This way is used by Eclemma and Intellij Idea. But there is a
big issue. PowerMock instruments classes also. Javassist is used to modify
classes. The main issue is that Javassist reads classes from disk and all
JaCoCo changes are disappeared. As result zero code coverage for classes witch
are loaded by PowerMock class loader. ——[Code coverage with
JaCoCo](https://github.com/powermock/powermock/wiki/Code-coverage-with-JaCoCo)
JaCoCo tracks execution with so called probes. Probes are additional byte
code instructions inserted in the original class file which will note when they
are executed and report this to the JaCoCo runtime. This process is called
instrumentation. In short, Jacoco will modify the class when it is loaded.
Jacoco use class ids to unambiguously identify Java classes. At runtime
execution data is sampled for every loaded class and typically stored to *.exec
files. At analysis time — for example for report generation — the class ids are
used to relate analyzed classes with the execution data.
Meanwhile, when performing unit tests, PowerMock will modify the byte code
of the tested class according to your mock requirements, which causes the class
ids to change. There are different classes are used at runtime and at analysis
time, so the data cannot be related to the analyzed classes. As a consequence
such classes are reported with 0% coverage.
## Solution
I think we can make Jacoco running in [offline
instrumentation](https://www.eclemma.org/jacoco/trunk/doc/offline.html) to get
code converage. This way classes get instrumented by JaCoCo before any runtime
modification can take place.
## Which version of Dolphin Scheduler
- 1.3.6
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]