Jacoco的Arquillian集成测试代码覆盖问题

时间:2019-01-29 01:16:15

标签: code-coverage jacoco jboss-arquillian tomee jacoco-maven-plugin

我正在使用Arquillian和tomee远程插件进行集成测试。运行良好。但是我的代码覆盖范围无效。我正在使用Jacoco插件进行代码覆盖。在我的Java类中获取异常 java.lang.instrument.IllegalClassFormatException:检测com / demo / EmpService

时出错

如何使用Jacoco在远程容器中进行代码覆盖?

注意::我已经在集成阶段将javaagent(argLine)传递给服务器catalina opts。我正在将我的bean注入测试类,并尝试涵盖测试用例。测试用例通过。但是没有代码覆盖并且没有异常

EmpService:

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class EmpService {

    public String getName(String name) {
        System.out.println(" I am here ###################### "+name);
        String s = "Fine";
        if(name.startsWith("s")) {
            s = "Welcome";
        }
        return s;
    }
}

EmpSericeIT.java

public class EmpServiceIT extends Arquillian {

    @Inject
    private EmpService empService;

    @Deployment
    public static WebArchive createDeployment() throws IOException {
        WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
                .addClass(EmpService.class)
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
        System.out.println(webArchive.toString(true));
        return webArchive;
    }

    @Test
    public void testService() {

        assertNotNull(empService);
        assertEquals(empService.getName("K"),"Fine");
        assertEquals(empService.getName("s"),"Welcome");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo</groupId>
    <artifactId>code-coverage</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>

        <tomee.version>7.1.0</tomee.version>
        <tomee.classifier>plus</tomee.classifier>
        <lombok.version>1.16.8</lombok.version>
        <arquillian.version>1.4.1.Final</arquillian.version>
        <testng.version>6.14.3</testng.version>
        <shrinkwrap.resolvers.version>3.1.3</shrinkwrap.resolvers.version>
        <plugin.maven.jacoco.version>0.8.2</plugin.maven.jacoco.version>

        <plugin.maven-surefire.version>2.19.1</plugin.maven-surefire.version>
        <version.plugin.maven.failsafe>2.19.1</version.plugin.maven.failsafe>

    </properties>

    <dependencies>

        <dependency>
            <groupId>org.apache.tomee</groupId>
            <artifactId>apache-tomee</artifactId>
            <classifier>${tomee.classifier}</classifier>
            <type>zip</type>
            <scope>provided</scope>
            <version>${tomee.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-jdk14</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.jboss.arquillian.testng</groupId>
            <artifactId>arquillian-testng-container</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.arquillian.config</groupId>
            <artifactId>arquillian-config-api</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-jacoco</artifactId>
            <version>1.0.0.Alpha10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.core</artifactId>
            <version>${plugin.maven.jacoco.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.shrinkwrap.resolver</groupId>
            <artifactId>shrinkwrap-resolver-depchain</artifactId>
            <version>${shrinkwrap.resolvers.version}</version>
            <scope>test</scope>
            <type>pom</type>
        </dependency>


        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.apache.tomee</groupId>
            <artifactId>arquillian-tomee-remote</artifactId>
            <version>${tomee.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.myfaces.core</groupId>
                    <artifactId>myfaces-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.myfaces.core</groupId>
                    <artifactId>myfaces-impl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.tomee</groupId>
                    <artifactId>tomee-myfaces</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.tomee</groupId>
            <artifactId>openejb-cxf-rs</artifactId>
            <version>${tomee.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>

        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${plugin.maven.jacoco.version}</version>
                <configuration>
                    <includes>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-prepare-agent-integration</id>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                        <configuration>
                            <destFile>${project.build.directory}/jacoco-it.exec</destFile>
                        </configuration>
                    </execution>
                    <execution>
                        <id>Create Unit Test Report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>Create Integration Test Report</id>
                        <goals>
                            <goal>report-integration</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${plugin.maven-surefire.version}</version>
                <configuration>
                    <skip>true</skip>
                    <skipTests>true</skipTests>
                    <failIfNoTests>false</failIfNoTests>
                    <excludes>
                        <exclude>**/*IT.java</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${version.plugin.maven.failsafe}</version>
                <configuration>
<!--
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
-->
                        <systemPropertyVariables>
                            <tomee.classifier>${tomee.classifier}</tomee.classifier>
                            <tomee.version>${tomee.version}</tomee.version>
                            <tomee.httpPort>-1</tomee.httpPort>
                            <tomee.stopPort>-1</tomee.stopPort>
                            <tomee.ajpPort>-1</tomee.ajpPort>
                            <tomee.dir>target/apache-tomee-remote</tomee.dir>
                            <tomee.appWorkingDir>target/arquillian-test-working-dir</tomee.appWorkingDir>
                            <tomee.cleanOnStartUp>true</tomee.cleanOnStartUp>
                            <tomee.catalina_opts>-Xmx550m -XX:MaxPermSize=200m ${argLine}</tomee.catalina_opts>
                            <!--<tomee.javaVmArguments>-Xmx1024m ${surefireArgLine} -Dsimple=XYZ</tomee.javaVmArguments>-->
                            <tomee.properties>
                                tomee.jpa.cdi=false
                                LOG_TO_CONSOLE=true
                            </tomee.properties>
                        </systemPropertyVariables>
<!--
                        <argLine> </argLine>
                        <suiteXmlFiles>
                            <suiteXmlFile>${project.basedir}/src/test/resources/testng.xml</suiteXmlFile>
                        </suiteXmlFiles>
-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>${arquillian.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

例外

java.lang.instrument.IllegalClassFormatException: Error while instrumenting com/demo/EmpService.
    at org.jacoco.agent.rt.internal_28bab1d.CoverageTransformer.transform(CoverageTransformer.java:93)
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2339)
    at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:829)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1278)
    at org.apache.tomee.catalina.TomEEWebappClassLoader.loadClass(TomEEWebappClassLoader.java:208)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137)
    at org.apache.openejb.cdi.CdiScanner.load(CdiScanner.java:321)
    at org.apache.openejb.cdi.CdiScanner.handleBda(CdiScanner.java:255)
    at org.apache.openejb.cdi.CdiScanner.init(CdiScanner.java:148)
    at org.apache.openejb.cdi.OpenEJBLifecycle.startApplication(OpenEJBLifecycle.java:179)
    at org.apache.openejb.cdi.ThreadSingletonServiceImpl.initialize(ThreadSingletonServiceImpl.java:189)
    at org.apache.openejb.cdi.CdiBuilder.build(CdiBuilder.java:41)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:963)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:757)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1303)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1125)
    at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:133)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5154)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.deployWar(TomcatWebAppBuilder.java:652)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.deployWebApps(TomcatWebAppBuilder.java:592)
    at org.apache.tomee.catalina.deployment.TomcatWebappDeployer.deploy(TomcatWebappDeployer.java:47)
    at org.apache.openejb.assembler.DeployerEjb.deploy(DeployerEjb.java:177)
    at org.apache.openejb.assembler.DeployerEjb.deploy(DeployerEjb.java:140)
    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 org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
    at org.apache.openejb.security.internal.InternalSecurityInterceptor.invoke(InternalSecurityInterceptor.java:35)
    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 org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
    at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:191)
    at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:102)
    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 org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
    at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:85)
    at org.apache.openejb.core.singleton.SingletonContainer._invoke(SingletonContainer.java:272)
    at org.apache.openejb.core.singleton.SingletonContainer.invoke(SingletonContainer.java:221)
    at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbObject_BUSINESS_METHOD(EjbRequestHandler.java:371)
    at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:182)
    at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:360)
    at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:247)
    at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:104)
    at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:60)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Error while instrumenting com/demo/EmpService.
    at org.jacoco.agent.rt.internal_28bab1d.core.instr.Instrumenter.instrumentError(Instrumenter.java:175)
    at org.jacoco.agent.rt.internal_28bab1d.core.instr.Instrumenter.instrument(Instrumenter.java:125)
    at org.jacoco.agent.rt.internal_28bab1d.CoverageTransformer.transform(CoverageTransformer.java:91)
    ... 83 more

1 个答案:

答案 0 :(得分:1)

我通过询问JaCoCo开发人员(here)找到了您的解决方案。它似乎与TestNG有关。如果将TestNG库添加到Arquillian容器中,则覆盖范围应固定。修改后的示例如下所示。

@Deployment
public static WebArchive createDeployment() throws IOException {
    PomEquippedResolveStage pomEquippedResolveStage = Maven.resolver().loadPomFromFile("pom.xml");

    File[] externalLibs = pomEquippedResolveStage.resolve(
            "org.testng:testng"
    ).withTransitivity().asFile();

    WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
            .addClass(EmpService.class)
            .addAsLibraries(externalLibs)
            .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
    System.out.println(webArchive.toString(true));
    return webArchive;
}