我在 bdd / 小黄瓜中做错了什么?

What am I doing wrong in bdd / gherkin?

提问人:JosePepeDev 提问时间:7/26/2023 最后编辑:LunivoreJosePepeDev 更新时间:7/26/2023 访问量:39

问:

我正在学习 BDD,即行为驱动开发,虽然我抓住了拥有系统行为示例的“想法”,我们可以执行这些示例并通过这些示例来开发它,但我被困在如何正确编写场景(使用 gherkin)中,旨在简化自然语言到步骤之间的过渡......

让我们来看看。我目前在注册服务部门工作。

我目前的问题就在这篇文章中:

  Scenario: Successful registration
      Given that a user wants to register
      And is not registered
      When he enters his credentials
      And they are correct
      Then the system should register him

按以下步骤分解的内容如下...

   @Dado("that a user wants to register")
    public void que_un_usuario_desea_registrarse() {
        name = "Marcos";
        surname = "Perez";
        email = "[email protected]";
        cardId = "23432423";
        marcos = new User(name,surname,email,cardId);
    }

    @Dado("is not registered")
    public void no_esta_registrado() {
        fakeDB.removeIfExists(marcos);
    }

    @Cuando("he enters his credentials")
    public void introduzca_sus_credenciales() {
// This is an empty space because i have no idea of what should be in
    }

    @Cuando("they are correct")
    public void estas_sean_correctas() {
        logUpService.logUp(name, surname, email, cardId, fakeDB);
    }

    @Entonces("the system should register him")
    public void el_sistema_deberia_registrarlo() {
        assertEquals(marcos.hashCode(), fakeDB.persisted.hashCode());
    }

我试图改变需求的表达方式,但我仍然被困住了

  1. 像“用户想要注册”这样的无软件内容应该如何一步实现?

  2. 尽管我使用了一种测试替身(称为“fakeDB”),它返回与注册服务(称为“logUpService”)发送到其“存储”组件相同的用户实例,但我不太确定这是否是在“Then”子句上断言的最佳方式。

我非常有兴趣了解这一点,所以我很乐意阅读您的建议。

测试 TDD BDD 行为 敏捷

评论


答:

1赞 Lunivore 7/26/2023 #1

我发现考虑正在行使的能力是有用的。在这种情况下,用户可以执行哪些操作?

用户可以注册

行使这种能力(或试图为不愉快的道路)为我们提供了时间。通常,一个场景中只有一个 When。所以现在我们可以这样写:

When Marco registers with details <details go here>

理想情况下,结果应该是有价值的东西。他们为什么要注册?注册后会发生什么?

Then Marco should see the home page
And Marco should be logged in to his account.

(最后一步将检查显示某人已登录的相关图标等。

现在我们可以回到上下文:这种情况需要什么才能发生?它可能是这样的:

Given Marco is not already registered
And Marco has a valid email address at [email protected]

您会注意到,我没有包含任何有关用户想要的内容。从系统的角度来看,这并不重要。也许有人强迫 Marco 登录,而他实际上根本不想登录!它不会改变系统行为。

如果你觉得它有用,你当然可以包含该步骤,但如果你这样做,我会把它留空,并且不会在那里放任何自动化。

以下是整个场景:

Given Marco is not already registered
And Marco has a valid email address at [email protected]
When Marco registers with 
    email: [email protected], 
    name: Marco Perez, 
    card id: 23432423
Then Marco should see the home page
And Marco should be logged in to his account.

如果您的 BDD 工具不允许多行步骤,您可以将 Marco 的信息放入后台表或 Givens 中,然后将 When 缩短为“Marco 注册他的详细信息”。在这种情况下,仍然应该只有一个 When。

我不会使用 FakeDB 作为验证结果的一种方式;当然不是一个人。您是从用户的角度看待系统,因此也要寻找他们想要的结果。

评论

0赞 JosePepeDev 7/27/2023
谢谢Lunivore!我发现非常有价值的部分是,在这种情况下,不重视不会改变系统行为的东西,就像用户(在系统中注册)的愿望一样。最后一点,虽然我明白了从用户的角度看系统的意义,但我没有发现注册服务如何帮助 Marco 查看主页......据我所知,该组件应该提供用户的数据持久性和一些业务逻辑(如数据验证等)......如果你像我一样在某个功能部门工作,你会怎么做?
0赞 Lunivore 7/28/2023
@JosePepeDev我不会从登录开始;没什么有趣的。从提供新功能的任何功能开始。您有一个用户。他们已登录。他们登录的目的是什么?可能这已经接近用户旅程的尾声,但尽早这样做意味着你可以更快地发现你不知道的东西。
0赞 Lunivore 7/28/2023
@JosePepeDev 如果您已经开始登录,请创建一个非常基本的主页 - “hello world”样式 - 并在用户登录时稍后更新。在真正的功能到来之前,可以做一个替身进行测试。不仅要考虑组件的行为,还要考虑它的价值,以及如何证明已经实现了这一点。
1赞 Barnaby Golden 7/26/2023 #2

通常,“用户想要注册”步骤将通过 UI 操作(例如单击注册按钮)实现。

对于测试,我将寻找两个独立的东西:

  • 用户是否已注册?通常,这将使用方法进行检查。其中重要的部分是让您确定确定它们是否已注册的唯一信息。也许他们的卡ID?.isRegistered()isRegistered(cardId)

  • 用户存储的数据是否与用户在注册时提交的数据相同。