JUnit學習筆記
JUnit框架
JUnit是一個測試框架,它使用注釋來標識指定測試的方法。JUnit是Github上托管的一個開源項目。
如何在JUnit中定義測試?
- JUnit 測試是類中包含的方法,僅用於測試。這稱為測試類。
- 要定義某種方法為測試方法,請使用注釋對其進行
@Test
注釋。此方法執行被測代碼。 - 您可以使用JUnit或另一個assert框架提供的assert方法來檢查預期結果與實際結果。這些方法調用通常稱為斷言或斷言語句。
JUnit測試示例
以下代碼顯示了使用JUnit 5
版本的JUnit
測試。該測試假定MyClass
該類存在並具有一個multiply(int, int)
方法。
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class MyTests {
@Test
public void multiplicationOfZeroIntegersShouldReturnZero() {
MyClass tester = new MyClass(); // MyClass is tested
// assert statements
assertEquals(0, tester.multiply(10, 0), "10 x 0 must be 0");
assertEquals(0, tester.multiply(0, 10), "0 x 10 must be 0");
assertEquals(0, tester.multiply(0, 0), "0 x 0 must be 0");
}
}
JUnit命名約定
- JUnit測試有幾種潛在的命名約定。對於類的一種廣泛使用的解決方案是在測試類名稱的末尾使用
Test
后綴。 - 通常,測試名稱應說明測試的用途。如果正確完成,可以避免閱讀實際的實現。
- 如果使用的是Maven構建系統,則應將
Test
后綴用於測試類。Maven構建系統(通過其surfire插件)會在其測試范圍內自動包括此類。
測試執行順序
- JUnit假定所有測試方法都可以按任意順序執行。編寫良好的測試代碼不應假定任何順序,即測試不應依賴於其他測試。
- 從JUnit 4.11開始,默認設置是使用確定性但不可預測的順序來執行測試。
使用JUnit 4
定義測試方法
JUnit使用注釋將方法標記為測試方法並進行配置。下表概述了4.x和5.x版本的JUnit中最重要的注釋。所有這些注釋都可以在方法上使用。
斷言
JUnit通過Assert類提供了靜態方法來測試某些條件。這些assert語句通常以開頭assert。它們使您可以指定錯誤消息,預期結果和實際結果。一個斷言方法比較通過測試返回預期值實際值。
JUnit測試套件
如果您有多個測試類,則可以將它們組合成一個測試套件。運行測試套件將以指定順序執行該套件中的所有測試類。一個測試套件也可以包含其他測試套件。
以下示例代碼演示了測試套件的用法。它包含兩個測試類MyClassTest
和MySecondClassTest
。如果要添加另一個測試類,可以將其添加到@Suite.SuiteClasses
語句中。
package com.vogella.junit.first;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
MyClassTest.class,
MySecondClassTest.class })
public class AllTests {
}
禁用測試
@Ignore
批注允許靜態忽略測試。或者,您可以使用Assume.assumeFalse
或Assume.assumeTrue
定義測試條件。 Assume.assumeFalse
如果條件評估為true
,則將測試標記為無效。 Assume.assumeTrue
如果條件為假,則將測試評估為無效。
例如,以下內容禁用了Linux
上的測試:
`Assume.assumeFalse(System.getProperty("os.name").contains("Linux"));`
參數化測試
JUnit
允許您在測試類中使用參數。此類可以包含一個測試方法,並且使用提供的不同參數來執行此方法。
您可以使用@RunWith(Parameterized.class)
注釋將測試類標記為參數化測試。
這樣的測試類必須包含帶有注釋的靜態方法@Parameters
該方法生成並返回數組的集合。此集合中的每個項目都用作測試方法的參數。
您可以@Parameter
在公共字段上使用批注獲取在測試中注入的測試值。
以下代碼顯示了參數化測試的示例。為此示例,它測試了作為內部類包括在內的類的multiply()方法MyClass。
package testing;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.runners.Parameterized.*;
@RunWith(Parameterized.class)
public class ParameterizedTestFields {
// fields used together with @Parameter must be public
@Parameter(0)
public int m1;
@Parameter(1)
public int m2;
@Parameter(2)
public int result;
// creates the test data
@Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][] { { 1 , 2, 2 }, { 5, 3, 15 }, { 121, 4, 484 } };
return Arrays.asList(data);
}
@Test
public void testMultiplyException() {
MyClass tester = new MyClass();
assertEquals("Result", result, tester.multiply(m1, m2));
}
// class to be tested
class MyClass {
public int multiply(int i, int j) {
return i *j;
}
}
}
除了使用@Parameter
注釋之外,您還可以使用構造函數,在該構造函數中存儲每個測試的值。用注釋的方法提供的每個數組中的元素數 @Parameters
必須與類的構造函數中的參數數相對應。將為每個參數創建該類,並將測試值通過構造函數傳遞給該類。
package de.vogella.junit.first;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class ParameterizedTestUsingConstructor {
private int m1;
private int m2;
public ParameterizedTestUsingConstructor(int p1, int p2) {
m1 = p1;
m2 = p2;
}
// creates the test data
@Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][] { { 1 , 2 }, { 5, 3 }, { 121, 4 } };
return Arrays.asList(data);
}
@Test
public void testMultiplyException() {
MyClass tester = new MyClass();
assertEquals("Result", m1 * m2, tester.multiply(m1, m2));
}
// class to be tested
class MyClass {
public int multiply(int i, int j) {
return i *j;
}
}
}
如果運行此測試類,則將使用每個定義的參數執行測試方法。在上面的示例中,測試方法執行了3次。
JUnit5概述
JUnit 5由許多離散組件組成:
- JUnit平台-基礎層,可在JVM上啟動不同的測試框架
- Junit Jupiter-是由JUnit Platform啟動的JUnit 5測試框架
- JUnit Vintage-運行較早測試的傳統TestEngine
將JUnit 5與Maven結合使用
本示例說明如何將JUnit 5的所有組件導入項目。
我們需要向Maven surefire注冊各個組件:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
<properties>
<!-- <includeTags>fast</includeTags> -->
<excludeTags>slow</excludeTags>
</properties>
</configuration>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit.platform.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit.vintage.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
並添加依賴項:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
定義測試方法
JUnit
使用注釋將方法標記為測試方法並進行配置。下表概述了4.x和5.x版本的JUnit
中最重要的注釋。所有這些注釋都可以在方法上使用。
禁用測試
該@Disabled
注釋允許靜態地忽略測試。
或者,您可以使用Assumptions.assumeFalse
或Assumptions.assumeTrue
定義測試停用的條件。 Assumptions.assumeFalse
如果條件評估為true
,則將測試標記為無效。Assumptions.assumeTrue
如果條件為假,則將測試評估為無效。例如,以下內容禁用了Linux
上的測試:
Assumptions.assumeFalse(System.getProperty("os.name").contains("Linux"));
測試套件
要一起運行多個測試,可以使用測試套件。它們允許聚合多個測試類。JUnit 5提供了兩個注釋:
- @SelectPackages -用於指定測試套件的軟件包名稱
- @SelectClasses-用於指定測試套件的類。它們可以位於不同的程序包中。
示例:
@RunWith(JUnitPlatform.class)
@SelectPackages("com.vogella.junit5.examples")
public class AllTests {}
@RunWith(JUnitPlatform.class)
@SelectClasses({AssertionTest.class, AssumptionTest.class, ExceptionTest.class})
public class AllTests {}