如何使用JaCoCo-Maven插件生成代码覆盖率报告

代码覆盖率是软件开发过程中常用的一项质量指标,用于确定已测试(或执行)的代码程度。为达到最佳代码覆盖率,关键在于测试实现(或测试套件)需覆盖大部分已实施代码。

针对Java、C#、JavaScript等语言,存在多种代码覆盖工具。选择最适合的代码覆盖工具至关重要,它有助于了解已测试代码的百分比,并采取相应措施以确保实现理想的代码覆盖率。

为进行高效代码测试,许多公司采用JaCoCo-Maven插件,该插件能生成详尽的代码覆盖报告。JaCoCo-Maven插件是专为Java项目设计的免费代码覆盖库,基于EclEmma团队开发的现有集成库研究而成。总体而言,代码覆盖率确实能在一定程度上反映产品质量,覆盖率越高,未经测试的代码进入发布周期的可能性越小。

本文将深入探讨JaCoCo-Maven插件,了解其在Maven中的实施方式,并通过集成Maven项目及执行Selenium测试来生成详细的代码覆盖报告。

何为代码覆盖率?

在软件开发中,代码覆盖率是衡量测试套件执行时应用程序源代码被执行程度的指标。通过生成报告来查看和分析软件应用的代码覆盖情况,进而利用这些报告确保代码质量。

JaCoCo-Maven插件用于生成代码覆盖率报告。源代码若具有高代码覆盖率,意味着在测试过程中其代码被执行得更多。例如,若您测试的软件包含100行代码,而其中90行通过了验证,则该软件应用的代码覆盖率将达到90%。

代码覆盖率的好处

代码覆盖率对开发者、测试人员和QA工程师而言是一项极为有用的指标。以下是代码覆盖率的一些显著益处:

  • 代码覆盖率报告有助于发现并消除无效代码。遵循最佳实践可避免此类问题,进而提升代码的可维护性和产品质量。
  • 质量保证过程能帮助检测未被测试覆盖的代码。
  • 开发者能更快完成软件开发流程,提高生产力、可扩展性和效率,从而缩短产品上市时间(TTM)。

众所周知,代码覆盖率对每款软件产品都至关重要。经过对代码覆盖率核心要点的快速回顾,接下来我们将深入探讨主题,即使用JaCoCo-Maven插件生成代码覆盖率报告。

JaCoCo-Maven插件是什么?

JaCoCo-Maven(Java Code Coverage的缩写)插件是一个开源的Java代码覆盖工具,它能够创建代码覆盖率报告,并良好地集成于Eclipse IDE等集成开发环境(IDE)中。

它与CI/CD工具(如Jenkins、Circle CI等)和项目管理工具(如SonarQube等)无缝集成。作为Eclipse基金会的一部分,它已取代了Eclipse中的EclEmma代码覆盖工具。

JaCoCo-Maven插件是如何工作的?

  • JaCoCo-Maven插件通过运行时代理对Java代码进行检测以执行覆盖率分析。简而言之,启动JVM(Java虚拟机)时附加此代理,该代理称为JaCoCo代理。首次执行start-agent即启动JaCoCo运行时代理。
  • 每当加载一个类时,JaCoCo能对其进行检测,以便在测试过程中观察何时调用该类及其调用的代码行。通过这种跟踪,它即时构建代码覆盖统计数据,在第二次执行(即generate-report)时完成。
  • 默认情况下,文件在JVM终止时创建,但也可以在服务器模式下运行代理。这会触发结果的转储,并在终止前创建报告。以下展示了JaCoCo插件的内部结构:

  • 你可以在JaCoCo-Maven插件的配置中定义目标和规则,这提供了设置限制的灵活性,并有助于检查代码覆盖的程度。
  • Maven-surefire插件是默认的Maven插件,它在JVM中运行测试并提供覆盖率报告。而JaCoCo插件则对已由其他插件(如Surefire插件)执行的代码进行检测。因此,检查maven-surefire插件的依赖性是一个良好的实践。

为什么JaCoCo-Maven插件适合代码覆盖率测试?

JaCoCo-Maven插件之所以适合代码覆盖率测试,原因如下:

  • 在任何项目开发中,开发者通常偏好使用集成开发环境(IDE),因为这简化了编码和测试过程。JaCoCo可以通过在Eclipse IDE中安装名为EclEmma的插件来实现,只需从其市场下载EclEmma即可。
  • JaCoCo插件易于添加到各种构建系统中,包括ANT、Maven和Gradle。它还可以与Jenkins、Circle CI等CI/CD工具集成,使其在多种使用场景中表现出色。
  • JaCoCo生成的代码覆盖率报告是一个简单且信息丰富的HTML文件,可在任何浏览器或IDE中查看。
  • JaCoCo还提供离线检测功能(即在运行任何测试之前对所有类进行检测)。
  • 报告分析也相当简单,采用基于颜色的显示方式,并提供精确的代码覆盖率百分比。

如何将JaCoCo插件与Maven集成

要在Maven项目中获取代码覆盖率报告,首先需要为该项目设置JaCoCo Maven插件。通过集成JaCoCo插件,可以作为HTML报告形式审查代码覆盖率分析结果。当前版本的JaCoCo-Maven插件可从MVN Repository下载。

以下是将JaCoCo Maven插件与Maven项目集成的步骤:

1. 每个Maven项目都包含一个pom.xml文件,用于声明所有依赖和插件。JaCoCo-Maven插件也在此pom.xml文件中声明。对应的XML代码如下:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
</plugin>

这是在基于Maven的项目中,在build标签下添加的基本XML代码,用于指定JaCoCo插件。通过在execution标签中指定目标和规则,我们可以增强功能(如指定报告生成时机等)。

2. 在version标签后,我们添加execution标签。此标签用于设置属性或执行指向JaCoCo代理,并作为VM(在本例中为JVM)参数传递。

3. 对于运行简单的单元测试,执行标签中设置的两个目标即可满足需求。最基本的是设置prepare-agent和report目标。

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
  	<execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
      </execution>
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
        </execution>
    </executions>
 </plugin>


  • Prepare-agent目标:prepare-agent目标准备JaCoCo运行时代理以记录执行数据,记录执行的行数、回溯等。默认情况下,执行数据被写入文件target/jacoco-ut.exec
  • Report目标:report目标从JaCoCo运行时代理记录的执行数据创建代码覆盖率报告。由于我们已指定phase属性,报告将在测试阶段编译后创建。默认情况下,执行数据从文件target/jacoco-ut.exec读取,代码覆盖率报告写入目录target/site/jacoco/index.html

4. 对于运行简单的单元测试,上述配置已经足够。然而,我们需要对代码覆盖率报告施加一些约束(例如,指定目标目录等)。这可以通过配置标签来实现:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
  	<execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
            <configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                <propertyName>surefireArgLine</propertyName>
            </configuration>
      </execution>
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
               <configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
               </configuration>
        </execution>
    </executions>
 </plugin>

首次执行的配置

根据上述代码,可以看到指定了一些标签,如destFile等。以下是对这些标签的简要描述:

  • destFile标签destFile标签用于设置包含执行数据文件的路径。
  • propertyName-surefireArgLine标签:此标签设置包含JaCoCo运行时代理设置的属性名称,同时也设置了运行单元测试时的VM参数行。

第二次执行的配置

根据上述代码,可以看到指定了标签如dataFile等。以下是对这些标签的简要描述:

  • dataFile标签: dataFile标签用于设置包含执行数据文件的路径。
  • outputDirectory标签: 此标签设置代码覆盖率报告的输出目录。

5. 我们还可以在配置标签中添加规则,以监控代码覆盖率的百分比。这可以通过以下方式实现:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
  	<execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
            <configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                <propertyName>surefireArgLine</propertyName>
            </configuration>
      </execution>
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
               <configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
               </configuration>
        </execution>
        <execution>
              <id>jacoco-check</id>
              <goals>
                <goal>check</goal>
              </goals>
              <configuration>
              	<rules>
                 	   <rule>
                    	<element>PACKAGE</element>
                    	<limits>
                      		<limit>
                        		<counter>LINE</counter>
                        		<value>COVEREDRATIO</value>
                        		<minimum>0.50</minimum>
                      		</limit>
                   	</limits>
                	   </rule>
            	      </rules>
             </configuration>
 	  </execution>
    </executions>
 </plugin>

第三次执行的配置

在此,定义了一个新的目标检查。jacoco:check目标绑定以验证指定的规则。规则在rule标签中给出。您可以灵活地指定多个规则。

  • 元素标签:此标签指定规则需应用的元素。
  • 限制标签:诸如counter、value、minimum等标签用于限制代码覆盖率的百分比。可以使用命令如mvn clean verify来确保规则是否被遵守。

6. JaCoCo-Maven插件配置中可以定义多个目标和规则。

使用Maven和JaCoCo插件生成代码覆盖报告

本节将演示使用JaCoCo Maven插件生成代码覆盖报告的步骤。演示通过一个非常简单的测试场景进行。那么,让我们开始吧。

前提条件

  1. Maven 3.0或更高版本:Maven是一个项目开发管理和理解工具。您可以从官方Apache Maven网站安装最新版本。
  2. Java 1.5或更高版本:您需要确保Java已安装在您的机器上。如果您未安装Java,请从官方Java网站下载最新版本的Java。
  3. Eclipse IDE for Java Developers:虽然您可以使用您选择的IDE,但本演示使用的是Eclipse IDE。

创建简单Maven项目的步骤

  1. 在Eclipse IDE中,转到File > New > Maven Project。

2. 弹出一个新对话框。确保勾选“使用默认工作区位置”复选框,并点击“下一步”。

3. 在项目中选择原型时,在过滤器旁边的文本框中输入org.apache.maven,选择maven-archetype-quickstart,然后点击“下一步”。

4. 现在,将“组ID”指定为com.example,将“构件ID”指定为jacoco-example。“构件ID”即我们的项目名称。最后,点击“完成”按钮。

5. 你可以在“项目资源管理器”中看到项目文件和文件夹的层次结构。

如何在POM.xml中指定JaCoCo Maven插件

1. 打开POM.xml,滚动到标签处。我们将在列出Maven插件的部分指定JaCoCo-Maven插件。只需复制下面的代码并粘贴到上述标签中:

 

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.6</version>
  <executions>
     <!--first execution : for preparing JaCoCo runtime agent-->
      <execution>
      	<id>prepare-agent</id>
            <goals>
            		<goal>prepare-agent</goal>
            </goals>
      </execution>
     <!--second execution : for creating code coverage reports-->
      <execution>
            <id>report</id>
            <phase>test</phase>
               <goals>
               	<goal>report</goal>
               </goals>
        </execution>
    </executions>
 </plugin>

2. 由于我们正在演示使用JUnit进行自动化Web测试的报告生成,我们还将声明POM.xml中的JUnit依赖。

以下是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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>


  <groupId>com.example</groupId>
  <artifactId>jacoco-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>

 <name>jacoco-example</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>


<!-- JUnit dependencies added to run test cases -->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>


  <build>
      <plugins>
        <!-- Maven plugin for Project Management -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.19.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.6</version>
                                  
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                        <goals><goal>prepare-agent</goal></goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals><goal>report</goal></goals>
                    </execution>
                </executions>
            </plugin>
      </plugins>
  </build> 
</project>

3. 从项目目录出发,导航到src/main/java中存在的com.example.jacoco_lambdatest包。创建一个名为LambdaTest.java的新Java类。我们将在其中编写一个简单的setUp()函数,该函数提供Selenium Grid所需的特性。

 

package com.example.Jacoco_lambdatest;

import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LambdaTest {
	public static String username = "<LambdaTest_Username>";
	public static String accessKey = "<LambdaTest_AccessKey>";
	
  public static DesiredCapabilities setUp() throws Exception {
     DesiredCapabilities capabilities = new DesiredCapabilities();
      capabilities.setCapability("platform", "Windows 10");
	     capabilities.setCapability("browserName", "Chrome");
	     capabilities.setCapability("version", "87.0"); // If this cap isn't specified, it will just get the any available one
      capabilities.setCapability("resolution","1024x768");
      capabilities.setCapability("build", "First Test");
      capabilities.setCapability("name", "Sample Test");
      capabilities.setCapability("network", true); // To enable network logs
      capabilities.setCapability("visual", true); // To enable step by step screenshot
      capabilities.setCapability("video", true); // To enable video recording
      capabilities.setCapability("console", true); // To capture console logs
      return capabilities;
  }
}

向项目中添加JUnit测试案例

1. 我们将在AppTest.java中创建一个简单的JUnit测试案例。这是默认提供的,位于src/test/java下的包名com.example.jacoco_lambdatest中。

 

package com.example.Jacoco_lambdatest;

import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import com.example.Jacoco_lambdatest.*;

public class AppTest {
	public static RemoteWebDriver driver;
	
	@Test
	public void testScript1() throws Exception {
		try {
	DesiredCapabilities capabilities = LambdaTest.setUp();
	String username =LambdaTest.username;
	String accessKey = LambdaTest.accessKey;
	RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities);       driver.get("https://lambdatest.github.io/sample-todo-app/");
     driver.findElement(By.name("li1")).click();
	driver.findElement(By.name("li2")).click();		      driver.findElement(By.id("sampletodotext")).clear();		driver.findElement(By.id("sampletodotext")).sendKeys("Yey, Let's add it to list");
	driver.findElement(By.id("addbutton")).click();
	driver.quit();					
	} catch (Exception e) {
		System.out.println(e.getMessage());
		}
	}
}

生成代码覆盖率报告

1. 点击“Run As”按钮并设置配置为Maven Test。

2. 或者,你可以打开命令行(cmd),导航至项目文件夹,并运行maven命令“mvn test”。

3. 运行JUnit测试将自动启动JaCoCo代理。它将在目标目录中创建一个二进制格式的报告,路径为target/jacoco.execjacoco.exec的输出不能单独解释,但其他工具如SonarQube和插件可以解释它。如前所述,jacoco:report目标将生成可读的代码覆盖率报告,格式包括HTML、CSV和XML。

4. 由于构建成功,转到目标文件夹,然后到site > jacoco文件夹。代码覆盖率报告(即index.html)位于target/site/jacoco/index.html。报告如下所示:

5. 你可以在报告中通过点击com.example.jacoco_lambdatest>LambdaTest进行微观层面的深入查看。

6. 通过点击特定函数,你将在LambdaTest.java中获得更详细的视图。

7. 在此,您会看到许多不同颜色的钻石,如绿色、黄色和红色。这些是报告中用于表示哪行代码被执行以及执行时间的规格。我们将在报告分析的下一部分中进一步了解这一点。至此,您已成功通过Jacoco Maven插件生成了代码覆盖率报告。

代码覆盖率报告分析

我们的代码覆盖率报告显示94%的指令覆盖率和100%的分支覆盖率,这是一个很好的代码覆盖分数。稍后,我们将尝试通过增加更多的测试用例来达到100%的代码覆盖率。

报告中由JaCoCo显示的38条指令指的是字节码指令而非Java代码指令。JaCoCo报告通过使用带有颜色的钻石表示分支和行背景高亮颜色来帮助您直观地分析代码覆盖率。下面是对代码覆盖率报告中看到的钻石的简要解释:

  • 红色钻石;表示在测试阶段没有分支被执行。
  • 黄色钻石:表示代码部分覆盖(即,有些分支未被执行)。
  • 绿色钻石:表示在测试期间所有分支都被执行。

同样的颜色编码适用于行覆盖的背景高亮颜色。

报告主要提供三个关键指标:

  1. 行覆盖率:这反映了基于测试调用的Java字节码指令数量所执行的代码量。
  2. 分支覆盖率:这显示了源代码中执行分支的百分比。通常涉及if/else或switch语句。
  3. 圈复杂度:通过计算覆盖代码所有可能路径所需的路径数来反映代码复杂度。它也指实现覆盖整个代码所需测试用例的数量。由于代码中没有switch或语句,圈复杂度将为一;只需一条执行路径就足以覆盖整个代码。

引入更多测试用例以提高代码覆盖率

1. 为了达到更好的代码覆盖率,需要引入更多测试来测试之前未通过测试实施覆盖的代码部分。

2. 前往src/test/java目录下的AppTest.java文件添加更多测试用例。

3. 新增至AppTest.java的测试用例如下:

 

@Test
	public void testScript2() throws Exception {
	    try {
	    DesiredCapabilities capabilities = LambdaTest.setUp();
	    String username = LambdaTest.username;
	    String accessKey = LambdaTest.accessKey;
	    RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities);		 driver.get("https://lambdatest.github.io/sample-todo-app/");		    driver.findElement(By.name("li2")).click();
	    driver.findElement(By.name("li3")).click();
	   driver.findElement(By.id("sampletodotext")).clear();	driver.findElement(By.id("sampletodotext")).sendKeys("Yes, Let's add it to list");				driver.findElement(By.id("addbutton")).click();
					driver.quit();					
		} catch (Exception e) {
				System.out.println(e.getMessage());
			    }
			}
	

	@Test
	public void testScript3() throws Exception {
		try {
	    DesiredCapabilities capabilities = LambdaTest.setUp();
	    String username = LambdaTest.username;
	    String accessKey = LambdaTest.accessKey;
	    RemoteWebDriver driver = new RemoteWebDriver(new URL("https://"+username+":"+accessKey+"@hub.lambdatest.com/wd/hub"),capabilities);			  driver.get("https://lambdatest.github.io/sample-todo-app/");		    driver.findElement(By.name("li4")).click();
	    driver.findElement(By.id("sampletodotext")).clear();	driver.findElement(By.id("sampletodotext")).sendKeys("Yes, Let's add  it!");
	  driver.findElement(By.id("addbutton")).click();
	  driver.quit();					
	} catch (Exception e) {
		System.out.println(e.getMessage());
			}
			}

4. 让我们运行Maven JaCoCo报告以发布新的覆盖率报告。

5. JaCoCo提供了一种简单易行的方法来跟踪代码覆盖率得分,通过声明最低要求。如果未满足这些要求,构建将失败;否则,构建成功。

6. 这些要求可以在POM.xml中作为规则指定。只需在POM.xml中第二个<execution>标签后指定新的执行,即指定‘check’目标。

 

<!--Third execution : used to put a check on the entire package-->
<execution>
    <id>jacoco-check</id>
    <goals>
        <goal>check</goal>
    </goals>
    <configuration>
        <rules>
            <rule>
                <element>PACKAGE</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.50</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
</execution>

7. 通过这种方式,我们将覆盖率限制在50%。这意味着在测试阶段至少应有50%的代码被覆盖。

8. 运行Maven clean verify命令,检查是否满足在jacoco:check目标中设定的规则。

9. 日志显示“所有覆盖率检查已满足”,因为我们的代码覆盖率达到94%,高于设定的最低50%。

LambdaTest Selenium Grid上的自动化测试

使用JaCoCo插件的Maven项目

在云端进行Selenium测试有助于提升浏览器覆盖率、增加测试覆盖率并加速产品上市时间。Selenium中的并行测试有助于实现上述需求。

LambdaTest Cloud Selenium Grid是一个基于云的可扩展Selenium测试平台,允许您在2000多种不同的浏览器和操作系统上运行自动化脚本。

前提条件

要使用JUnit和Selenium运行测试脚本,需设置环境。首先需要在LambdaTest上创建账户,并记下LambdaTest个人资料部分中的用户名和访问密钥。

我们将使用这个示例项目进行Java Selenium测试。

将项目导入Eclipse IDE

从GitHub下载项目zip文件junit-selenium-sample后,按照以下步骤将其导入Eclipse IDE:

1. 打开Eclipse IDE,点击“文件”菜单并选择“导入”。此时会弹出一个新的对话框。

2. 在文本框中输入Maven,然后选择“现有Maven项目”,接着点击“下一步”。

3. 在接下来的对话框中,点击“浏览”并导航至项目文件夹。同时勾选提供POM.xml文件路径的复选框,然后点击“完成”。

4. 项目将成功加载到Eclipse IDE中。

在POM.xml文件中添加依赖

1. 打开POM.xml,现在添加JUnit、Selenium和JaCoCo Maven插件的依赖。添加依赖后,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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lambdatest</groupId>
    <artifactId>lambdatest-junit-sample</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <surefire.version>2.19.1</surefire.version>
        <config.file>default</config.file>
    </properties>

    <dependencies>
        <!--JUnit dependency-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
            <scope>test</scope>
        </dependency>
        <!--Selenium dependency-->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>2.52.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.json-simple</groupId>
            <artifactId>json-simple</artifactId>
            <version>1.1.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--Apache Maven Plugins-->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
            </plugin>
            <!--JaCoCo Maven Plugin-->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.6</version>      
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                      <goals><goal>prepare-agent</goal></goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals><goal>report</goal></goals>
                   </execution>
               </executions>
          </plugin>
        </plugins>
    </build>
</project>

 
<em><a href="https://github.com/rachnaagrawal/junit-selenium-sample/blob/master/pom.xml" target="_blank" rel="nofollow">Github</a></em>

配置JUnit自动化测试的所需功能

1. 为了连接到LambdaTest Selenium自动化网格,首先需调用一个远程WebDriver。此远程驱动程序需要一些功能,如浏览器、浏览器版本、操作系统等,以构建环境。相关代码如下:

 

WebDriver driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + "@hub.lambdatest.com/wd/hub"),
DesiredCapabilities.firefox()); //A class named DesiredCapabilities is used to create an environment as a Firefox browser.

2. 在JUnit自动化测试代码中,可以通过capabilities对象自定义并传递浏览器、浏览器版本、操作系统信息等功能。

3. LambdaTest简化了这一过程,提供了一个内置的功能生成器。该生成器将根据您的输入自动生成所需功能的代码。例如,我们的配置如下:

字段

选定值

操作系统

Windows 10

浏览器

Chrome

浏览器版本

62.0

分辨率

1024×768

Selenium版本

3.13.0

4. 在能力生成器中选择上述指定配置,并将其粘贴到LambdaTestBaseTest.java中。

在所需的Java类中指定LambdaTest用户名和访问密钥

1. 在项目资源管理器中,您将看到三个Java类:

  • LambdaTestBaseTest.java(包含Java Selenium测试所需的设置)。
  • Parallelized.java(包含在LambdaTest Selenium网格上进行并行测试的Junit测试)。
  • SimpleTest.java(包含简单的单元测试)。

2. LambdaTestBaseTest.java从配置文件中获取所需数据,如所需能力、用户名和访问密钥。这些信息在src/test/resources中作为config.json提供。

3. 在config.json中指定所需能力、用户名和访问密钥。此JSON文件用于提供多配置,实现Selenium并行测试,您可以在config.json中指定多配置,然后稍后获取它们。

 

[ { "tunnelName":"LambdaTest tunnel", 
"buildName":"running Java Selenium Tests",
"testName":"Jacoco JUnit Test",
"username": "user-name",
"access_key":"access-key", 
 "operatingSystem" : "win10", 
 "browserName" : "chrome",  
 "browserVersion" : "62.0", 
 "resolution" : "1024x768" }]

使用JUnit和Selenium进行单元测试:

1. SimpleTest.java 是一个Java类,用于定义单个单元测试用例,通过JaCoCo Maven插件进行测试并执行代码覆盖率分析。

 

package com.lambdatest;

import com.lambdatest.LambdaTestBaseTest;
import org.junit.Test;
import org.openqa.selenium.By;
import static org.junit.Assert.assertEquals;

public class SimpleTest extends LambdaTestBaseTest {
    /**
     * Simple Test case annotation for JUnit Test
     * @throws Exception
     */

   @Test
    public void validateUser() throws Exception {
    	  driver.get("https://lambdatest.github.io/sample-todo-app/");
	  driver.findElement(By.name("li1")).click();
	  driver.findElement(By.name("li2")).click();
	  driver.findElement(By.id("sampletodotext")).clear();
	  driver.findElement(By.id("sampletodotext")).sendKeys("Yey, Let's add it to list");
	  driver.findElement(By.id("addbutton")).click();
    }

}

2. 这是一个简单的Selenium WebDriver测试,将打开一个示例待办事项应用程序,执行以下任务:

  • 将前两项标记为“已完成。
  • 向列表中添加一项新内容。
  • 返回添加的项。

3. 在终端中触发命令 `mvn test` 以构建并运行测试用例。

4. 现在,登录您的LambdaTest账户并进入“自动化”部分。您将在构建名称“JUnit JaCoCo测试”下找到您运行的测试。

5. 点击“JUnit JaCoCo测试”并详细审查它们。LambdaTest已录制视频,因此您还可以查看视觉内容。

通过JaCoCo Maven插件生成代码覆盖率报告:

  1. 现在,由于我们在LambdaTest Selenium Grid上运行了JUnit测试用例,应通过JaCoCo Maven插件生成代码覆盖率报告。
  2. 只需转到目标文件夹,您将找到报告的二进制格式,文件名为jacoco.exec
  3. 您可以在target/site/jacoco文件夹中查看代码覆盖率报告的HTML、CSV和XML格式,分别为index.html, jacoco.csvjacoco.xml
  4. 现在您还可以尝试提高代码覆盖率得分并分析生成的代码覆盖率报告。

结论

本文中,我们探讨了如何利用JaCoCo-Maven插件为Java项目生成代码覆盖率报告,并借助LambdaTest Selenium Grid云服务的敏捷性与可扩展性自动化测试流程。需谨记,尽管100%的代码覆盖率并不意味着测试的有效性,它仅表明测试过程中执行了多少代码。

然而,提高代码覆盖率有助于减少缺陷数量并提升软件发布质量。此外,它对构建过程的额外开销微乎其微,并允许开发团队在添加边界条件或实施防御性编程时保持一定的阈值。

Source:
https://dzone.com/articles/how-to-generate-code-coverage-report-jacoco-maven