我定义了自己的 JUnit 注释:
@ParameterizedTest
@MethodSource("myorg.qa.ccrtesting.DataProviders#standardDataProvider")
@Tags({@Tag("ccr"), @Tag("standard")})
public @interface CcrStandardTest {
}
然后,我可以在测试中使用该注释:
@CcrStandardTest
public void E0010_contact_standard (String testData) {
...
- 我的运行配置:
JVM 选项:-ea
类:myorg.qa.ccrtesting.ccrstandardtests.CcrStanConTest
- 这是 IDE 建议的(并经过验证指向正确的类,其中包含我的原型(prototype)测试方法)
但是,这会导致:jupiter.api.extension.ParameterResolutionException:在方法 [public void... 中没有为参数 [java.lang.String arg0] 注册 ParameterResolver。
我尝试从测试方法签名中删除
String testData
,但 JUnit 没有执行任何测试:未找到测试
当我在原型(prototype)测试方法上方添加
@Test
时,它会执行但是:- 似乎我在
@CcrStandardTest
下定义的注释均未应用 - IDE 建议
可疑的组合 @Test 和参数化源
(我已经知道@ParameterizedTest
暗示@Test
,只是不确定为什么 IDE 能够找到自定义注释,而 JUnit 却不能?)
- 似乎我在
最佳答案
正如您所发现的,您需要将 @Retention(RUNTIME)
添加到您的组合注释中,以便 JUnit 能够看到它。 Java 中的注释具有三种不同的保留策略:
-
Annotations are to be discarded by the compiler.
-
Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. This is the default behavior. [emphasis added]
-
Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.
正如我上面强调的,如果您没有显式添加 @Retention(...)
,则使用 CLASS
策略。这不适用于 JUnit,因为 JUnit 不会扫描 *.class
文件(即字节码)中的注释,它会反射性地扫描加载的类来查找测试方法。如果没有 RUNTIME
保留策略,您的注释将无法通过反射方式访问,因此 JUnit 永远不会看到它,因此不会执行测试。
@Target
注释:
Indicates the contexts in which an annotation type is applicable. The declaration contexts and type contexts in which an annotation type may be applicable are specified in JLS 9.6.4.1, and denoted in source code by enum constants of
java.lang.annotation.ElementType
.If an
@Target
meta-annotation is not present on an annotation typeT
, then an annotation of typeT
may be written as a modifier for any declaration except a type parameter declaration.If an
@Target
meta-annotation is present, the compiler will enforce the usage restrictions indicated byElementType
enum constants, in line with JLS 9.7.4.
在我对 your other question 的回答中,我使用了:
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
因为这与 @ParameterizedTest
使用的目标相同。我认为将其限制为 METHOD
是一个好主意,因为 @ParameterizedTest
的设计者显然认为只有方法应该由参数化测试扩展直接扩展(请参阅 §5 Extension Model )。包含 ANNOTATION_TYPE
允许您将组合注释放在另一个注释上,从而创建另一个组合注释。
您还会看到我包含了 @Documented
:
If the annotation
@Documented
is present on the declaration of an annotation typeA
, then any@A
annotation on an element is considered part of the element's public contract. In more detail, when an annotation typeA
is annotated withDocumented
, the presence and value of annotations of typeA
are a part of the public contract of the elementsA
annotates. Conversely, if an annotation typeB
is not annotated withDocumented
, the presence and value ofB
annotations are not part of the public contract of the elementsB
annotates. Concretely, if an annotation type is annotated withDocumented
, by default a tool like javadoc will display annotations of that type in its output while annotations of annotation types withoutDocumented
will not be displayed.
请注意,这些注释 - @Retention
、@Target
和 @Documented
- 并非特定于 JUnit。这些注释对于 Java 中注释的工作方式至关重要,每个注释都位于 java.lang.annotation
包中。
关于java - JUnit5-木星 : Composed ( ="meta") annotation does not resolve to annotation definition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60339277/