So let us say I have a test
@Test
public void testA(){
new A().doSomthing();
}
And let us say it covers a method doSomething()
, Now in my project, I have 10million tests and this test is just one of those. A small test doesn't do much.
Now let us say my doSomething
method looks like this:-
public void doSomething() {
if (var1)
killMylSelf();
else if (var2)
killMyMother();
else
killMySelfAndMyMother();
}
So as you can see there are a lot of branches in the method, that consequently call other methods that have even more branches. When I run testA
I want to see which branches I have missed in the code that got executed, how can I achieve this WITHOUT HAVING TO RUN ALL THE UNIT TESTS AND ONLY THE TEST THAT I CARE ABOUT,
Remember these magical words when you answer the question WITHOUT HAVING TO RUN ALL THE UNIT TESTS AND ONLY THE TEST THAT I CARE ABOUT
JaCoCo does not execute your tests, it simply records information about what was executed. So execution of a tests, including case of a single test, is entirely depends on a tool that you use to execute tests, which unfortunately not mentioned in your question.
If you use Maven as a build tool, then execution of tests is usually done and controlled by maven-surefire-plugin
, which has option test
to run individual test. Here is example:
src/main/java/Example.java
:
public class Example {
public void doSomething(int p) {
if (p == 1) {
a();
} else {
b();
}
}
private void a() {
System.out.println("a");
}
private void b() {
System.out.println("b");
}
}
src/test/java/ExampleTest.java
:
import org.junit.Test;
public class ExampleTest {
@Test
public void test1() {
new Example().doSomething(1);
}
@Test
public void test2() {
new Example().doSomething(2);
}
}
pom.xml
:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Execution of mvn clean verify -Dtest=ExampleTest#test1
will produce following report in directory target/site/jacoco
:
and execution of mvn clean verify -Dtest=ExampleTest#test2
will produce:
which show coverage of test1
and test2
respectively.
For comparison - execution of all tests by mvn clean verify
produces:
Note about usage of clean
: File target/jacoco.exec
contains execution information and used for generation of report ( see agent option destfile
and corresponding parameter of jacoco-maven-plugin
). By default JaCoCo agent appends to this files ( see agent option append
and corresponding parameter of jacoco-maven-plugin
), so that clean
is used in this example to prevent accumulation of data in this file about previous executions.
If you use Gradle, then it also has similar ability - given same sources and build.gradle
:
apply plugin: 'java'
apply plugin: 'jacoco'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
}
execution of gradle clean test --tests ExampleTest.test1 jacocoTestReport
will produce report containing coverage of test1
, which is the same as in case of Maven.
Similarly to example for Maven, clean
is used in this example to prevent accumulation of data about previous executions in file build/jacoco/test.exec
- see append
property of JaCoCo Gradle Plugin
.
If you use Eclipse IDE, then there is EclEmma Eclipse plugin that integrates JaCoCo in Eclipse IDE and included by default in "Eclipse IDE for Java Developers" starting from Oxygen (4.7) version. With it you can also get coverage of single test in Eclipse IDE - in editor right mouse click on a test name to get context menu and select "Coverage As -> JUnit Test".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With