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:cobertura
See screenshots:
Coverage test report generation (cobertura)
cobertura principle
cobertura implementation process is as follows:
1, using instrument
modified after we compile class
files located target\generated-classes
.
2, the output of a test is performed to test data xxx.ser
in located target\cobertura\cobertura.ser
.
3, use report
to generate coverage reports.
1. instrument
-
instrument
: Cobertura useinstrument
to 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 .class
in, save it to \target\generated-classes
the 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.ser
archive.
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\cobertura
next path. If you configured to generate a html
report format, by index.html
the 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:cobertura
when 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:-UseSplitVerifier
this 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:check
function is the same, the difference between the two is bound maven life cycle is not the same.cobertura:check
Boundtest
,cobertura:check-integration-test
boundverify
. Some say it's clear, there is a maven life cycle istest
run unit tests, there is aintegration-test
running integration tests. andverify
before thatintegration-test
. That iscobertura:check-integration-test
more thancobertura:check
more 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 filecobertura.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:cobertura
did 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 understandingcobertura-maven-plugin
. cobertura:help
-
cobertura:instrument
Mark is compiled class files. This command will execute in the directory
/target/generated-classes/cobertura
to 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 pom
providing 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 pom
providing 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=false
parameters 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