This entry assumes that you are using Lombok, which generates the source code, and the coverage measurement tool Jacoco. I will prepare a sample and introduce how to increase the coverage in).
The purpose of this entry is to help you get started when you want to use Lombok with as little code as possible and increase coverage with Jacoco. It does not explain all the functions of each tool.
In conclusion, let's exclude the automatically generated code from the coverage inspection target by specifying "lombok.addLombokGeneratedAnnotation = true" on the lombok side using Jacoco 0.8.0 (released 1/2/2018) or higher. , Is a big point.
In Qiita, about Lombok, Jacoco,
-[Search by Qiita](https://qiita.com/search?utf8= ✓ & sort = & q = lombok), there were 347.
-[Search by Qiita](https://qiita.com/search?utf8= ✓ & sort = & q = jacoco), there were 79.
There are many (as of May 26, 2018), but the following will be helpful.
As a sample, I made a Spring Boot that stores and displays simple entities through a REST Controller.
It works like this.
(Registration)
$ curl -H 'Content-Type:application/json' -d '{"intField":123}' http://localhost:8080
(reference)
$ curl http://localhost:8080/
[{"id":"2815cfc6-f908-4c7d-a20b-b2c52953555f","intField":123,"longField":0,"stringField":null,"charField"
(1 detail)
$ curl http://localhost:8080/2815cfc6-f908-4c7d-a20b-b2c52953555f
{"id":"2815cfc6-f908-4c7d-a20b-b2c52953555f","intField":123,"longField":0,"stringField":null,"charField":"\u0000","byteField":0}hirokis-M
It is stored in Initial repository.
In this version, it is implemented without using the convenient functions of lombok.
$ ./gradlew test
$ ./gradlew jacocoTestReport
The coverage looks like this.
@ Data
SampleEntity.java
public class SampleEntity {
private SampleId id;
private int intField;
private long longField;
private String stringField;
private char charField;
private byte byteField;
/**
* @return the id
*/
public SampleId getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(SampleId id) {
this.id = id;
}
/**
* @return the intField
*/
public int getIntField() {
return intField;
}
/**
* @param intField the intField to set
*/
public void setIntField(int intField) {
this.intField = intField;
}
/**
* @return the longField
*/
public long getLongField() {
return longField;
}
/**
* @param longField the longField to set
*/
public void setLongField(long longField) {
this.longField = longField;
}
/**
* @return the stringField
*/
public String getStringField() {
return stringField;
}
/**
* @param stringField the stringField to set
*/
public void setStringField(String stringField) {
this.stringField = stringField;
}
/**
* @return the charField
*/
public char getCharField() {
return charField;
}
/**
* @param charField the charField to set
*/
public void setCharField(char charField) {
this.charField = charField;
}
/**
* @return the byteField
*/
public byte getByteField() {
return byteField;
}
/**
* @param byteField the byteField to set
*/
public void setByteField(byte byteField) {
this.byteField = byteField;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + byteField;
result = prime * result + charField;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + intField;
result = prime * result + (int) (longField ^ (longField >>> 32));
result = prime * result
+ ((stringField == null) ? 0 : stringField.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SampleEntity other = (SampleEntity) obj;
if (byteField != other.byteField)
return false;
if (charField != other.charField)
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (intField != other.intField)
return false;
if (longField != other.longField)
return false;
if (stringField == null) {
if (other.stringField != null)
return false;
} else if (!stringField.equals(other.stringField))
return false;
return true;
}
/**
* @param id
* @param intField
* @param longField
* @param stringField
* @param charField
* @param byteField
*/
public SampleEntity(SampleId id, int intField, long longField,
String stringField, char charField, byte byteField) {
super();
this.id = id;
this.intField = intField;
this.longField = longField;
this.stringField = stringField;
this.charField = charField;
this.byteField = byteField;
}
public SampleEntity() {
super();
};
}
SampleEntity.java
@Data
public class SampleEntity {
private SampleId id;
private int intField;
private long longField;
private String stringField;
private char charField;
private byte byteField;
}
If you check in the IDE with the lombok plugin applied (Eclipse in this entry), you can see that the setter, getter, toString, and hashCode are generated.
@ RequiredArgsConstructor
When injecting a field with @Autowired of Spring, it may be troublesome to replace it directly for testing etc., or it may take up space when there are many things to use, so inject it with the constructor. I will change it.
SampleApi.java
@RestController
@RequestMapping("/")
public class SampleApi {
@Autowired
private SampleFacade sampleFacade;
SampleApi.java
@RestController
@RequestMapping("/")
@RequiredArgsConstructor
public class SampleApi {
private final SampleFacade sampleFacade;
So far, the jacoco Report looks like this.
Here, the domain package is a good proportion, but if you look inside, it is naturally the code automatically generated by lombok. When the behavior of lombok is positive, it doesn't make much sense to test what is generated.
For this reason, let's specify to exclude the code generated by Lombok from the test. Place the following files in the project directory and try the test again.
lombok.config
lombok.addLombokGeneratedAnnotation = true
$ ./gradlew clean
$ ./gradlew test
$ ./gradlew jacocoTestReport
And the coverage changes like this. The red situation hasn't changed since I haven't written the test code yet, but the domain area has been greatly reduced, and the overall code instructions have been significantly reduced from 731 to 170.
A description of the values that can be specified in lombok.config can be found on the lombok official website.
I put the above as v0.2 on GitHub.
In the unit test, the coverage is set to 100% by passing 1 pass for the time being Sample on GitHub v0.3 It will be /releases/tag/v0.3).
(Reference) Now, if you restore (do not specify) the exclusion setting, this situation will occur.
In this entry, I saw how to exclude the code automatically generated by lombok from the coverage measurement, and showed through the sample code how it actually works.
In addition to using the lombok function in the sample of this entry, Various on the original site has been introduced, so I would like to introduce a usage example at another time. think.
Recommended Posts