JGiven
JGiven copied to clipboard
Alternative usage of external stages
I think it would sometimes be easier if we could use an external stage GivenTestData
via given(GivenTestData.class)
or and(GivenTestData.class)
instead of injecting the stage via @ScenarioStage
.
The following code:
given().some_configuration();
givenTestData.and().some_test_data();
Could then be written as:
given().some_configuration()
.and(GivenTestData.class).some_test_data();
Sounds like a good idea. There is one problem though. If the stage has a @BeforeScenario
annotation, the corresponding method cannot be executed anymore before the complete scenario, because JGiven does not know about that stage at the beginning of the scenario.
I think it's a recurring problem that JGiven needs to now the stages in advance and we should find a way to solve this.
What if the meaning of @BeforeScenario
would be more like @BeforeStageOnce
as from my of view there is no real need to execute stage-specific code before the whole scenario?
Why do I think so? Let's say, we have an annotated method with some behavior a later test relies on. Then it should not matter when exactly that method is called since (assuming a modular stage design) the method works independently of the other stages (including their setup via @BeforeX
) and, as a stage does not have any reference to a JUnit test, it also works independently of the test classes' setup via @Before
.
Thus, the essential point of the @BeforeScenario
annotation is not that the annotated method is executed before the whole scenario but that it is executed once at some point in time before the first usage of the corresponding stage. That's something we can determine at "Runtime", can't we?
Well, I guess you are right. @BeforeScenario
should be in most cases identical to @BeforeStage
which is also only executed once before the stage. This is in contrast to @AfterScenario
which really cannot be replaced with @AfterStage
. The problem still might be that existing code relies on the existing behavior of @BeforeScenario
. So changing the semantics might break existing code.
You could still introduce a new annotation, deprecate the old one and then throw the old one away after some release cycles. And JGiven is version 0.x, so there can always be breaking changes. :smirk:
Well, if we would introduce a mechanism like the one you are describing and @BeforeScenario would only behave differently in this case then this would also be fine as there is no existing code that uses that. However, the documentation of the semantics of @BeforeScenario
will then become a bit difficult.
Perhaps we can use it like so:
@ScenarioStage
private WhenSomething<?> whenSomething
@Test
public test() {
given().nop();
when().nop().
.and(whenSomething).some_other();
}