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]


Reply via email to