SpringBoot unit test (Cobertura coverage report generation)

demo (SpringBoot project)

The test class:

import org.springframework.stereotype.Service;

@Service
public class TestService {
    public String sayHi() {
        return "hi";
    }

    public int divide(int a, int b) {
        return a / b;
    }
}

Test code:

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestServiceTest {
    @Autowired
    TestService testService;

    @Test
    public void testSayHi() {
        TestService testService = new TestService();
        String result = testService.sayHi();
        assertEquals("hi", result);
    }

    @Test
    public void testDivide() {
        TestService testService = new TestService();
        int result = testService.divide(3, 6);
        assertTrue(result > -1);
    }
}

pom.xml Profiles

![cobertura](C:\Users\jiaflu\Desktop\cobertura.PNG)<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.jiaflu</groupId>
    <artifactId>learn_springoot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>learn_springoot</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <jackson.version>2.9.8</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.5</version>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>cobertura-maven-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <formats>
                        <format>html</format>
                        <format>xml</format>
                    </formats>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>

Run mvn cobertura:coberturaSee screenshots:

5114528-ae2dea22c99d6bdc.PNG
cobertura.PNG

Coverage test report generation (cobertura)

cobertura principle

cobertura implementation process is as follows:
1, using instrumentmodified after we compile classfiles located target\generated-classes.
2, the output of a test is performed to test data xxx.serin located target\cobertura\cobertura.ser.
3, use reportto generate coverage reports.

1. instrument

  • instrument: Cobertura use instrumentto modify our compiled class files, add cobertura statistical code in the code inside. .Ser and generates a file (for output data coverage).

Use instrument implementation process, CoberturaInstrumenter will first analyze a given analysis compiled listener calls .class, get touchPoint and other required information (corresponding to the source code line can be considered to be covered). Then call the listener will inject injected into the new information .classin, save it to \target\generated-classesthe directory.

Example:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.cisco.webex.cmse.soa.soaservice.service;

import net.sourceforge.cobertura.coveragedata.HasBeenInstrumented;
import net.sourceforge.cobertura.coveragedata.TouchCollector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;

@PropertySource({"classpath:application.properties"})
@Service
public class PropertyService implements HasBeenInstrumented {
    private static final Logger logger;
    @Value("${cdp.instance.url}")
    private String cdpInstanUrl;
    @Value("${soa.instance.url}")
    private String soaInstanceUrl;
    @Value("${github.api.token}")
    public String gitApiToken;
    @Value("${github.instance.url}")
    private String githubInstance;
    @Value("${github.repo.template.owner}")
    private String tplRepoOwner;
    @Value("${github.repo.consul.owner}")
    private String consulRepoOwner;
    @Value("${slm.listen.queue.name}")
    private String slmListenQueue;

    public PropertyService() {
        boolean var1 = false;
        int __cobertura__branch__number__ = true;
        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 12);
        super();
    }

    public String getCdpInstanUrl() {
        boolean var1 = false;
        int __cobertura__branch__number__ = true;
        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 33);
        return this.cdpInstanUrl;
    }

    ...

    public void setSlmListenQueue(String ()V) {
        boolean var2 = false;
        int __cobertura__branch__number__ = true;
        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 85);
        this.slmListenQueue = slmListenQueue;
        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 86);
    }

    static {
        boolean var0 = false;
        boolean var1 = true;
        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 13);
        logger = LoggerFactory.getLogger(PropertyService.class);
    }
}

2. Perform a test

In the implementation of test cases, cited cobertura modified .class, test information is written to c obertura.serarchive.

3. Generate reports

Coverage data acquired from cobertura.ser, src and then combined with the source code provided to generate the final coverage report, placed target\site\coberturanext path. If you configured to generate a htmlreport format, by index.htmlthe coverage test report viewing.

SpringBoot pom.xml configuration

Add the following dependence:

        <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <!-- 此参数用于解决一个坑,下面会说明 -->
                    <argLine>-noverify</argLine>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>cobertura-maven-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <formats>
                        <format>xml</format>
                        <format>html</format>
                    </formats>
                </configuration>
            </plugin>

Pit:

In use mvn cobertura:coberturawhen generating test coverage report command, a problem arises that (taken part, the reason given below):

  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: 2ab4 001b 2bb9 002e 0200 c600 2f2a b400
    0x0000010: 1b2b b900 2e02 00c0 0030 b600 34c6 001c

Solution:

  • I am using jdk1.8, add jvm parameters -noverify, you can add pom configuration file, the configuration see abovepom.xml
  • Online information jdk1.7 add jvm parameters -XX:-UseSplitVerifier, (not 1.8 -XX:-UseSplitVerifierthis parameter)

Commands

  • coverage: check

    According to the latest source code tag (generated class file) verification test case coverage, if not meet the requirements, the failure to perform.

  • cobertura:check-integration-test

    This command and cobertura:checkfunction is the same, the difference between the two is bound maven life cycle is not the same. cobertura:checkBound test, cobertura:check-integration-testbound verify. Some say it's clear, there is a maven life cycle is testrun unit tests, there is a integration-testrunning integration tests. and verifybefore that integration-test. That is cobertura:check-integration-testmore than cobertura:checkmore test cases to cover.

  • cobertura:clean

    This is easy to understand, is to clean out the directory /target/cobertura/of the files we have now found it on a file cobertura.ser.

  • coverage: coverage

    The key command this plug-in. Mark is compiled files, run unit tests, generate test reports.

  • Coverage: Coverage-integration-test

    And cobertura:coberturadid the same thing, the difference is the inclusion of an integrated test case.

  • cobertura:dump-datafile

    At the command line output coverage data is based on data generated class file. This command I did not get to know what is the meaning of his. In the back 一个有趣的实验we will use this command to a better understanding cobertura-maven-plugin.

  • cobertura:help

  • cobertura:instrument

    Mark is compiled class files. This command will execute in the directory /target/generated-classes/coberturato generate a class file.

maven-surefire-plugin Description

Maven is not in itself a unit testing framework, it is only when building execution to a specific stage of the life cycle to execute JUnit or TestNG test cases through plug-ins. This plug-in is the maven-surefire-plugin, can also be referred to as test runner (Test Runner), it is compatible with JUnit 3, JUnit 4 and TestNG.

By default, test target maven-surefire-plugin automatically perform a test source path (by default src / test / java /) The test classes comply with a set mode is named. This set of patterns is:

  • * / Test .java: any Java class to a subfolder named Test all switches.
  • * / Test.java: any Java class named Test all ending in a subdirectory.
  • * / TestCase.java: any Java class TestCase all named after ending subdirectory.

maven-surefire-plugin plug-in applications:

1. Skip Test

Skip the test run mvn package -DskipTests

Or by pomproviding the properties:

<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skipTests>true</skipTests>  
    </configuration>  
</plugin>

Skip compiling test code mvn package -Dmaven.test.skip=true

Or by pomproviding the properties:

<plugin>  
    <groupId>org.apache.maven.plugin</groupId>  
    <artifactId>maven-compiler-plugin</artifactId>  
    <version>2.1</version>  
    <configuration>  
        <skip>true</skip>  
    </configuration>  
</plugin>

2. Dynamic designated to run the test case

mvn test -Dtest=RandomGeneratorTest

You can also use wildcards:

mvn test -Dtest=Random*Test

Or may be used "," No specify a plurality of test categories:

mvn test -Dtest=Random*Test,AccountCaptchaServiceTest

If no test class, it will complain and cause the build to fail:

mvn test -Dtest
This time you can add -DfailIfNoTests=falseparameters to tell maven-surefire-plugin and do not test even without any error:

mvn test -Dtest -DfailIfNoTests=false

3. Including and Excluding a test case

<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <includes>  
            <include>**/*Tests.java</include>  
        </includes>  
        <excludes>  
            <exclude>**/*ServiceTest.java</exclude>  
            <exclude>**/TempDaoTest.java</exclude>  
        </excludes>  
    </configuration>  
</plugin>

Reference article:

https://my.oschina.net/huhaoren/blog/410437

https://www.cnblogs.com/qyf404/archive/2015/12/12/5040593.html

Guess you like

Origin blog.csdn.net/weixin_34025151/article/details/90790610