新的科研idea是覆盖率引导的测试生成,里面需要用到查询某个测试类对被测方法的覆盖情况,想到了最常用的jacoco,在chatgpt的帮助下实现了这个方法。
需要在项目的pom.xml中加入以下内容
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
再在teminal中执行(如果有多个测试类,可以用逗号隔开)
mvn test -Dtest="org.apache.commons.csv.generated_by_chatgpt.CSVFormatTest"
运行成功截图
这时,能够在target/site下看到jacoco.xml
我们可以在在jacoco.xml中首先定位类标签
<class name="org/apache/commons/csv/CSVFormat" sourcefilename="CSVFormat.java">
然后定位方法标签
<method name="hashCode" desc="()I" line="554">
就能看到CSVFormatTest针对CSVFormat的hashCode这一方法的覆盖率情况了
五个标签的含义如下
hashCode
这个方法被完全覆盖,即在测试中被调用了。对我来说我需要获取字节码指令和分支这两个属性遗漏覆盖的情况,为此我写了一个Python方法,用xml.etree.ElementTree来解析jacoco.xml,代码如下
import xml.etree.ElementTree as ET
def check_missed_value():
"""
查询特定项目某个方法运行后生成的jacoco.xml
返回遗漏的被测方法的字节码指令数量和分支数量
"""
jacoco_xml_path = r"C:\dataset\d4j-spec5\3_csv\4f\4f\target\site\jacoco\jacoco.xml"
# 加载XML文件
tree = ET.parse(jacoco_xml_path)
root = tree.getroot()
# 寻找特定的<class>标签
class_name = "org/apache/commons/csv/CSVFormat"
source_file_name = "CSVFormat.java"
method_name = "hashCode"
method_desc = "()I"
for cls in root.iter('class'):
if cls.get('name') == class_name and cls.get('sourcefilename') == source_file_name:
# 在找到的<class>标签中寻找特定的<method>标签
for method in cls.iter('method'):
if method.get('name') == method_name and method.get('desc') == method_desc:
# 显示所有的<counter>标签
for counter in method.iter('counter'):
if counter.get('type') == "INSTRUCTION":
missed_instruction = int(counter.get('missed'))
elif counter.get('type') == "BRANCH":
missed_branch = int(counter.get('missed'))
if missed_instruction is not None and missed_branch is not None:
return (missed_instruction, missed_branch)
return None