如果您需要获得针对 Java 代码的测试的代码覆盖率,那么 JaCoCo 是一个非常好的选择,因为您不需要事先对代码进行检测,它会在测试期间即时完成.
将 JaCoCo 附加到 Weblogic JVM:
JaCoCo 收集器将自己作为代理附加到 JVM 并不断收集代码覆盖工具。我们需要添加 JVM 参数来进行设置。
第一步:
为此,请编辑 setDomainEnv.cmd 或 setDomainEnv.sh 文件以添加以下参数:
set JACOCO_PROPERTIES=-javaagent:c:/tools/jacoco-0.7.1-20140326.062324-3/lib/jacocoagent.jar=destfile=c:/temp/jacoco.exec,output=file,address=,includes=com.package
在同一个文件中,将其添加到 EXTRA_JAVA_PROPERTIES 环境变量中:
set
EXTRA_JAVA_PROPERTIES=-Dcommon.components.home=%COMMON_COMPONENTS_HOME%
-Djrf.version=11.1.1 -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
-Ddomain.home=%DOMAIN_HOME% -Djrockit.optfile=%COMMON_COMPONENTS_HOME%\modules\oracle.jrf_11.1.1\jrocket_optfile.txt
-Doracle.server.config.dir=%ORACLE_DOMAIN_CONFIG_DIR%\servers\%SERVER_NAME%
-Doracle.domain.config.dir=%ORACLE_DOMAIN_CONFIG_DIR% -Digf.arisidbeans.carmlloc=%ORACLE_DOMAIN_CONFIG_DIR%\carml -Digf.arisidstack.home=%ORACLE_DOMAIN_CONFIG_DIR%\arisidprovider -Doracle.security.jps.config=%DOMAIN_HOME%\config\fmwconfig\jps-config.xml
-Doracle.deployed.app.dir=%DOMAIN_HOME%\servers\%SERVER_NAME%\tmp_WL_user
-Doracle.deployed.app.ext=- -Dweblogic.alternateTypesDirectory=%ALT_TYPES_DIR% -Djava.protocol.handler.pkgs=%PROTOCOL_HANDLERS% %WLS_JDBC_REMOTE_ENABLED% %**JACOCO_PROPERTIES**%
%EXTRA_JAVA_PROPERTIES%
第二步:
重新启动 Weblogic 服务器
由于 JaCoCo 将自身附加到 JVM,因此您需要重新启动 Weblogic 服务器。使用 startWeblogic.sh 或 startWeblogic.cmd 再次启动 JVM 后,您将看到列出的文件位置 destfile=c:/temp/jacoco.exec 将被创建。最初它是空的,但在 JVM 关闭时它会被填充。
第 3 步:测试您的应用程序
连接 JaCoCo 代理后,部署您的应用程序并运行集成测试。 JaCoCo 将即时检测代码并收集指令级和分支级覆盖率信息。
第 4 步:生成报告
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
import org.jacoco.core.analysis.IClassCoverage;
import org.jacoco.core.tools.ExecFileLoader;
import org.jacoco.report.DirectorySourceFileLocator;
import org.jacoco.report.FileMultiReportOutput;
import org.jacoco.report.IReportVisitor;
import org.jacoco.report.html.HTMLFormatter;
public class JaCoCoReportGenerator{
private static String title = "Code Coverage";
private static File executionDataFile = new File("your path where you have jacoco.exec");
private static List<File> classesDirectory;
private static List<File> sourceDirectory;
private static File reportDirectory = new File("path where you want your report to be generated");
private ExecFileLoader execFileLoader;
public JaCoCoReportGenerator(){
super();
initializeClassFileList();
initializeSourceFileList();
}
private void initializeClassFileList(){
classesDirectory = new ArrayList<File>();
File file0 = new File("class file path");
classesDirectory.add(file0);
}
private void initializeSourceFileList(){
sourceDirectory = new ArrayList<File>();
File file0 = new File("source file path");
sourceDirectory.add(file0);
}
public void create() throws IOException{
// Read the jacoco.exec file. Multiple data files could be merged
// at this point
loadExecutionData();
// Run the structure analyzer on a single class folder to build up
// the coverage model. The process would be similar if your classes
// were in a jar file. Typically you would create a bundle for each
// class folder and each jar you want in your report. If you have
// more than one bundle you will need to add a grouping node to your
// report
IBundleCoverage bundleCoverage = analyzeStructure();
createReport(bundleCoverage);
}
private void createReport(IBundleCoverage bundleCoverage) throws IOException{
// Create a concrete report visitor based on some supplied
// configuration. In this case we use the defaults
HTMLFormatter htmlFormatter = new HTMLFormatter();
IReportVisitor visitor = htmlFormatter.createVisitor(new FileMultiReportOutput(reportDirectory));
// Initialize the report with all of the execution and session
// information. At this point the report doesn't know about the
// structure of the report being created
visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(),execFileLoader.getExecutionDataStore().getContents());
for (File sourceFile : sourceDirectory) {
visitor.visitBundle(bundleCoverage,new DirectorySourceFileLocator(sourceFile,POSMConstant.ENCODING,4));
}
// Populate the report structure with the bundle coverage information.
// Call visitGroup if you need groups in your report.
// Signal end of structure information to allow report to write all
// information out
visitor.visitEnd();
}
private void loadExecutionData() throws IOException{
execFileLoader = new ExecFileLoader();
execFileLoader.load(executionDataFile);// Loading my jacoco.exe file
analyzeStructure();
}
private IBundleCoverage analyzeStructure() throws IOException{
final CoverageBuilder coverageBuilder = new CoverageBuilder();
final Analyzer analyzer = new Analyzer(execFileLoader.getExecutionDataStore(),coverageBuilder);
for (File classFile : classesDirectory) {
analyzer.analyzeAll(classFile);// Analyzes all class files contained in the given file or folder. Folders are searched recursively.
}
return coverageBuilder.getBundle(title);
}
public static void main(String[] args) throws IOException{
JaCoCoReportGenerator generator = new JaCoCoReportGenerator();
generator.create();
}
}