Storyteller provides a couple mechanisms to reuse grammars across fixtures or even within the same fixture:
- Subclass a
Fixture
with inheritance. - Use <[linkto:documentation/engine/grammars/embedded_section]>
- Use Currying to use an existing grammar in a more specific way. Shown below.
- Use the
Fixture.Import()
method shown below
Let's say that you're working on an invoicing system again. A common task in your Storyteller project will be to set up an Invoice
object with all its various properties. In some cases you definitely want to explicitly specify all of the Invoice's properties. In other cases, the only thing that matters for the specification is that an Invoice is open or fulfilled. Since one of the Storyteller's deepest held ideas is that only information germane to a specification should be expressed in a specification, Storyteller provides a feature called grammar currying to allow you to supply less information to an existing grammar.
The generic grammar for setting up an Invoice and a curried version to set up an open invoice.
<[sample:currying-a-grammar-for-expressiveness]>
In usage, you can see the difference between the more generic grammar and the specific, curried grammar.
<[spec:Currying/Currying]>
The goal of grammar currying was to make the expression of the specifications more declarative and easier to understand without requiring users to duplicate grammar code.
Storyteller also supports a mechanism to import a grammar from one fixture into another:
<[sample:import-grammar-example]>
When using an imported grammar, the ISpecContext
for the current specification is available on the original Fixture object, but you cannot depend on the SetUp()
and TearDown()
methods to be called on the original Fixture.