How to properly dispose stuff in scenario files

Jun 15, 2010 at 7:27 PM
Edited Jun 15, 2010 at 7:28 PM
When NBehave runs scenario files, I have hooks like [BeforeStep]/[AfterStep], and [BeforeScenario]/[AfterScenario] - but I wish for some way of hooking into the creation/disposal of the instance of the action steps class.

As my wish is purely driven by technical motives, I am thinking that it would fit nicely if NBehave would call Dispose if the class implemented IDisposable, allowing stuff to be allocated and initialized in the ctor of the class and disposed properly again in Dispose.

Another approach would be to implement [BeforeStory]/[AfterStory], but I think that would give a non-technical feel to it, like the hooks were somehow related to executing the story.

I am thinking about supplying a patch for this. Does someone have an opinion on which approach is better?

PS: The "stuff" I want to create/dispose is a Selenium InternetExplorerDriver, navigated to a Silverlight application which takes a few seconds to load. If the navigation could happen only once per scenario file instead of once per scenario, I could save a lot of time executing my specs.

PPS: I am currently accomplishing this with ctor/dtor, but we all know that .NET dtors are not called in a deterministic fashion, rendering them unusable for stuff like this.
Jun 15, 2010 at 9:35 PM

NBehave create instances of all classes that have [ActionSteps] on them before running anything, and they live until everything has executed, and I think its bad. What I would like to change in NBehave is to create a new instance of an [ActionStep] class for each scenario so there is no unintended state kept between scenarios. This make IDisposable unusable for what you want.
I think we should add the [BeforeStory] and [AfterStory] attributes along with context/session collection where you can keep your instance of Selenium InternetExplorerDriver (created and destroyed in [BeforeStory] / [AfterStory]).
What do you think?

Jun 16, 2010 at 6:10 PM
I think it would definitely be prettier if action step classes were instantiated when they were needed, e.g. per story (which would fit nicely as a parallel to the test fixture lifecycle i various unit testing frameworks), or per scenario as you mention.

Actually I think I would prefer the per-story-strategy, because of the way it aligns with other testing frameworks.

The [BeforeStory]/[AfterStory] attributes would be a nice solution to my problem, as I could instantiate stuff in [BeforeStory] and dispose it in [AfterStory] - but if I understand you correctly, you are thinking of letting NBehave provide some kind of Context.Items dictionary, allowing e.g. my InternetExplorerDriver to "survive" multiple scenarios, am I understanding you correctly?

If we settled on the per-story-strategy, the class itself would be the context, allowing its fields to be used instead of a weakly typed dictionary of objects. In my opinion this would be better.

What's your opinion on this?
Jun 20, 2010 at 2:22 PM

I have been thinking and you are right, instantiate per story is the best option. If IDispose is implemented we can call Dispose, if not just drop the instance.
If someone want instance per scenario its easily doable with [BeforeScenario]/[AfterScenario].
And we don need any context object which is good.