英文:
JUnit 5 @EnabledIfSystemProperty doesn't work as expected
问题
我将我的测试从JUnit 4迁移到JUnit 5。一切都正常,但是我之前的注解翻译不正确:
@IfProfileValue(name = "run.import.tests", values = {"true"})
翻译成了:
@EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
但是它的行为与预期不符。在迁移之前,我运行测试时只有在传递了以下参数时才会运行:
-Drun.import.tests=true
但是使用JUnit 5,即使使用了注解@EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
,测试也会在未设置run.import.tests
参数的情况下运行。
我是否做错了什么?
英文:
I migrated my test from JUnit 4 to JUnit 5. All works fine but the translation of my previous annotation:
@IfProfileValue(name = "run.import.tests", values = {"true"})
into
@EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
doesn't work as expected. Before the migration I runned my tests passing the argument
-Drun.import.tests=true
only if I passed it they were runned. With Junit 5, even with annotation @EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
the test is runned even if the argument run.import.tests
is not set.
Am I doing something wrong?
答案1
得分: 7
为使其生效,需要添加一个“相反”注释,这样它们两者一起看起来像这样:
@EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
@DisabledIfSystemProperty(named = "run.import.tests", matches = "(?!true)")
我已经检查过了,如果未设置run.import.tests
属性或者它设置为除true
以外的任何其他值,测试类都将被禁用;如果值设置为true
,则测试类不会被禁用。
有趣的是,@EnabledIfSystemProperty
的文档表示:
如果指定的系统属性未定义,则将禁用带有该注释的类或方法。
但实际情况并非如此,这可能是一个bug。我将尝试调试JUnit类,如果在它们的GitHub上创建了问题,我将在这里链接它。
我已经仔细查看了代码并进行了多次测试 - 这里是总结:
- 当我使用Maven运行测试(
mvn test
)时,仅使用@EnabledIfSystemProperty
注释就可以正常工作 - 只有在添加-Drun.import.tests=true
参数时才会运行测试。在这种情况下,不需要@DisabledIfSystemProperty
。 - 当我使用IntelliJ的“运行XxxTest”来运行测试时,只有在两个注释都存在的情况下,属性的处理才正常工作。经过一些调试,我发现了
JupiterTestEngine
- 这是由外部启动器(Maven、IntelliJ、任何其他启动器)运行的类。似乎IntelliJ在其测试启动器中添加了一个属性:junit.jupiter.conditions.deactivate,通常是有用的 - 有了它,我们甚至可以在本地运行已被条件注释禁用的测试,忽略它们。当@DisabledIfSystemProperty
不存在时,属性的值为org.junit.*Enabled*Condition
,而存在时为org.junit.*Disabled*Condition
- 这些条件是JUnit的扩展,用于解析测试的禁用状态。
(2)中描述的功能通常很有用,但在您的情况下,它让注释看起来好像不起作用。实际上,它确实起作用,只是IntelliJ绕过了它。
英文:
To make it work an "opposite" annotation has to be added, so both of them together look like this:
@EnabledIfSystemProperty(named = "run.import.tests", matches = "true")
@DisabledIfSystemProperty(named = "run.import.tests", matches = "(?!true)")
I've checked it and the test class is disabled if the run.import.tests
property is not set or if it is set to any other value than true
; if the value is set to true
- the test class is not disabled.
Curiously, the documentation of @EnabledIfSystemProperty states:
> If the specified system property is undefined, the annotated class or method will be disabled.
Yet it does not work that way and it may be a bug. I will try and debug the JUnit classes and if I create an issue on their GitHub, I will link it here.
I've gone through the code and tested it a few more times - here is the summary:
- When I run the test using Maven (
mvn test
), the annotation@EnabledIfSystemProperty
alone works fine - the test is run only when I add-Drun.import.tests=true
argument.@DisabledIfSystemProperty
is not needed in that case. - When I run the test using IntelliJ's
Run XxxTest
handling of the property worked fine only if both annotations were present. After some debugging I came acrossJupiterTestEngine
- a class that is run by external launchers (Maven, IntelliJ, any other). It seems that IntelliJ adds a property to it's test launcher: junit.jupiter.conditions.deactivate, which is usually useful - thanks to that we can run even tests that are disabled with conditional annotations locally, ignoring them. The value of the property isorg.junit.*Enabled*Condition
when@DisabledIfSystemProperty
is not present andorg.junit.*Disabled*Condition
when it is - the conditions are JUnit's extensions that resolve disabled state for the test.
The functionality described in (2) is usually useful, but in your case it made it look like the annotation is not working. It actually is working, but IntelliJ just bypasses it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论