【问题标题】:SpecFlow report all assertions even if one failsSpecFlow 报告所有断言,即使一个失败
【发布时间】:2014-07-11 07:25:20
【问题描述】:

有谁知道 SpecFlow 是否可以做到这一点?本着每个测试不超过一个断言的精神,我希望 SpecFlow 将每个“Then”视为一个单独的测试。

我有一个包含多个“然后”步骤的场景,看起来像这样 (sn-p):

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        |

第二个断言“My Well --oops!”应该失败。我想要的是让 SpecFlow 测试以下断言

我明白了:

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>. 

我想要什么:

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>. 

【问题讨论】:

    标签: bdd specflow


    【解决方案1】:

    我不相信你能做到这一点,但我的问题是你为什么要那样做?对于任何单元测试,它都会在第一个断言处失败。您不会期望测试在断言失败后继续执行,这也不例外。当然知道测试由于某种原因失败就足够了。在这种特定情况下,您可能能够做出单独的独立断言来提供有用的信息,但在一般情况下,在失败之后的断言可能完全没有意义。

    如果您想让每个断言独立于其他断言,那么您需要将其分解为几个场景,每个当前的And 步骤都作为自己的Then 步骤。您或许可以使用后台步骤来进行常见设置。

    我不确定这是否会对您有所帮助,因为您的断言似乎都与示例相关,因此您最终需要重复示例。

    【讨论】:

    • 我已经缩短了我的断言列表。实际上,我有大约 10 个。但是,我仍然认为这是一个单一的场景。此特定场景表示按天聚合。无论哪一天,一些值都应该是相同的(例如井号、井名),而一些值应该在不同的日子里不同(违规、差异)
    • 无论如何,我不认为,例如,“所有聚合的名称应该相同”是一个场景。该场景是根据这些详细信息生成一个聚合......也许类似的场景是复制一个实体。根据业务规则,预期某些属性将被复制,而其他属性则为空。因此,“复制”将是场景,需要进行多项测试来验证复制是否正常工作。复制可以被认为是一项功能,但我们仍然会有不同的变化,这将是不同的场景。
    • @CamperWill 我明白它们不是不同的场景,我的意思是我不认为你可以得到你想要的没有将断言分成不同的场景.正如我所说,您可能不想这样做。每个都只是一个带有多个断言的单元测试,因此测试将在第一个失败的断言处失败。您也许可以改变生成单元测试的方式,但我不确定这样做会有多大好处
    • 谢谢,山姆。在过去('08 或 '09),我似乎记得使用 SpecUnit(没有 Gherkin),其中类名代表场景,我们会编写多个测试方法,每个断言一个。
    【解决方案2】:

    如果您升级到 Specflow 2.4 并使用 Nunit,您现在可以执行此操作,请参阅 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");
    });
    

    【讨论】:

      【解决方案3】:

      我已经确定了一种方法来做到这一点。那么在specflow内部发生了什么,在运行任何步骤之前,TestExecutionEngine会检查Scenario的LastExecutionStatus,如果不是OK..那么我们可以做的是,在[AfterStep]钩子中添加以下内容行:

      typeof(ScenarioContext).GetProperty("ScenarioExecutionStatus").SetValue(this.ScenarioContext, ScenarioExecutionStatus.OK);

      this.ScenarioContext 替换为存在的任何具有ScenarioContext 类型的对象。这将使当前状态为 OK,并允许您继续下一步。

      请记住,这不会让您在一个步骤中捕获所有断言失败。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-11
        • 1970-01-01
        • 2017-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-21
        相关资源
        最近更新 更多