Spring JUnit 4 Testing Annotations

  • @IfProfileValue:基于配置的配置文件值启用或禁用测试。

  • @ProfileValueSourceConfiguration:指定用于检索配置文件值的配置文件值源类型。

  • @Timed:限制测试方法执行的持续时间,如果超过会使测试失败。

  • @Repeat:指定测试方法应重复执行的次数。

这些注释有助于控制和配置 Spring 和 JUnit 4 测试的执行行为,使其更灵活和健壮。

只有在与 SpringRunnerSpring’s JUnit 4 rulesSpring’s JUnit 4 support classes结合使用时,才支持以下注释:

The following annotations are supported only when used in conjunction with the SpringRunner, Spring’s JUnit 4 rules , or Spring’s JUnit 4 support classes:

@IfProfileValue

@IfProfileValue 表明带注解的测试类或测试方法已针对特定测试环境启用。如果配置的 ProfileValueSource 返回与提供的 name 匹配的 value,则测试处于启用状态。否则,测试将被禁用,并且实际上会被忽略。

@IfProfileValue indicates that the annotated test class or test method is enabled for a specific testing environment. If the configured ProfileValueSource returns a matching value for the provided name, the test is enabled. Otherwise, the test is disabled and, effectively, ignored.

你可以在类级别、方法级别或两者都应用 @IfProfileValue@IfProfileValue 的类级别用法优先于该类或其子类中任何方法的类级别用法。具体而言,如果测试在类级别和方法级别均处于启用状态,则该测试处于启用状态。不存在 @IfProfileValue 表示测试已隐式启用。这类似于 JUnit 4 的 @Ignore 注解的语义,除了 @Ignore 的存在始终禁用测试。

You can apply @IfProfileValue at the class level, the method level, or both. Class-level usage of @IfProfileValue takes precedence over method-level usage for any methods within that class or its subclasses. Specifically, a test is enabled if it is enabled both at the class level and at the method level. The absence of @IfProfileValue means the test is implicitly enabled. This is analogous to the semantics of JUnit 4’s @Ignore annotation, except that the presence of @Ignore always disables a test.

以下示例显示具有 @IfProfileValue 注解的测试:

The following example shows a test that has an @IfProfileValue annotation:

Java
@IfProfileValue(name="java.vendor", value="Oracle Corporation") (1)
@Test
public void testProcessWhichRunsOnlyOnOracleJvm() {
	// some logic that should run only on Java VMs from Oracle Corporation
}
1 Run this test only when the Java vendor is "Oracle Corporation".
Kotlin
@IfProfileValue(name="java.vendor", value="Oracle Corporation") (1)
@Test
fun testProcessWhichRunsOnlyOnOracleJvm() {
	// some logic that should run only on Java VMs from Oracle Corporation
}
2 Run this test only when the Java vendor is "Oracle Corporation".

或者,你可以使用一个 values 列表配置 @IfProfileValue(带有 OR 语义)来实现对 JUnit 4 环境中测试组的 TestNG 类似的支持。考虑以下示例:

Alternatively, you can configure @IfProfileValue with a list of values (with OR semantics) to achieve TestNG-like support for test groups in a JUnit 4 environment. Consider the following example:

Java
@IfProfileValue(name="test-groups", values={"unit-tests", "integration-tests"}) (1)
@Test
public void testProcessWhichRunsForUnitOrIntegrationTestGroups() {
	// some logic that should run only for unit and integration test groups
}
1 Run this test for unit tests and integration tests.
Kotlin
@IfProfileValue(name="test-groups", values=["unit-tests", "integration-tests"]) (1)
@Test
fun testProcessWhichRunsForUnitOrIntegrationTestGroups() {
	// some logic that should run only for unit and integration test groups
}
2 Run this test for unit tests and integration tests.

@ProfileValueSourceConfiguration

@ProfileValueSourceConfiguration 是一个注解,可以应用于测试类,以指定在通过 @IfProfileValue 注解检索通过配置的配置文件值时要使用哪种类型的 ProfileValueSource。如果未为测试声明 @ProfileValueSourceConfiguration,则默认使用 SystemProfileValueSource。以下示例展示如何使用 @ProfileValueSourceConfiguration

@ProfileValueSourceConfiguration is an annotation that can be applied to a test class to specify what type of ProfileValueSource to use when retrieving profile values configured through the @IfProfileValue annotation. If @ProfileValueSourceConfiguration is not declared for a test, SystemProfileValueSource is used by default. The following example shows how to use @ProfileValueSourceConfiguration:

Java
@ProfileValueSourceConfiguration(CustomProfileValueSource.class) (1)
public class CustomProfileValueSourceTests {
	// class body...
}
1 Use a custom profile value source.
Kotlin
@ProfileValueSourceConfiguration(CustomProfileValueSource::class) (1)
class CustomProfileValueSourceTests {
	// class body...
}
2 Use a custom profile value source.

@Timed

@Timed 表明带注解的测试方法必须在指定的时间段内完成执行(以毫秒为单位)。如果文本执行时间超过指定的时间段,则测试失败。

@Timed indicates that the annotated test method must finish execution in a specified time period (in milliseconds). If the text execution time exceeds the specified time period, the test fails.

时间段包括运行测试方法本身,测试的任何重复(请参阅“@Repeat”),以及测试装置的任何设置或拆除。以下示例展示了如何使用它:

The time period includes running the test method itself, any repetitions of the test (see @Repeat), as well as any setting up or tearing down of the test fixture. The following example shows how to use it:

Java
@Timed(millis = 1000) (1)
public void testProcessWithOneSecondTimeout() {
	// some logic that should not take longer than 1 second to run
}
1 Set the time period for the test to one second.
Kotlin
@Timed(millis = 1000) (1)
fun testProcessWithOneSecondTimeout() {
	// some logic that should not take longer than 1 second to run
}
2 Set the time period for the test to one second.

Spring 的“@Timed”注释与 JUnit 4 中的“@Test(timeout=…​)”支持具有不同的语义。具体来说,由于 JUnit 4 处理测试执行超时的方式(即,在单独的“Thread”中执行测试方法),如果测试花费的时间太长,“@Test(timeout=…​)”会先发制人地使测试失败。另一方面,Spring 的“@Timed”不会先发制人地使测试失败,而是等到测试完成才使其失败。

Spring’s @Timed annotation has different semantics than JUnit 4’s @Test(timeout=…​) support. Specifically, due to the manner in which JUnit 4 handles test execution timeouts (that is, by executing the test method in a separate Thread), @Test(timeout=…​) preemptively fails the test if the test takes too long. Spring’s @Timed, on the other hand, does not preemptively fail the test but rather waits for the test to complete before failing.

@Repeat

“@Repeat”表示注释的测试方法必须反复运行。测试方法运行的次数在注释中指定。

@Repeat indicates that the annotated test method must be run repeatedly. The number of times that the test method is to be run is specified in the annotation.

要重复执行的范围包括执行测试方法本身以及对测试夹具进行任何设置或拆除。与 xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[SpringMethodRule 一起使用时,此范围还包括通过 TestExecutionListener 实现准备测试实例。以下示例显示了如何使用 @Repeat 注释:

The scope of execution to be repeated includes execution of the test method itself as well as any setting up or tearing down of the test fixture. When used with the SpringMethodRule, the scope additionally includes preparation of the test instance by TestExecutionListener implementations. The following example shows how to use the @Repeat annotation:

Java
@Repeat(10) (1)
@Test
public void testProcessRepeatedly() {
	// ...
}
1 Repeat this test ten times.
Kotlin
@Repeat(10) (1)
@Test
fun testProcessRepeatedly() {
	// ...
}
2 Repeat this test ten times.