JUnit 快速指南



JUnit - 概述

測試是檢查應用程式功能以確保其按要求執行的過程。單元測試在開發人員層面發揮作用;它是對單個實體(類或方法)的測試。單元測試在幫助軟體公司向客戶交付高質量產品方面發揮著關鍵作用。

單元測試可以透過兩種方式完成:手動測試和自動化測試。

手動測試 自動化測試
在沒有任何工具支援的情況下手動執行測試用例稱為手動測試。 利用工具支援並使用自動化工具執行測試用例稱為自動化測試。
耗時且繁瑣 - 由於測試用例由人力資源執行,因此速度非常慢且繁瑣。 快速 - 自動化執行測試用例的速度比人力資源快得多。
人力資源投入巨大 - 由於需要手動執行測試用例,因此手動測試需要更多測試人員。 人力資源投入較少 - 測試用例使用自動化工具執行,因此自動化測試需要較少的測試人員。
可靠性較低 - 手動測試的可靠性較低,因為它必須考慮人為錯誤。 可靠性更高 - 自動化測試精確且可靠。
不可程式設計 - 無法進行程式設計來編寫複雜的測試以獲取隱藏資訊。 可程式設計 - 測試人員可以編寫複雜的測試來獲取隱藏資訊。

什麼是 JUnit?

JUnit 是 Java 程式語言的單元測試框架。它在測試驅動開發中扮演著至關重要的角色,並且是統稱為 xUnit 的單元測試框架家族的一員。

JUnit 推崇“先測試後編碼”的理念,強調首先為一段程式碼設定測試資料,然後進行測試,再進行實現。這種方法類似於“測試一點,編碼一點,測試一點,編碼一點”。它提高了程式設計師的生產力和程式程式碼的穩定性,從而減少了程式設計師的壓力和除錯時間。

JUnit 的特點

  • JUnit 是一個開源框架,用於編寫和執行測試。

  • 提供註解來標識測試方法。

  • 提供斷言來測試預期結果。

  • 提供測試執行器來執行測試。

  • JUnit 測試允許您更快地編寫程式碼,從而提高質量。

  • JUnit 簡潔優雅。它不復雜且耗時較少。

  • JUnit 測試可以自動執行,它們檢查自己的結果並提供即時反饋。無需手動檢查測試結果報告。

  • JUnit 測試可以組織成包含測試用例甚至其他測試套件的測試套件。

  • JUnit 在進度條中顯示測試進度,如果測試執行順利,則為綠色;如果測試失敗,則變為紅色。

什麼是單元測試用例?

單元測試用例是程式碼的一部分,它確保另一部分程式碼(方法)按預期工作。為了快速獲得所需結果,需要一個測試框架。JUnit 是 Java 程式語言的理想單元測試框架。

正式編寫的單元測試用例的特點是已知的輸入和預期的輸出,這些在測試執行之前就已確定。已知的輸入應該測試前提條件,而預期的輸出應該測試後置條件。

每個需求至少必須有兩個單元測試用例:一個正測試和一個負測試。如果一個需求有子需求,則每個子需求必須至少有兩個測試用例作為正測試和負測試。

JUnit - 環境搭建

本地環境搭建

JUnit 是一個 Java 框架,因此首要要求是在您的機器上安裝 JDK。

系統要求

JDK 1.5 或更高版本。
記憶體 無最低要求。
磁碟空間 無最低要求。
作業系統 無最低要求。

步驟 1:驗證您的機器上是否安裝了 Java

首先,開啟控制檯並根據您正在使用的作業系統執行 java 命令。

作業系統 任務 命令
Windows 開啟命令控制檯 c:\> java -version
Linux 開啟命令終端 $ java -version
Mac 開啟終端 machine:~ joseph$ java -version

讓我們驗證所有作業系統的輸出:

作業系統 輸出
Windows

java version "1.8.0_101"

Java(TM) SE Runtime Environment (build 1.8.0_101)

Linux

java version "1.8.0_101"

Java(TM) SE Runtime Environment (build 1.8.0_101)

Mac

java version "1.8.0_101"

Java(TM) SE Runtime Environment (build 1.8.0_101)

如果您的系統上未安裝 Java,請從以下連結下載 Java 軟體開發工具包 (SDK) https://www.oracle.com。在本教程中,我們假設已安裝 Java 1.8.0_101 版本。

步驟 2:設定 JAVA 環境

設定JAVA_HOME環境變數以指向 Java 安裝在您機器上的基目錄位置。例如:

作業系統 輸出
Windows 將環境變數 JAVA_HOME 設定為 C:\Program Files\Java\jdk1.8.0_101
Linux export JAVA_HOME = /usr/local/java-current
Mac export JAVA_HOME = /Library/Java/Home

將 Java 編譯器位置新增到系統路徑。

作業系統 輸出
Windows 在系統變數Path的末尾附加字串C:\Program Files\Java\jdk1.8.0_101\bin
Linux export PATH = $PATH:$JAVA_HOME/bin/
Mac 不需要

使用上面解釋的命令java -version驗證 Java 安裝。

步驟 3:下載 JUnit 歸檔檔案

http://www.junit.org下載最新版本的 JUnit jar 檔案。在撰寫本教程時,我們已下載 Junit-4.12.jar 並將其複製到 C:\>JUnit 資料夾。

作業系統 歸檔檔名
Windows junit4.12.jar
Linux junit4.12.jar
Mac junit4.12.jar

步驟 4:設定 JUnit 環境

設定JUNIT_HOME環境變數以指向 JUNIT jar 儲存在您機器上的基目錄位置。假設我們將 junit4.12.jar 儲存在 JUNIT 資料夾中。

序號 作業系統和說明
1

Windows

將環境變數 JUNIT_HOME 設定為 C:\JUNIT

2

Linux

export JUNIT_HOME = /usr/local/JUNIT

3

Mac

export JUNIT_HOME = /Library/JUNIT

步驟 5:設定 CLASSPATH 變數

設定CLASSPATH環境變數以指向 JUNIT jar 位置。

序號 作業系統和說明
1

Windows

將環境變數 CLASSPATH 設定為 %CLASSPATH%;%JUNIT_HOME%\junit4.12.jar;.;

2

Linux

export CLASSPATH = $CLASSPATH:$JUNIT_HOME/junit4.12.jar:.

3

Mac

export CLASSPATH = $CLASSPATH:$JUNIT_HOME/junit4.12.jar:.

步驟 6:測試 JUnit 設定

C:\>JUNIT_WORKSPACE中建立一個名為 TestJunit 的 Java 類檔案。

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class TestJunit {
   @Test
	
   public void testAdd() {
      String str = "Junit is working fine";
      assertEquals("Junit is working fine",str);
   }
}

C:\>JUNIT_WORKSPACE中建立一個名為 TestRunner 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

步驟 7:驗證結果

使用javac編譯器編譯類,如下所示:

C:\JUNIT_WORKSPACE>javac TestJunit.java TestRunner.java

現在執行 Test Runner 以檢視結果,如下所示:

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

true

JUnit - 測試框架

JUnit 是開發人員用來在 Java 中實現單元測試並加快程式設計速度和提高程式碼質量的迴歸測試框架。JUnit 框架可以輕鬆地與以下任何一個整合:

  • Eclipse
  • Ant
  • Maven

JUnit 測試框架的特點

JUnit 測試框架提供以下重要功能:

  • 夾具
  • 測試套件
  • 測試執行器
  • JUnit 類

夾具

夾具是一組物件的固定狀態,用作執行測試的基線。測試夾具的目的是確保有一個眾所周知的固定環境來執行測試,以便結果可重複。它包括:

  • setUp() 方法,在每次測試呼叫之前執行。
  • tearDown() 方法,在每次測試方法之後執行。

讓我們檢查一個例子:

import junit.framework.*;

public class JavaTest extends TestCase {
   protected int value1, value2;
   
   // assigning the values
   protected void setUp(){
      value1 = 3;
      value2 = 3;
   }

   // test method to add two values
   public void testAdd(){
      double result = value1 + value2;
      assertTrue(result == 6);
   }
}

測試套件

測試套件捆綁了一些單元測試用例並一起執行它們。在 JUnit 中,@RunWith 和 @Suite 註解都用於執行套件測試。下面是一個使用 TestJunit1 和 TestJunit2 測試類的示例。

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

//JUnit Suite Test
@RunWith(Suite.class)

@Suite.SuiteClasses({ 
   TestJunit1.class ,TestJunit2.class
})

public class JunitTestSuite {
}
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit1 {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
   
   @Test
   public void testPrintMessage() {	
      System.out.println("Inside testPrintMessage()");    
      assertEquals(message, messageUtil.printMessage());     
   }
}
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit2 {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
 
   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
}

測試執行器

測試執行器用於執行測試用例。這是一個假設測試類TestJunit已經存在的示例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}

JUnit 類

JUnit 類是在編寫和測試 JUnit 中使用的重要類。一些重要的類包括:

  • Assert - 包含一組斷言方法。

  • TestCase - 包含一個測試用例,該用例定義了執行多個測試的夾具。

  • TestResult - 包含用於收集執行測試用例結果的方法。

JUnit - 基本用法

現在讓我們來看一個基本的例子來演示使用 JUnit 的逐步過程。

建立類

建立一個要測試的 Java 類,例如,在C:\>JUNIT_WORKSPACE中建立 MessageUtil.java

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
	
   public MessageUtil(String message){
      this.message = message;
   }
      
   // prints the message
   public String printMessage(){
      System.out.println(message);
      return message;
   }   
}  

建立測試用例類

  • 建立一個 Java 測試類,例如,TestJunit.java。
  • 向您的測試類新增一個測試方法 testPrintMessage()。
  • 向方法 testPrintMessage() 新增一個註解 @Test。
  • 實現測試條件並使用 JUnit 的 assertEquals API 檢查條件。

C:\>JUNIT_WORKSPACE中建立一個名為 TestJunit.java 的 Java 類檔案。

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class TestJunit {
	
   String message = "Hello World";	
   MessageUtil messageUtil = new MessageUtil(message);

   @Test
   public void testPrintMessage() {
      assertEquals(message,messageUtil.printMessage());
   }
}

建立測試執行器類

  • 建立一個 TestRunner Java 類。
  • 使用 JUnit 的 JUnitCore 類的 runClasses 方法執行上面建立的測試類的測試用例。
  • 獲取 Result 物件中執行的測試用例的結果。
  • 使用 Result 物件的 getFailures() 方法獲取失敗。
  • 使用 Result 物件的 wasSuccessful() 方法獲取成功結果。

C:\>JUNIT_WORKSPACE中建立一個名為 TestRunner.java 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯 MessageUtil、測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

Hello World
true

現在更新C:\>JUNIT_WORKSPACE中的 TestJunit,以便測試失敗。更改訊息字串。

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class TestJunit {
	
   String message = "Hello World";	
   MessageUtil messageUtil = new MessageUtil(message);

   @Test
   public void testPrintMessage() {
      message = "New Word";
      assertEquals(message,messageUtil.printMessage());
   }
}

讓我們保持其餘類不變,並嘗試執行相同的 Test Runner。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {

   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

Hello World
testPrintMessage(TestJunit): expected:<[New Wor]d> but was:<[Hello Worl]d>
false

JUnit - API

JUnit 中最重要的包是junit.framework,它包含所有核心類。一些重要的類如下:

序號 類名 功能
1 Assert 一組斷言方法。
2 TestCase 測試用例定義了執行多個測試的夾具。
3 TestResult(測試結果) TestResult 收集執行測試用例的結果。
4 TestSuite(測試套件) TestSuite 是測試的組合。

Assert 類(斷言類)

以下是 **org.junit.Assert** 類的宣告:

public class Assert extends java.lang.Object

此類提供了一組用於編寫測試的有用斷言方法。只有失敗的斷言才會被記錄。Assert 類的一些重要方法如下:

序號 方法和描述
1

void assertEquals(boolean expected, boolean actual)

檢查兩個基本型別/物件是否相等。

2

void assertFalse(boolean condition)

檢查條件是否為假。

3

void assertNotNull(Object object)

檢查物件是否不為空。

4

void assertNull(Object object)

檢查物件是否為空。

5

void assertTrue(boolean condition)

檢查條件是否為真。

6

void fail()

測試失敗,無訊息。

讓我們在示例中使用上面提到的某些方法。在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 TestJunit1.java 的 Java 類檔案。

import org.junit.Test;
import static org.junit.Assert.*;

public class TestJunit1 {
   @Test
   public void testAdd() {
      //test data
      int num = 5;
      String temp = null;
      String str = "Junit is working fine";

      //check for equality
      assertEquals("Junit is working fine", str);
      
      //check for false condition
      assertFalse(num > 6);

      //check for not null value
      assertNotNull(temp);
   }
}

接下來,在 C:\>JUNIT_WORKSPACE 中建立一個名為 **TestRunner1.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner1 {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit1.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac TestJunit1.java TestRunner1.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner1

驗證輸出。

true

TestCase 類(測試用例類)

以下是 **org.junit.TestCase** 類的宣告:

public abstract class TestCase extends Assert implements Test

測試用例定義了執行多個測試的夾具。**TestCase** 類的一些重要方法如下:

序號 方法和描述
1

int countTestCases()

計算 run(TestResult result) 執行的測試用例數量。

2

TestResult createResult()

建立一個預設的 TestResult 物件。

3

String getName()

獲取 TestCase 的名稱。

4

TestResult run()

一個方便的方法來執行此測試,使用預設的 TestResult 物件收集結果。

5

void run(TestResult result)

執行測試用例並將結果收集到 TestResult 中。

6

void setName(String name)

設定 TestCase 的名稱。

7

void setUp()

設定夾具,例如,開啟網路連線。

8

void tearDown()

拆除夾具,例如,關閉網路連線。

9

String toString()

返回測試用例的字串表示形式。

讓我們在示例中使用上面提到的某些方法。在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit2.java** 的 Java 類檔案。

import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;

public class TestJunit2 extends TestCase  {
   protected double fValue1;
   protected double fValue2;
   
   @Before 
   public void setUp() {
      fValue1 = 2.0;
      fValue2 = 3.0;
   }
	
   @Test
   public void testAdd() {
      //count the number of test cases
      System.out.println("No of Test Case = "+ this.countTestCases());
		
      //test getName 
      String name = this.getName();
      System.out.println("Test Case Name = "+ name);

      //test setName
      this.setName("testNewAdd");
      String newName = this.getName();
      System.out.println("Updated Test Case Name = "+ newName);
   }
	
   //tearDown used to close the connection or clean up activities
   public void tearDown(  ) {
   }
}

接下來,在 C:\>JUNIT_WORKSPACE 中建立一個名為 **TestRunner2.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner2 {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit2.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
} 

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac TestJunit2.java TestRunner2.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner2

驗證輸出。

No of Test Case = 1
Test Case Name = testAdd
Updated Test Case Name = testNewAdd
true

TestResult 類(測試結果類)

以下是 **org.junit.TestResult** 類的宣告:

public class TestResult extends Object

TestResult 收集執行測試用例的結果。它是收集引數模式的一個例項。測試框架區分失敗和錯誤。失敗是預期的,並透過斷言進行檢查。錯誤是意外的問題,例如 ArrayIndexOutOfBoundsException。**TestResult** 類的一些重要方法如下:

序號 方法和描述
1

void addError(Test test, Throwable t)

向錯誤列表中新增錯誤。

2

void addFailure(Test test, AssertionFailedError t)

向失敗列表中新增失敗。

3

void endTest(Test test)

通知結果測試已完成。

4

int errorCount()

獲取檢測到的錯誤數量。

5

Enumeration errors()

返回錯誤的列舉。

6

int failureCount()

獲取檢測到的失敗數量。

7

void run(TestCase test)

執行 TestCase。

8

int runCount()

獲取已執行測試的數量。

9

void startTest(Test test)

通知結果將要啟動測試。

10

void stop()

標記測試執行應該停止。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit3.java** 的 Java 類檔案。

import org.junit.Test;
import junit.framework.AssertionFailedError;
import junit.framework.TestResult;

public class TestJunit3 extends TestResult {
   // add the error
   public synchronized void addError(Test test, Throwable t) {
      super.addError((junit.framework.Test) test, t);
   }

   // add the failure
   public synchronized void addFailure(Test test, AssertionFailedError t) {
      super.addFailure((junit.framework.Test) test, t);
   }
	
   @Test
   public void testAdd() {
      // add any test
   }
   
   // Marks that the test run should stop.
   public synchronized void stop() {
      //stop the test here
   }
}

接下來,在 C:\>JUNIT_WORKSPACE 中建立一個名為 **TestRunner3.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner3 {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit3.class);

      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac TestJunit3.java TestRunner3.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner3

驗證輸出。

true

TestSuite 類(測試套件類)

以下是 **org.junit.TestSuite** 類的宣告

public class TestSuite extends Object implements Test

TestSuite 是測試的組合。它執行一系列測試用例。**TestSuite** 類的一些重要方法如下:

序號 方法和描述
1

void addTest(Test test)

向套件中新增測試。

2

void addTestSuite(Class testClass)

將給定類中的測試新增到套件中。

3

int countTestCases()

計算此測試將執行的測試用例數量。

4

String getName()

返回套件的名稱。

5

void run(TestResult result)

執行測試並將結果收集到 TestResult 中。

6

void setName(String name)

設定套件的名稱。

7

Test testAt(int index)

返回給定索引處的測試。

8

int testCount()

返回此套件中的測試數量。

9

static Test warning(String message)

返回一個將失敗並記錄警告訊息的測試。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **JunitTestSuite.java** 的 Java 類檔案來建立測試套件。

import junit.framework.*;

public class JunitTestSuite {
   public static void main(String[] a) {
      // add the test's in the suite
      TestSuite suite = new TestSuite(TestJunit1.class, TestJunit2.class, TestJunit3.class );
      TestResult result = new TestResult();
      suite.run(result);
      System.out.println("Number of test cases = " + result.runCount());
   }
}

使用 javac 編譯測試套件類。

C:\JUNIT_WORKSPACE>javac JunitTestSuite.java 

現在執行測試套件。

C:\JUNIT_WORKSPACE>java JunitTestSuite

驗證輸出。

No of Test Case = 1
Test Case Name = testAdd
Updated Test Case Name = testNewAdd
Number of test cases = 3

JUnit - 編寫測試

在這裡,我們將看到一個使用 POJO 類、業務邏輯類和測試類的 JUnit 測試完整示例,測試執行器將執行該示例。

在 **C:\>JUNIT_WORKSPACE** 中建立 **EmployeeDetails.java**,這是一個 POJO 類。

public class EmployeeDetails {

   private String name;
   private double monthlySalary;
   private int age;
   
   /**
   * @return the name
   */
	
   public String getName() {
      return name;
   }
	
   /**
   * @param name the name to set
   */
	
   public void setName(String name) {
      this.name = name;
   }
	
   /**
   * @return the monthlySalary
   */
	
   public double getMonthlySalary() {
      return monthlySalary;
   }
	
   /**
   * @param monthlySalary the monthlySalary to set
   */
	
   public void setMonthlySalary(double monthlySalary) {
      this.monthlySalary = monthlySalary;
   }
	
   /**
   * @return the age
   */
   public int getAge() {
      return age;
   }
	
   /**
   * @param age the age to set
   */
   public void setAge(int age) {
      this.age = age;
   }
}

**EmployeeDetails** 類用於:

  • 獲取/設定員工姓名。
  • 獲取/設定員工月薪。
  • 獲取/設定員工年齡。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **EmpBusinessLogic.java** 的檔案,其中包含業務邏輯。

public class EmpBusinessLogic {
   // Calculate the yearly salary of employee
   public double calculateYearlySalary(EmployeeDetails employeeDetails) {
      double yearlySalary = 0;
      yearlySalary = employeeDetails.getMonthlySalary() * 12;
      return yearlySalary;
   }
	
   // Calculate the appraisal amount of employee
   public double calculateAppraisal(EmployeeDetails employeeDetails) {
      double appraisal = 0;
		
      if(employeeDetails.getMonthlySalary() < 10000){
         appraisal = 500;
      }else{
         appraisal = 1000;
      }
		
      return appraisal;
   }
}

**EmpBusinessLogic** 類用於計算:

  • 員工的年薪。
  • 員工的考核金額。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestEmployeeDetails.java** 的檔案,其中包含要測試的測試用例。

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class TestEmployeeDetails {
   EmpBusinessLogic empBusinessLogic = new EmpBusinessLogic();
   EmployeeDetails employee = new EmployeeDetails();

   //test to check appraisal
   @Test
   public void testCalculateAppriasal() {
      employee.setName("Rajeev");
      employee.setAge(25);
      employee.setMonthlySalary(8000);
		
      double appraisal = empBusinessLogic.calculateAppraisal(employee);
      assertEquals(500, appraisal, 0.0);
   }

   // test to check yearly salary
   @Test
   public void testCalculateYearlySalary() {
      employee.setName("Rajeev");
      employee.setAge(25);
      employee.setMonthlySalary(8000);
		
      double salary = empBusinessLogic.calculateYearlySalary(employee);
      assertEquals(96000, salary, 0.0);
   }
}

**TestEmployeeDetails** 類用於測試 **EmpBusinessLogic** 類的函式。它

  • 測試員工的年薪。
  • 測試員工的考核金額。

接下來,在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestEmployeeDetails.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
} 

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac EmployeeDetails.java 
EmpBusinessLogic.java TestEmployeeDetails.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

true

JUnit - 使用斷言

斷言

所有斷言都在 Assert 類中。

public class Assert extends java.lang.Object

此類提供了一組斷言方法,用於編寫測試。只有失敗的斷言才會被記錄。Assert 類的一些重要方法如下:

序號 方法和描述
1

void assertEquals(boolean expected, boolean actual)

檢查兩個基本型別/物件是否相等。

2

void assertTrue(boolean condition)

檢查條件是否為真。

3

void assertFalse(boolean condition)

檢查條件是否為假。

4

void assertNotNull(Object object)

檢查物件是否不為空。

5

void assertNull(Object object)

檢查物件是否為空。

6

void assertSame(object1, object2)

assertSame() 方法測試兩個物件引用是否指向同一個物件。

7

void assertNotSame(object1, object2)

assertNotSame() 方法測試兩個物件引用是否不指向同一個物件。

8

void assertArrayEquals(expectedArray, resultArray);

assertArrayEquals() 方法將測試兩個陣列是否彼此相等。

讓我們在示例中使用上面提到的某些方法。在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestAssertions.java** 的 Java 類檔案。

import org.junit.Test;
import static org.junit.Assert.*;

public class TestAssertions {

   @Test
   public void testAssertions() {
      //test data
      String str1 = new String ("abc");
      String str2 = new String ("abc");
      String str3 = null;
      String str4 = "abc";
      String str5 = "abc";
		
      int val1 = 5;
      int val2 = 6;

      String[] expectedArray = {"one", "two", "three"};
      String[] resultArray =  {"one", "two", "three"};

      //Check that two objects are equal
      assertEquals(str1, str2);

      //Check that a condition is true
      assertTrue (val1 < val2);

      //Check that a condition is false
      assertFalse(val1 > val2);

      //Check that an object isn't null
      assertNotNull(str1);

      //Check that an object is null
      assertNull(str3);

      //Check if two object references point to the same object
      assertSame(str4,str5);

      //Check if two object references not point to the same object
      assertNotSame(str1,str3);

      //Check whether two arrays are equal to each other.
      assertArrayEquals(expectedArray, resultArray);
   }
}

接下來,在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner2 {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestAssertions.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
} 

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac TestAssertions.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

true

註解

註解就像可以新增到程式碼中的元標記,並將它們應用於方法或類中。JUnit 中的這些註解提供了有關測試方法的以下資訊:

  • 哪些方法將在測試方法之前和之後執行。
  • 哪些方法在所有方法之前和之後執行,以及。
  • 在執行期間將忽略哪些方法或類。

下表提供了 JUnit 中註解及其含義的列表:

序號 註解和描述
1

@Test

Test 註解告訴 JUnit,附加到它的 public void 方法可以作為測試用例執行。

2

@Before

幾個測試需要在執行之前建立類似的物件。用 @Before 註解 public void 方法會導致在每個 Test 方法之前執行該方法。

3

@After

如果在 Before 方法中分配外部資源,則需要在測試執行後釋放它們。用 @After 註解 public void 方法會導致在 Test 方法之後執行該方法。

4

@BeforeClass

用 @BeforeClass 註解 public static void 方法會導致在類中任何測試方法之前執行一次。

5

@AfterClass

這將在所有測試完成後執行該方法。這可用於執行清理活動。

6

@Ignore

Ignore 註解用於忽略測試,並且該測試將不會執行。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **JunitAnnotation.java** 的 Java 類檔案來測試註解。

import org.junit.After;
import org.junit.AfterClass;

import org.junit.Before;
import org.junit.BeforeClass;

import org.junit.Ignore;
import org.junit.Test;

public class JunitAnnotation {
	
   //execute before class
   @BeforeClass
   public static void beforeClass() {
      System.out.println("in before class");
   }

   //execute after class
   @AfterClass
   public static void  afterClass() {
      System.out.println("in after class");
   }

   //execute before test
   @Before
   public void before() {
      System.out.println("in before");
   }
	
   //execute after test
   @After
   public void after() {
      System.out.println("in after");
   }
	
   //test case
   @Test
   public void test() {
      System.out.println("in test");
   }
	
   //test case ignore and will not execute
   @Ignore
   public void ignoreTest() {
      System.out.println("in ignore test");
   }
}

接下來,在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行註解。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(JunitAnnotation.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
} 

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac JunitAnnotation.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

in before class
in before
in test
in after
in after class
true

JUnit - 執行流程

本章解釋了 JUnit 中方法的執行過程,該過程定義了呼叫的方法的順序。下面討論的是 JUnit 測試 API 方法的執行過程以及示例。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 ExecutionProcedureJunit.java 的 Java 類檔案來測試註解。

import org.junit.After;
import org.junit.AfterClass;

import org.junit.Before;
import org.junit.BeforeClass;

import org.junit.Ignore;
import org.junit.Test;

public class ExecutionProcedureJunit {
	
   //execute only once, in the starting 
   @BeforeClass
   public static void beforeClass() {
      System.out.println("in before class");
   }

   //execute only once, in the end
   @AfterClass
   public static void  afterClass() {
      System.out.println("in after class");
   }

   //execute for each test, before executing test
   @Before
   public void before() {
      System.out.println("in before");
   }
	
   //execute for each test, after executing test
   @After
   public void after() {
      System.out.println("in after");
   }
	
   //test case 1
   @Test
   public void testCase1() {
      System.out.println("in test case 1");
   }

   //test case 2
   @Test
   public void testCase2() {
      System.out.println("in test case 2");
   }
}

接下來,在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行註解。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(ExecutionProcedureJunit.class);

      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
} 

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac ExecutionProcedureJunit.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

in before class
in before
in test case 1
in after
in before
in test case 2
in after
in after class

請參閱上面的輸出。執行過程如下:

  • 首先,beforeClass() 方法只執行一次。
  • afterClass() 方法只執行一次。
  • before() 方法為每個測試用例執行,但在執行測試用例之前。
  • after() 方法為每個測試用例執行,但在執行測試用例之後。
  • 在 before() 和 after() 之間,每個測試用例都會執行。

JUnit - 執行測試

測試用例使用 **JUnitCore** 類執行。JUnitCore 是用於執行測試的 facade。它支援執行 JUnit 4 測試、JUnit 3.8.x 測試以及混合測試。要從命令列執行測試,請執行 java org.junit.runner.JUnitCore 。對於一次性測試執行,請使用靜態方法 runClasses(Class[])。

以下是 **org.junit.runner.JUnitCore** 類的宣告

public class JUnitCore extends java.lang.Object

在這裡,我們將看到如何藉助 JUnitCore 執行測試。

建立類

建立一個要測試的 Java 類,例如 **MessageUtil.java**,在 **C:\>JUNIT_WORKSPACE** 中。

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message;
   }
      
   // prints the message
   public String printMessage(){
      System.out.println(message);
      return message;
   }   
	
}  

建立測試用例類

  • 建立一個 Java 測試類,例如,TestJunit.java。

  • 向您的測試類新增一個測試方法 testPrintMessage()。

  • 向 testPrintMessage() 方法添加註解 @Test。

  • 實現測試條件並使用 JUnit 的 assertEquals API 檢查條件。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit.java** 的 Java 類檔案。

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class TestJunit {
	
   String message = "Hello World";	
   MessageUtil messageUtil = new MessageUtil(message);

   @Test
   public void testPrintMessage() {
      assertEquals(message,messageUtil.printMessage());
   }
}

建立測試執行器類

現在在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。它匯入 JUnitCore 類並使用 runClasses() 方法,該方法將測試類名作為其引數。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

Hello World
true

JUnit - 套件測試

**測試套件** 用於捆綁一些單元測試用例並一起執行它們。在 JUnit 中,@RunWith 和 @Suite 註解都用於執行套件測試。本章以一個包含兩個測試類 TestJunit1 和 TestJunit2 的示例為例,它們使用測試套件一起執行。

建立類

在 **C:\>JUNIT_WORKSPACE** 中建立一個要測試的 Java 類,例如 **MessageUtil.java**。

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message; 
   }

   // prints the message
   public String printMessage(){
      System.out.println(message);
      return message;
   }   

   // add "Hi!" to the message
   public String salutationMessage(){
      message = "Hi!" + message;
      System.out.println(message);
      return message;
   }   
}  	

建立測試用例類

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit1.java** 的 Java 類檔案。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit1 {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
   
   @Test
   public void testPrintMessage() {	
      System.out.println("Inside testPrintMessage()");    
      assertEquals(message, messageUtil.printMessage());     
   }
}

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit2.java** 的 Java 類檔案。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit2 {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
 
   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
}

建立測試套件類

  • 建立一個 Java 類。
  • 使用 @RunWith(Suite.class) 註解附加到該類。
  • 使用 @Suite.SuiteClasses 註解新增對 JUnit 測試類的引用。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestSuite.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)

@Suite.SuiteClasses({
   TestJunit1.class,
   TestJunit2.class
})

public class JunitTestSuite {   
}  	

建立測試執行器類

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(JunitTestSuite.class);

      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯所有 Java 類。

C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit1.java 
TestJunit2.java JunitTestSuite.java TestRunner.java

現在執行 Test Runner,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

Inside testPrintMessage()
Robert
Inside testSalutationMessage()
Hi Robert
true

JUnit - 忽略測試

有時我們的程式碼在執行測試用例時並非完全準備好,導致測試用例失敗。在這種情況下,@Ignore 註解很有幫助。

  • 用 @Ignore 註解的測試方法不會被執行。

  • 如果一個測試類用 @Ignore 註解,那麼它的所有測試方法都不會被執行。

現在讓我們看看 @Ignore 的實際應用。

建立類

在 **C:\>JUNIT_WORKSPACE** 中建立一個要測試的 Java 類,例如 **MessageUtil.java**。

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message; 
   }

   // prints the message
   public String printMessage(){
      System.out.println(message);
      return message;
   }   

   // add "Hi!" to the message
   public String salutationMessage(){
      message = "Hi!" + message;
      System.out.println(message);
      return message;
   }   
	
}  

建立測試用例類

  • 建立一個 Java 測試類,例如,TestJunit.java。

  • 在你的測試類中新增一個測試方法 testPrintMessage() 或 testSalutationMessage()。

  • 在 testPrintMessage() 方法中新增 @Ignore 註解。

在 C:\JUNIT_WORKSPACE 中建立一個名為 TestJunit.java 的 Java 類檔案。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
   
   @Ignore
   @Test
   public void testPrintMessage() {
      System.out.println("Inside testPrintMessage()");
      message = "Robert";
      assertEquals(message,messageUtil.printMessage());
   }

   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
	
}

建立測試執行器類

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);

      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯 MessageUtil、測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java

現在執行測試執行器,它不會執行在提供的測試用例類中定義的 testPrintMessage() 測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。testPrintMessage() 測試用例未被測試。

Inside testSalutationMessage()
Hi!Robert
true

現在,更新 C:\JUNIT_WORKSPACE 中的 TestJunit 以忽略所有測試用例。在類級別新增 @Ignore。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

@Ignore
public class TestJunit {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
     
   @Test
   public void testPrintMessage() {
      System.out.println("Inside testPrintMessage()");
      message = "Robert";
      assertEquals(message,messageUtil.printMessage());
   }

   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
	
}

使用 javac 編譯測試用例。

C:\JUNIT_WORKSPACE>javac TestJunit.java

保持你的測試執行器不變,如下所示:

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}

現在執行測試執行器,它不會執行在提供的測試用例類中定義的任何測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。沒有任何測試用例被測試。

true

JUnit - 時間測試

JUnit 提供了一個方便的超時選項。如果測試用例花費的時間超過指定的毫秒數,JUnit 將自動將其標記為失敗。timeout 引數與 @Test 註解一起使用。讓我們看看 @Test(timeout) 的實際應用。

建立類

在 **C:\>JUNIT_WORKSPACE** 中建立一個要測試的 Java 類,例如 **MessageUtil.java**。

在 printMessage() 方法內新增一個無限 while 迴圈。

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message; 
   }

   // prints the message
   public void printMessage(){
      System.out.println(message);
      while(true);
   }   

   // add "Hi!" to the message
   public String salutationMessage(){
      message = "Hi!" + message;
      System.out.println(message);
      return message;
   }   
}  	

建立測試用例類

建立一個 Java 測試類,例如 TestJunit.java。為 testPrintMessage() 測試用例新增 1000 的超時時間。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit.java** 的 Java 類檔案。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
   
   @Test(timeout = 1000)
   public void testPrintMessage() {	
      System.out.println("Inside testPrintMessage()");     
      messageUtil.printMessage();     
   }

   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
}

建立測試執行器類

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯 MessageUtil、測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java

現在執行測試執行器,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。testPrintMessage() 測試用例將標記單元測試失敗。

Inside testPrintMessage()
Robert
Inside testSalutationMessage()
Hi!Robert
testPrintMessage(TestJunit): test timed out after 1000 milliseconds
false

JUnit - 異常測試

JUnit 提供了跟蹤程式碼異常處理的選項。你可以測試程式碼是否丟擲了所需的異常。expected 引數與 @Test 註解一起使用。讓我們看看 @Test(expected) 的實際應用。

建立類

建立一個要測試的 Java 類,例如 MessageUtil.java,位於 C:\JUNIT_WORKSPACE。

在 printMessage() 方法中新增一個錯誤條件。

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message; 
   }

   // prints the message
   public void printMessage(){
      System.out.println(message);
      int a = 0;
      int b = 1/a;
   }   

   // add "Hi!" to the message
   public String salutationMessage(){
      message = "Hi!" + message;
      System.out.println(message);
      return message;
   }   
}  	

建立測試用例類

建立一個名為 TestJunit.java 的 Java 測試類。在 testPrintMessage() 測試用例中新增預期的異常 ArithmeticException。

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestJunit.java** 的 Java 類檔案。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestJunit {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
   
   @Test(expected = ArithmeticException.class)
   public void testPrintMessage() {	
      System.out.println("Inside testPrintMessage()");     
      messageUtil.printMessage();     
   }

   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
}

建立測試執行器類

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
		
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯 MessageUtil、測試用例和測試執行器類。

C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java

現在執行測試執行器,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。testPrintMessage() 測試用例將透過。

Inside testPrintMessage()
Robert
Inside testSalutationMessage()
Hi!Robert
true

JUnit - 引數化測試

JUnit 4 引入了一項名為 引數化測試 的新功能。引數化測試允許開發人員使用不同的值反覆執行相同的測試。建立引數化測試需要遵循五個步驟。

  • 使用 @RunWith(Parameterized.class) 註解測試類。

  • 建立一個用 @Parameters 註解的公共靜態方法,該方法返回一個物件集合(作為陣列)作為測試資料集。

  • 建立一個公共建構函式,它接收相當於測試資料的一“行”。

  • 為測試資料的每一“列”建立一個例項變數。

  • 使用例項變數作為測試資料的來源建立測試用例。

對於資料的每一行,測試用例都將被呼叫一次。讓我們看看引數化測試的實際應用。

建立類

建立一個要測試的 Java 類,例如 PrimeNumberChecker.java,位於 C:\JUNIT_WORKSPACE。

public class PrimeNumberChecker {
   public Boolean validate(final Integer primeNumber) {
      for (int i = 2; i < (primeNumber / 2); i++) {
         if (primeNumber % i == 0) {
            return false;
         }
      }
      return true;
   }
}

建立引數化測試用例類

建立一個 Java 測試類,例如 PrimeNumberCheckerTest.java。在 C:\JUNIT_WORKSPACE 中建立一個名為 PrimeNumberCheckerTest.java 的 Java 類檔案。

import java.util.Arrays;
import java.util.Collection;
 
import org.junit.Test;
import org.junit.Before;

import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;

@RunWith(Parameterized.class)
public class PrimeNumberCheckerTest {
   private Integer inputNumber;
   private Boolean expectedResult;
   private PrimeNumberChecker primeNumberChecker;

   @Before
   public void initialize() {
      primeNumberChecker = new PrimeNumberChecker();
   }

   // Each parameter should be placed as an argument here
   // Every time runner triggers, it will pass the arguments
   // from parameters we defined in primeNumbers() method
	
   public PrimeNumberCheckerTest(Integer inputNumber, Boolean expectedResult) {
      this.inputNumber = inputNumber;
      this.expectedResult = expectedResult;
   }

   @Parameterized.Parameters
   public static Collection primeNumbers() {
      return Arrays.asList(new Object[][] {
         { 2, true },
         { 6, false },
         { 19, true },
         { 22, false },
         { 23, true }
      });
   }

   // This test will run 4 times since we have 5 parameters defined
   @Test
   public void testPrimeNumberChecker() {
      System.out.println("Parameterized Number is : " + inputNumber);
      assertEquals(expectedResult, 
      primeNumberChecker.validate(inputNumber));
   }
}

建立測試執行器類

在 **C:\>JUNIT_WORKSPACE** 中建立一個名為 **TestRunner.java** 的 Java 類檔案來執行測試用例。

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(PrimeNumberCheckerTest.class);

      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
		
      System.out.println(result.wasSuccessful());
   }
}  	

使用 javac 編譯 PrimeNumberChecker、PrimeNumberCheckerTest 和測試執行器類。

C:\JUNIT_WORKSPACE>javac PrimeNumberChecker.java PrimeNumberCheckerTest.java
TestRunner.java

現在執行測試執行器,它將執行在提供的測試用例類中定義的測試用例。

C:\JUNIT_WORKSPACE>java TestRunner

驗證輸出。

Parameterized Number is : 2
Parameterized Number is : 6
Parameterized Number is : 19
Parameterized Number is : 22
Parameterized Number is : 23
true

JUnit - 與 Ant 整合

我們將透過一個示例演示如何使用 Ant 執行 JUnit。請按照以下步驟操作。

步驟 1:下載 Apache Ant

根據你正在使用的作業系統下載 Apache Ant

作業系統 歸檔名稱
Windows apache-ant-1.8.4-bin.zip
Linux apache-ant-1.8.4-bin.tar.gz
Mac apache-ant-1.8.4-bin.tar.gz

步驟 2:設定 Ant 環境

設定 ANT_HOME 環境變數,使其指向 ANT 庫儲存在你機器上的基目錄位置。假設 Ant 庫儲存在 apache-ant-1.8.4 資料夾中。

序號 作業系統和說明
1

Windows

將環境變數 ANT_HOME 設定為 C:\Program Files\Apache Software Foundation\apache-ant-1.8.4

2

Linux

export ANT_HOME = /usr/local/apache-ant-1.8.4

3

Mac

export ANT_HOME = /Library/apache-ant-1.8.4

將 Ant 編譯器位置追加到系統路徑,如下所示:

作業系統 輸出
Windows 在系統變數 Path 的末尾追加字串 %ANT_HOME\bin
Linux export PATH = $PATH:$ANT_HOME/bin/
Mac 不需要

步驟 3:下載 JUnit 歸檔檔案

下載適合你作業系統的 JUnit 歸檔檔案。

作業系統 歸檔名稱
Windows junit4.10.jar
Linux junit4.10.jar
Mac junit4.10.jar

步驟 4:建立專案結構

  • 在 C:\JUNIT_WORKSPACE 中建立一個名為 TestJunitWithAnt 的資料夾。

  • 在 C:\JUNIT_WORKSPACE\TestJunitWithAnt 中建立一個名為 src 的資料夾。

  • 在 C:\JUNIT_WORKSPACE\TestJunitWithAnt 中建立一個名為 test 的資料夾。

  • 在 C:\JUNIT_WORKSPACE\TestJunitWithAnt 中建立一個名為 lib 的資料夾。

  • 在 C:\JUNIT_WORKSPACE\TestJunitWithAnt\src 資料夾中建立 MessageUtil 類。

/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message; 
   }

   // prints the message
   public String printMessage(){
      System.out.println(message);
      return message;
   }   

   // add "Hi!" to the message
   public String salutationMessage(){
      message = "Hi!" + message;
      System.out.println(message);
      return message;
   }   
}  	

在 C:\JUNIT_WORKSPACE\TestJunitWithAnt\src 資料夾中建立 TestMessageUtil 類。

import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

public class TestMessageUtil {

   String message = "Robert";	
   MessageUtil messageUtil = new MessageUtil(message);
   
   @Test
   public void testPrintMessage() {	
      System.out.println("Inside testPrintMessage()");     
      assertEquals(message,messageUtil.printMessage());
   }

   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Robert";
      assertEquals(message,messageUtil.salutationMessage());
   }
}

將 junit-4.10.jar 複製到 C:\JUNIT_WORKSPACE\TestJunitWithAnt\lib 資料夾。

建立 Ant Build.xml

我們將使用 Ant 中的 <junit> 任務來執行我們的 JUnit 測試用例。

<project name = "JunitTest" default = "test" basedir = ".">
   <property name = "testdir" location = "test" />
   <property name = "srcdir" location = "src" />
   <property name = "full-compile" value = "true" />
	
   <path id = "classpath.base"/>
	
   <path id = "classpath.test">
      <pathelement location = "lib/junit-4.10.jar" />
      <pathelement location = "${testdir}" />
      <pathelement location = "${srcdir}" />
      <path refid = "classpath.base" />
   </path>
	
   <target name = "clean" >
      <delete verbose = "${full-compile}">
         <fileset dir = "${testdir}" includes = "**/*.class" />
      </delete>
   </target>
	
   <target name = "compile" depends = "clean">
      <javac srcdir = "${srcdir}" destdir = "${testdir}" 
         verbose = "${full-compile}">
         <classpath refid = "classpath.test"/>
      </javac>
   </target>
	
   <target name = "test" depends = "compile">
      <junit>
         <classpath refid = "classpath.test" />
         <formatter type = "brief" usefile = "false" />
         <test name = "TestMessageUtil" />
      </junit>
   </target>
	
</project>

執行以下 Ant 命令。

C:\JUNIT_WORKSPACE\TestJunitWithAnt>ant

驗證輸出。

Buildfile: C:\JUNIT_WORKSPACE\TestJunitWithAnt\build.xml

clean:  

compile:  
   [javac] Compiling 2 source files to C:\JUNIT_WORKSPACE\TestJunitWithAnt\test
   [javac] [parsing started C:\JUNIT_WORKSPACE\TestJunitWithAnt\src\
      MessageUtil.java]
   [javac] [parsing completed 18ms]
   [javac] [parsing started C:\JUNIT_WORKSPACE\TestJunitWithAnt\src\
      TestMessageUtil.java]
   [javac] [parsing completed 2ms]
   [javac] [search path for source files: C:\JUNIT_WORKSPACE\
      TestJunitWithAnt\src]    
   [javac] [loading java\lang\Object.class(java\lang:Object.class)]
   [javac] [loading java\lang\String.class(java\lang:String.class)]
   [javac] [loading org\junit\Test.class(org\junit:Test.class)]
   [javac] [loading org\junit\Ignore.class(org\junit:Ignore.class)]
   [javac] [loading org\junit\Assert.class(org\junit:Assert.class)]
   [javac] [loading java\lang\annotation\Retention.class
      (java\lang\annotation:Retention.class)]
   [javac] [loading java\lang\annotation\RetentionPolicy.class
      (java\lang\annotation:RetentionPolicy.class)]
   [javac] [loading java\lang\annotation\Target.class
      (java\lang\annotation:Target.class)]
   [javac] [loading java\lang\annotation\ElementType.class
      (java\lang\annotation:ElementType.class)]
   [javac] [loading java\lang\annotation\Annotation.class
      (java\lang\annotation:Annotation.class)]
   [javac] [checking MessageUtil]
   [javac] [loading java\lang\System.class(java\lang:System.class)]
   [javac] [loading java\io\PrintStream.class(java\io:PrintStream.class)]
   [javac] [loading java\io\FilterOutputStream.class
      (java\io:FilterOutputStream.class)]
   [javac] [loading java\io\OutputStream.class(java\io:OutputStream.class)]
   [javac] [loading java\lang\StringBuilder.class
      (java\lang:StringBuilder.class)]
   [javac] [loading java\lang\AbstractStringBuilder.class
      (java\lang:AbstractStringBuilder.class)]
   [javac] [loading java\lang\CharSequence.class(java\lang:CharSequence.class)]
   [javac] [loading java\io\Serializable.class(java\io:Serializable.class)]
   [javac] [loading java\lang\Comparable.class(java\lang:Comparable.class)]
   [javac] [loading java\lang\StringBuffer.class(java\lang:StringBuffer.class)]
   [javac] [wrote C:\JUNIT_WORKSPACE\TestJunitWithAnt\test\MessageUtil.class]
   [javac] [checking TestMessageUtil]
   [javac] [wrote C:\JUNIT_WORKSPACE\TestJunitWithAnt\test\TestMessageUtil.class]
   [javac] [total 281ms]

test:
    [junit] Testsuite: TestMessageUtil
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.008 sec
    [junit]
    [junit] ------------- Standard Output ---------------
    [junit] Inside testPrintMessage()
    [junit] Robert
    [junit] Inside testSalutationMessage()
    [junit] Hi!Robert
    [junit] ------------- ---------------- ---------------

BUILD SUCCESSFUL
Total time: 0 seconds

JUnit - 與 Eclipse 整合

要使用 Eclipse 設定 JUnit,請按照以下步驟操作。

步驟 1:下載 JUnit 歸檔檔案

根據你係統上的作業系統下載 JUnit jar 檔案。

作業系統 歸檔名稱
Windows junit4.10.jar
Linux junit4.10.jar
Mac junit4.10.jar

假設你已將上述 JAR 檔案複製到 C:\JUnit 資料夾。

步驟 2:設定 Eclipse 環境

開啟 Eclipse → 右鍵單擊專案並單擊屬性 → 構建路徑 → 配置構建路徑,並使用“新增外部 Jar”按鈕在庫中新增 junit-4.10.jar。

Add junit-4.10.jar in liraries.

我們假設你的 Eclipse 具有內建的 JUnit 外掛。如果它不存在於 C:\eclipse\plugins 目錄中,你可以從 JUnit Plugin 下載它。將下載的 zip 檔案解壓縮到 Eclipse 的 plugin 資料夾中。最後重新啟動 Eclipse。

現在你的 Eclipse 已準備好開發 JUnit 測試用例。

步驟 3:驗證 Eclipse 中的 JUnit 安裝

在任何位置的 Eclipse 中建立一個名為 TestJunit 的專案。然後在專案中建立一個要測試的 MessageUtil 類。

   
/*
* This class prints the given message on console.
*/

public class MessageUtil {

   private String message;

   //Constructor
   //@param message to be printed
   public MessageUtil(String message){
      this.message = message;
   }
      
   // prints the message
   public String printMessage(){
      System.out.println(message);
      return message;
   }   
} 

在專案中建立一個測試類 TestJunit

   
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class TestJunit {
	
   String message = "Hello World";	
   MessageUtil messageUtil = new MessageUtil(message);

   @Test
   public void testPrintMessage() {	  
      assertEquals(message,messageUtil.printMessage());
   }
}

專案結構應如下所示:

Project Structure

最後,右鍵單擊程式並選擇“以 JUnit 執行”以驗證程式的輸出。

Run Junit

驗證結果。

JUnit result success.

JUnit - 擴充套件

以下是 JUnit 擴充套件:

  • Cactus
  • JWebUnit
  • XMLUnit
  • MockObject

Cactus

Cactus 是一個簡單的測試框架,用於單元測試伺服器端 Java 程式碼(Servlet、EJB、標籤庫、過濾器)。Cactus 的目的是降低編寫伺服器端程式碼測試的成本。它使用 JUnit 並對其進行擴充套件。Cactus 實現了一個容器內策略,該策略在容器內執行測試。

Cactus 生態系統由多個元件組成:

  • Cactus 框架是 Cactus 的核心。它是提供編寫 Cactus 測試的 API 的引擎。

  • Cactus 整合模組是前端和框架,它們提供了使用 Cactus 框架的簡便方法(Ant 指令碼、Eclipse 外掛和 Maven 外掛)。

以下程式碼演示瞭如何使用 Cactus。

import org.apache.cactus.*;
import junit.framework.*;

public class TestSampleServlet extends ServletTestCase {
   @Test
   public void testServlet() {
      // Initialize class to test
      SampleServlet servlet = new SampleServlet();

      // Set a variable in session as the doSomething()
      // method that we are testing 
      session.setAttribute("name", "value");

      // Call the method to test, passing an 
      // HttpServletRequest object (for example)
      String result = servlet.doSomething(request);

      // Perform verification that test was successful
      assertEquals("something", result);
      assertEquals("otherValue", session.getAttribute("otherName"));
   }
}

JWebUnit

JWebUnit 是一個基於 Java 的 Web 應用程式測試框架。它使用統一的簡單測試介面包裝現有的測試框架(如 HtmlUnit 和 Selenium),以測試 Web 應用程式的正確性。

JWebUnit 提供了一個高階 Java API,用於導航 Web 應用程式,並結合一系列斷言來驗證應用程式的正確性。這包括透過連結導航、表單輸入和提交、表內容驗證以及其他典型的業務 Web 應用程式功能。

簡單的導航方法和現成的斷言允許比僅使用 JUnit 或 HtmlUnit 更快地建立測試。如果你想從 HtmlUnit 切換到其他外掛,例如 Selenium(即將推出),則無需重寫你的測試。

這是一個示例程式碼。

import junit.framework.TestCase;
import net.sourceforge.jwebunit.WebTester;

public class ExampleWebTestCase extends TestCase {
   private WebTester tester;
   
   public ExampleWebTestCase(String name) {
      super(name);
      tester = new WebTester();
   }
	
   //set base url
   public void setUp() throws Exception {
      getTestContext().setBaseUrl("http://myserver:8080/myapp");
   }
	
   // test base info
   @Test
   public void testInfoPage() {
      beginAt("/info.html");
   }
}

XMLUnit

XMLUnit 提供單個 JUnit 擴充套件類 XMLTestCase 和一組支援類,允許對以下內容進行斷言:

  • 兩段 XML 之間的差異(透過 Diff 和 DetailedDiff 類)。

  • XML 片段的有效性(透過 Validator 類)。

  • 使用 XSLT 轉換 XML 片段的結果(透過 Transform 類)。

  • 在 XML 片段上評估 XPath 表示式的結果(透過實現 XpathEngine 介面的類)。

  • 透過 DOM 遍歷公開的 XML 片段中的各個節點(透過 NodeTest 類)。

讓我們假設我們有兩段 XML 需要比較並斷言它們相等。我們可以編寫一個簡單的測試類,如下所示:

import org.custommonkey.xmlunit.XMLTestCase;

public class MyXMLTestCase extends XMLTestCase {

   // this test method compare two pieces of the XML
   @Test
   public void testForXMLEquality() throws Exception {
      String myControlXML = "<msg><uuid>0x00435A8C</uuid></msg>";
      String myTestXML = "<msg><localId>2376</localId></msg>";
      assertXMLEqual("Comparing test xml to control xml", myControlXML, myTestXML);
   }
}

MockObject

在單元測試中,模擬物件可以模擬複雜、真實的(非模擬)物件的 behavior,因此當在單元測試中包含真實物件不切實際或不可能時,它們非常有用。

使用模擬物件進行測試的常見編碼風格是:

  • 建立模擬物件的例項。
  • 在模擬物件中設定狀態和期望。
  • 使用模擬物件作為引數呼叫領域程式碼。
  • 驗證模擬物件的一致性。

以下是使用 Jmock 的 MockObject 示例。

import org.jmock.Mockery;
import org.jmock.Expectations;

class PubTest extends TestCase {
   Mockery context = new Mockery();
   public void testSubReceivesMessage() {
      // set up
      final Sub sub = context.mock(Sub.class);

      Pub pub = new Pub();
      pub.add(sub);
    
      final String message = "message";
      
      // expectations
      context.checking(new Expectations() {
         oneOf (sub).receive(message);
      });

      // execute
      pub.publish(message);
      
      // verify
      context.assertIsSatisfied();
   }
}
廣告