It would be awesome if Specflow allowed steps in one feature file to be called from a step definition or event hook.
This would allow data setup to be done in a feature that could be used across a number of different features. Specflow provides lovely Gherkin format tables which are great for setting up data, but if you want the same data to be set up for a number of different scenarios or features, you need to repeat the table in each feature. alternatives are to put standing data into xml files or similar, but it would be nice if the test data were viewable in feature files a so they can be Pickled!
yes, sort of. you can call the feature.cs methods from a step definition, but there are 2 problems
- the scenario and feature context are replaced with the feature and scenario context in the called feature and scenario method
- there are warnings in the console output about not disposing the feature and scenario contexts (see below)
What am I after?
a way of calling the methods in a feature.cs file from a step definition or hook that preserves the current scenario and feature context, and doesn't lead to warnings about undisposed contexts
How might this be done?
- create a built in method of calling methods in feature.cs classes without needing to set up a new context for the scenario or feature (maybe pass in the current sceanrio and feature info as constructor arguments to the feature?)
- create a new type of specflow class in the addins to go along with features, step definitions, and event hooks - maybe a specialised feature (DataFeature.feature maybe?)
- ?
Here's the output of my attempts to use Specflow 1.9 to do this as is:-
Test Name: A
Test Outcome: Passed
Result StandardOutput:
-> warning: The previous FeatureContext was not disposed.
-> warning: The previous ScenarioContext was not disposed.
-> warning: The previous ScenarioContext was not disposed.
Given I have setup the following templated test data as "defaultUser":
--- table step argument ---
| howMuch | title | firstName | middleName | dob_day | dob_month | dob_year |
| £350 | Mr | John | Smith | 12 | 11 | 1979 |
-> done: TestDataToShareStepBase.GivenIHaveSetupTheFollowingTemplatedTestDataAs("defaultUser", <table>) (3.1s)
Given the Test Run Context does contain templated data named "defaultUser"
-> done: TestDataToShareStepBase.GivenTheTestRunContextDoesContainTemplatedDataNamed("defaultUser") (5.2s)
[BeforeScenario("DataSetup")]
public void BeforeScenario()
{
//save the current Scenario and Feature contexts
var featureContext = FeatureContext.Current;
var scenarioContext = ScenarioContext.Current;
TestDataToShareFeature TestDataToShareFeature = new TestDataToShareFeature();
TestDataToShareFeature.FeatureSetup();
TestDataToShareFeature.ScenarioSetup(new ScenarioInfo("setup", new string[]{}));
TestDataToShareFeature.SetupTestData();
//problem - if these cleanup/teardowns aren't called then there is a warning in the output
// if they are called, the present scenario is killed. May have to add an after sceanrio hook to call these cleanup/Teardowns to avoid a memory leak, and just live with the warnings.
//TestDataToShareFeature.ScenarioCleanup();
//TestDataToShareFeature.ScenarioTearDown();
//TestDataToShareFeature.FeatureTearDown();
TestRunContext["TestDataToShareFeature"] = TestDataToShareFeature;
//reanimate the contexts - todo - get the type of the feature from the feature context
//FeatureContext.Current = featureContext; -- can't do this - read only
//ScenarioContext.Current = scenarioContext; -- can't do this - read only
TestDataToShareClientTwoFeature TestDataToShareClientTwoFeature = new TestDataToShareClientTwoFeature();
TestDataToShareClientTwoFeature.FeatureSetup();
TestDataToShareClientTwoFeature.ScenarioSetup(scenarioContext.ScenarioInfo); //works, but calls the scenario setup which calls this event again!
}