New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Execution order of extensions changed with 1.7.0 #623
Comments
Hey @JoergSiebahn, thank you for the detailed issue description! 🙏 We actually considered this a bug, but your use case is definitely valid. We will look into this and try to come up with something. |
Hey @beatngu13, thank you for the quick response and for looking into this. For the moment I prepared my idea of a quick fix in the update PR. We have to discuss internally if we consider it as a breaking change for the consumers of our library to decide for a merge or waiting for our next major. I'm happy to hear about a better idea of a workaround or solution for such kind of tests. |
The easiest and (in my opinion) obvious solution would be to make this behaviour configurable. We could introduce an enum, e.g.:
The problem with this approach is that we basically re-introduce the "bug" we were trying to fix - extensions behaving kind of unpredictably...? |
Thanks for opening the issue @JoergSiebahn. This is a complicated topic because the semantics aren't clear. As you said, in the past annotating a class meant (A) "set system property before all tests", but we got feedback from some users who were surprised by this because they saw annotating the class as a shorthand for annotating each method and so thought it meant (B) "set system property before each test". To make matters worse, some of our extension did (A), others (B). After some back and forth, particularly on what should happen if users override a value (in this case, a system property) in one of their tests, we decided to go with (B). If I remember correctly, we considered adding (A) back in (i.e. having (A+B) behavior) for all such extensions: I think this should be possible and we may explore that in the coming weeks (we're not the fastest moving project). My recommendation is to sit on 1.6.2 for a while longer and wait how this shakes out before making any drastic changes. |
Thanks for giving an outlook to possible future changes @nipafx. I appreciate how you all take feedback into account for a little feature that has much more perspectives than I initially saw. |
Due to our new reset mechanism, I think we can no longer combine @TestMethodOrder(OrderAnnotation.class)
// Default execution phase BeforeEach/AfterEach.
@SetSystemProperty(key = "foo", value = "bar")
class MyTestA {
@BeforeAll
static void setUpOnce() {
assertThat(System.getProperty("foo")).isNull();
}
@BeforeEach
void setUp() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
}
@Order(1)
@Test
void test1() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
// Not visible in test2() because of AfterEach reset.
System.setProperty("foo", "baz");
}
@Order(2)
@Test
void test2() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
}
}
@TestMethodOrder(OrderAnnotation.class)
// Alternative execution phase BeforeAll/AfterAll.
@SetSystemProperty(key = "foo", value = "bar", executionPhase = BEFORE_ALL)
class MyTestB {
@BeforeAll
static void setUpOnce() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
}
@BeforeEach
void setUp() {
// Before test1() "foo" = "bar", after test() "foo" = "baz".
assertThat(System.getProperty("foo")).isNotNull();
}
@Order(1)
@Test
void test1() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
// Visible in test2() because of AfterAll reset.
System.setProperty("foo", "baz");
}
@Order(2)
@Test
void test2() {
assertThat(System.getProperty("foo")).isEqualTo("baz");
}
} Thoughts? |
If at all possible, I'd like to avoid an option because it makes the user choose.
That would be too bad. Can you explain why that may be the case? |
Let's recall your comment here:
One basically can't have both, at least that is my impression. See also my example above: in |
After today's maintainer meeting: we would first try to keep the current/new behavior, but make the extension additionally visible in @TestMethodOrder(OrderAnnotation.class)
@SetSystemProperty(key = "foo", value = "bar")
class MyTest {
@BeforeAll
static void setUpOnce() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
}
@BeforeEach
void setUp() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
}
@Order(1)
@Test
void test1() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
// Not visible in test2() because of AfterEach reset.
System.setProperty("foo", "baz");
}
@Order(2)
@Test
void test2() {
assertThat(System.getProperty("foo")).isEqualTo("bar");
}
} @JoergSiebahn would that work for you? |
Hey @beatngu13, sorry for the late response. It sounds reasonable to me, that an annotation at class level applies to everything in the class. That would work for our case. |
Hi @JoergSiebahn, thanks for the feedback! 👍 So, we will first follow the aforementioned approach, where we "try to keep the current/new behavior, but make the extension additionally visible in PS: I only used the
|
This PR fixes the reset of entry-based extension, so the value gets restored to its original value or the value of the higher-level container, or will be cleared if they didn't have one before. This is a breaking change considered to the way the reset worked before, but the maintainers considered it a bug and decided to fix it this way. closes #623 PR: #641
Since 1.7.0 some extension annotations at class level are not applied before
@RegisterExtension
any more.Specifically
@SetSystemProperty
is usingbeforeEach
now but usedbeforeAll
and has been executed before@RegisterExtension
annotated extension fields in the test class.We are using DropwizardAppExtension to bootstrap an application for all tests in the test class. In our case, the application needs the system property on startup to be configured for the test.
This change has been introduced with #496.
We see our test failing with the update to 1.7.0.
The PR and associated issues refer to alignment and consistent behavior. That sounds reasonable at a first glance. My personal assumption would be that something at class level is wrapped around something at method level and is applied as a class extension.
Do you have any suggestion how a test can be configured with 1.7.0 when it uses a static class extension that needs a system property to be configured for the test. In our specific case we could try to bootstrap the application in the test method and shut it down in a
finally
statement. But in general that is not suitable as it should be started only once for many test methods for performance reasons.The text was updated successfully, but these errors were encountered: