Since: Concordion 2.0.0
Concordion encourages you to keep your examples completely independent of each other. This allows individual examples to be run in isolation. It also makes the specification easier to follow when you can read examples in isolation.
To support this behaviour, Concordion reinitialises the fields in fixture objects for each Concordion example (where the example is using the concordion:example
command). This is standard JUnit behaviour (in fact, JUnit creates a new fixture object for each test).
However, we recognise that sometimes you will want to share fields across a specification when the field is expensive to initialise, for example a browser instance or database connection. Concordion provides support for specification scoped instance fields, in addition to the default example scope.
Scoped fields must be wrapped in ScopedObjectHolder and annotated with @ConcordionScoped.
For example:
@ConcordionScoped(Scope.SPECIFICATION)
private ScopedObjectHolder<AtomicInteger> specScopedCounter = new ScopedObjectHolder<AtomicInteger>() {
@Override
protected AtomicInteger create() {
return new AtomicInteger();
}
};
The scoped object is created lazily when you call the get()
method on the ScopedObjectHolder
. ScopedObjectHolder
also provides a destroy()
method that you can override to clean-up resources when they go out of scope.
We have two examples below. Each example increments an AtomicInteger that is scoped differently and echoes the value.