如何使用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可以以EclEmma的名義安裝在Eclipse IDE中,只需從其市場下載EclEmma即可。
  • JaCoCo插件易於添加到各種構建類型,包括ANT、Maven和Gradle。它還可以與Jenkins、Circle CI等CI/CD工具集成。這使其在許多用例中都非常靈活。
  • JaCoCo生成的代碼覆蓋率報告是一個簡單且信息豐富的HTML文件,可在任何瀏覽器或IDE中查看。
  • JaCoCo還提供離線儀器化(即在運行任何測試之前對所有類進行儀器化)。
  • 報告的分析也相當容易,因為它是基於顏色的,並提供了確切的代碼覆蓋率百分比。

如何在Maven中設置JaCoCo插件

要在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. 在版本標籤後,我們添加execution標籤。此標籤準備屬性或執行指向JaCoCo代理,並作為VM(在此例中為JVM)參數傳遞。

3. 對於運行簡單的單元測試,設置在execution標籤中的兩個目標將足夠。最基本的是設置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目標綁定以驗證指定的規則。規則在

  • 標籤中給出。您可以靈活地指定多個規則。元素標籤:此標籤指定規則應應用於哪個元素。
  • 限制標籤:使用計數器、值、最小值等標籤來限制代碼覆蓋率百分比。可以使用類似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中,轉到文件 > 新建 > Maven項目。

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進行自動化網頁測試的報告生成,我們還將在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. 或者,您可以打開命令提示字元(Command Line),導航至專案資料夾,並運行maven命令“mvn test”。

3. 運行JUnit測試將自動啟動JaCoCo代理。它會在目標目錄中以target/jacoco.exec路徑生成一個二進制格式的報告。jacoco.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 網格

使用帶有 JaCoCo 插件的 Maven 項目

雲端上的 Selenium 測試幫助您實現更廣泛的瀏覽器覆蓋、增加測試覆蓋率並加速上市時間。Selenium 中的平行測試有助於達成上述要求。

LambdaTest 雲端 Selenium 網格是一個基於雲的可擴展 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 Plugin的依賴。添加依賴後,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自動化測試代碼中,可以自定義瀏覽器、瀏覽器版本、操作系統信息等功能,並通過功能對象傳遞。

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