【问题标题】:Should Assertions be performed in BDD Given and When是否应该在 BDD Given 和 When 中执行断言
【发布时间】:2017-02-20 18:31:23
【问题描述】:

在编写自动化功能测试的行为驱动开发风格中,一般认为Givens应该是系统必须处于的先决条件,才能开始测试,何时 应该是用户执行的操作,然后 应该断言观察到的是否与预期匹配并相应地失败或通过测试。

我的团队也开始在 Givens 和 Whens 中执行断言,这让我怀疑这是否是正确的做法。

例如 -

Given a user with xyz privileges is logged in
When I click on the abc tab
Then records should be displayed

这个测试中的 Given 是否应该断言登录的用户确实具有 xyz 权限,或者假设用户具有所需的权限并只执行登录

When 还应该断言该选项卡在单击之前可见吗?

【问题讨论】:

    标签: cucumber bdd


    【解决方案1】:

    如果“登录”是一种有趣的行为*并且您需要示例来说明它**,那么它应该是“何时”,它发生的上下文是“给定的”,以及产生的结果成为“当时”。

    这适用于您需要举​​例说明的任何行为。

    但是,有时在 Given 中进行断言可能很有用,只是为了检查上下文是否确实设置正确。有时,当人们开始采用 BDD 时,环境可能会有点不稳定,很容易知道是您的场景发现了导致它失败的错误,还是在流程的早期阶段。因此,出于这个原因,您可能会在那里找到断言。

    Given 并不关心系统如何进入那个状态。如果它有断言,它应该只是检查它是否是。

    我见过的另一种形式是检查系统是否处于上下文的正确状态,如果不是,则采取纠正措施。

    请注意,这些主要是临时模式。在团队采用 BDD 并使其管道和自动化部署成形时,它们会很有帮助。

    检查“When”结果的断言是结果的一部分,因此也是“Then”的一部分。我无法想象在没有结果的情况下您需要检查“何时”的结果的情况。如果你有,请给我一个例子。

    We discourage using clicking and UI details in scenarios. 找出你想要达到的目标,然后去做。隐藏点击。

    大多数时候,自动化场景实际上并不是用来捕捉错误的;它们是活文档,可以帮助人们思考他们想要实现的目标以及系统已经完成的工作,从而鼓励良好的设计并从一开始就防止错误。

    我会说“导航到 ABC 选项卡”之类的话,然后就这样做;如果它不存在,你会得到一个相关的异常,而且这种情况不会像阅读场景的人那样频繁发生。

    * 它正在登录。它可能不是。
    ** 它正在登录。你可能没有。

    【讨论】:

    • 嗨,thanx 的答案 :) 如果它是测试的断言会发生什么? (例如Given this dataset sample(我怀疑我的同事明年需要更换)',When the dataset has salary information.And I compute the tax,Then the tax should be positive and less than the sallary)在这里我在When上设置了一个断言来测试不是程序而是我的测试,?
    • @ntg 关于 Givens 的一点是(从场景的角度来看)你如何获得它们并不重要。也许您从头开始创建它们。也许它们是数据集的一部分。也许,如果它们不存在,您就创建它们;或者您可能会查看它们是否存在,如果不存在则抛出错误。我过去使用的最后两种模式都是完全有效的。将它们保持在您的“给定”步骤内;可以从 Given 调用“Then”断言测试,因为一个场景的结果通常是另一个场景的上下文。重构,使重复的​​上下文或期望的结果清晰易读。
    • @ntg 刚刚意识到我的回答并不明确:除非您对设置工资信息的示例感兴趣,否则您的包含工资信息的数据集是给定的,而不是时间的一部分。计算税收是您正在行使的能力,因此这是“何时”部分; “何时”发生的状态是所有Givens的一部分。
    【解决方案2】:

    Givens 和 Whens 中的断言通常是步骤定义不成熟的一个指标。所以我可能会在我正在努力的步骤中加入一个,但我不会把它留在那里很长时间。

    我会执行你的步骤

    Given a user with xyz privileges is logged in

    有点像

    'Given a user with xyz privileges is logged in' do
      user = create_user(privileges: xyz)
      login_as user: user
    end
    

    我希望create_user 方法很快就会被信任并且不需要断言。 login_as 方法相同。 (如果这样的方法不能正常工作,你会认为很多场景都会被破坏)

    请注意这段代码如何清楚地表明有两件事正在发生,并提供/使用一个您希望许多其他 stepdefs 使用的 api。以及您可能想要保留的任何断言如何真正属于辅助方法而不是步骤 def。

    【讨论】:

      【解决方案3】:

      没有严格的规则,但是根据我的经验,我发现定义那里没有断言很方便,因此很清楚实际测试的是什么并且测试本身会运行得更快。

      如果您的 abc 选项卡未显示,则它不应是可单击的,然后在识别要单击的对象或执行下一步时测试将失败(取决于您使用的工具和方法)。

      但是,您应该确保测试的实际实现没有作弊,并且使用能够触发点击的内部组件,即使实际组件不是。

      关于Given还有一点,一般建议设置测试环境。这意味着您确保在您的系统中有一个用户并且该用户已经登录。在您设置它时这没有任何意义,但是如果发生任何故障,您应该快速失败以知道什么是错误的。

      【讨论】:

        【解决方案4】:

        通常我会小心在自动化代码的 Given 或 When 步骤中使用断言。

        但是,我在我的代码中到处都使用这样的登录步骤,因为如果使用得当,可以将步骤变成一个上下文而不是断言本身。

        例如:

        此用户是否已登录?

        • 是 => 什么都不做。
        • 否 => 注销,然后以该用户身份登录

        在您提供的示例中,我们知道我们需要特定用户登录才能使此方案正常工作,但是我们不知道是否有其他用户登录(之前可能已运行其他方案) .如果您将此步骤用作检查以确保正确的用户已登录(如我的示例中),它是上下文的一部分,它将加快自动化的运行时间,因为您不必登录在每个场景之前和之后注销。

        【讨论】:

        • 对我来说,失败的断言也会导致测试失败,因此检查与断言完全相同的条件以采取适当的行动实际上并不是断言。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-01
        • 1970-01-01
        相关资源
        最近更新 更多