Reputation: 108
Does anyone know if this is possible with SpecFlow? In the spirit of not having more than one assertion per test, I was hoping SpecFlow would treat each "Then" as a separate test.
I have a Scenario with multiple "Then" steps that looks something like this (snippet):
When a summary for day <day number> is requested
Then the summary well id should be "134134"
And the summary well name should be "My Well --oops!"
And the summary violated rules should be <violations>
And the summary variance should be <variance>
Examples:
| day number | violations | variance |
| 0 | BadTotal,HpOnLp | -33 |
| 3 | BadTotal | -133.33 |
| 5 | | 0 |
The second assertion "My Well --oops!" should fail. What I want is for SpecFlow to test the assertions that follow
I get:
When a summary for day 0 is requested
-> done: DprSummarySteps.WhenASummaryForDayIsRequested(0) (0.0s)
Then the summary well id should be "134134"
-> done: DprSummarySteps.ThenTheSummaryWellIdShouldBe("134134") (0.0s)
And the summary well name should be "My Well --oops!"
-> error: Assert.AreEqual failed. Expected:<My Well --oops!>. Actual:<My Well>.
And the summary violated rules should be BadTotal,HpOnLp
-> skipped because of previous errors
And the summary variance should be -33
-> skipped because of previous errors
Assert.AreEqual failed. Expected:<My Well --oops!>. Actual:<My Well>.
What I want:
When a summary for day 0 is requested
-> done: DprSummarySteps.WhenASummaryForDayIsRequested(0) (0.0s)
Then the summary well id should be "134134"
-> done: DprSummarySteps.ThenTheSummaryWellIdShouldBe("134134") (0.0s)
And the summary well name should be "My Well --oops!"
-> error: Assert.AreEqual failed. Expected:<My Well --oops!>. Actual:<My Well>.
And the summary violated rules should be BadTotal,HpOnLp
-> done: DprSummarySteps.ThenTheViolatedRulesShouldBe("BadTotal,HpOnLp") (0.0s)
And the summary variance should be -33
-> done: DprSummarySteps.ThenTheVarianceShouldBe(-33) (0.0s)
Assert.AreEqual failed. Expected:<My Well --oops!>. Actual:<My Well>.
Upvotes: 2
Views: 2680
Reputation: 1471
I have identified one way to do this. So what happens internally in specflow, before running any step, the TestExecutionEngine checks the LastExecutionStatus of Scenario, and it does not proceed if it is not OK
.. So what we can do is, in [AfterStep]
hook, add the following line :
typeof(ScenarioContext).GetProperty("ScenarioExecutionStatus").SetValue(this.ScenarioContext, ScenarioExecutionStatus.OK);
Replace this.ScenarioContext
with whatever object with type ScenarioContext exist. This will make the current status as OK and will allow you to proceed to next step.
Keep in mind this won't allow you to catch all assert failures in a single step.
Upvotes: 0
Reputation: 245
You can do this now if you upgrade to Specflow 2.4 and are using Nunit, see something like https://github.com/nunit/docs/wiki/Multiple-Asserts
Assert.Multiple(() =>
{
Assert.AreEqual(5.2, result.RealPart, "Real part");
Assert.AreEqual(3.9, result.ImaginaryPart, "Imaginary part");
});
Upvotes: 1
Reputation: 32954
I don't believe that you can do this but my question to you would be why do you want that? With any unit test it will fail at the first assertion. you wouldn't expect a test to continue execution after an assertion failed and this is no different. Surely knowing that the test failed for some reason is enough. In this specific case you might be able to make separate independent assertions which provide useful info, but in the general case assertions that come after one that has failed might be completely meaningless.
If you want to have each assertion independent of the others then you need to break it into several scenarios with each of you current And
steps as its own Then
step. You might be able to use a Background step to do the common setup.
I'm not sure that this will help you though as it seems like your assertions are all related to the examples so you end up needing to repeat the examples.
Upvotes: 1