The @ClearSystemProperty
and @SetSystemProperty
annotations can be used to clear and set, respectively, the values of system properties for a test execution.
Both annotations work on the test method and class level, are repeatable, combinable, and inherited from higher-level containers.
After the annotated method has been executed, the properties mentioned in the annotation will be restored to their original value or the value of the higher-level container, or will be cleared if they didn’t have one before.
Other system properties that are changed during the test, are not restored.
For example, clearing a system property for a test execution can be done as follows:
@Test
@ClearSystemProperty(key = "some property")
void testClearingProperty() {
assertThat(System.getProperty("some property")).isNull();
}
And setting a system property for a test execution:
@Test
@SetSystemProperty(key = "some property", value = "new value")
void testSettingProperty() {
assertThat(System.getProperty("some property")).isEqualTo("new value");
}
As mentioned before, both annotations are repeatable and they can also be combined:
@Test
@ClearSystemProperty(key = "1st property")
@ClearSystemProperty(key = "2nd property")
@SetSystemProperty(key = "3rd property", value = "new value")
void testClearingAndSettingProperty() {
assertThat(System.getProperty("1st property")).isNull();
assertThat(System.getProperty("2nd property")).isNull();
assertThat(System.getProperty("3rd property")).isEqualTo("new value");
}
Note that class-level configurations are overwritten by method-level configurations:
@ClearSystemProperty(key = "some property")
class MySystemPropertyTest {
@Test
@SetSystemProperty(key = "some property", value = "new value")
void clearedAtClasslevel() {
assertThat(System.getProperty("some property")).isEqualTo("new value");
}
}
Note
|
Method-level configurations are visible in both Since v1.7.0, a class-level configuration means that the specified system properties are cleared/set before and reset after each individual test in the annotated class. |
Sometimes, you might also need to set a system property to a value that is not a constant expression, which is required for annotation values. In this case, you can still leverage the restore mechanism:
@ParameterizedTest
@ValueSource(strings = { "foo", "bar" })
@ClearSystemProperty(key = "some property")
void parameterizedTest(String value) {
System.setProperty("some property", value);
}
Thread-Safety
Since system properties are global state, reading and writing them during parallel test execution can lead to unpredictable results and flaky tests.
The system property extension is prepared for that and tests annotated with @ClearSystemProperty
or @SetSystemProperty
will never execute in parallel (thanks to resource locks) to guarantee correct test results.
However, this does not cover all possible cases. Tested code that reads or writes system properties independently of the extension can still run in parallel to it and may thus behave erratically when, for example, it unexpectedly reads a property set by the extension in another thread. Tests that cover code that reads or writes system properties need to be annotated with the respective annotation:
-
@ReadsSystemProperty
-
@WritesSystemProperty
Tests annotated in this way will never execute in parallel with tests annotated with @ClearSystemProperty
or @SetSystemProperty
.