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 {}