简体   繁体   English

如何编写基于先前功能的 Cucumber 测试?

[英]How Do I Write Cucumber Tests That Build On Previous Features?

I have started using Cucumber to write BDD tests to match the business use cases for my application.我已经开始使用 Cucumber 来编写 BDD 测试以匹配我的应用程序的业务用例。 It is blockchain based so each user in the test is running an instance of the application.它是基于区块链的,因此测试中的每个用户都在运行应用程序的一个实例。 This also means that each test is quite heavy and 95% of the test time is in the setup stage.这也意味着每次测试都非常繁重,95% 的测试时间都在设置阶段。

As I write the tests I am finding that I am starting to repeat myself and the earlier features are seemingly becoming redundant.当我编写测试时,我发现我开始重复自己,早期的功能似乎变得多余了。

One business flow is:一种业务流程是:

  • User1 saves a new message User1 保存一条新消息
  • User2 edits the message User2 编辑消息
  • User1 verifies the edit User1 验证编辑
  • User1 cancels the message User1 取消消息
  • User2 acknowledges cancellation User2 确认取消

This gets broken down into New/Edit/Cancel features.这被分解为新/编辑/取消功能。

Initially I started out with "New" and "Edit" feature files looking like this:最初,我从“新建”和“编辑”功能文件开始,如下所示:

New新的

Feature: a new message is added

  Scenario: a user adds a new message
    Given there is a user called User1
    And there is a user called User2
    When User1 creates a new message with id 1234
    Then User2 should see the message with id 1234

Edit编辑

Feature: Editing a message

  Scenario: A User edits a message
    Given there is a user called User1
    And there is a user called User2
    When User1 creates a new message with id 1234
    And User2 adds the location US to the message
    Then User1 should see the location US on the message

But now I am coming on to the Cancel part I realise that in order to test the Cancel properly, the system needs to have an edited message which means I need to have gone through the New and Edit features to get the message into the right state.但是现在我要进入取消部分,我意识到为了正确测试取消,系统需要有一个编辑过的消息,这意味着我需要通过新建和编辑功能才能将消息放入正确的 state .

This would make the Cancel look something like this, which then is starting to get quite lengthy:这将使取消看起来像这样,然后开始变得很长:

Cancel取消

Feature: Cancelling a message

  Scenario: A User cancels a message
    Given there is a user called User1
    And there is a user called User2
    When User1 creates a new message with id 1234
    And User2 adds the location US to the message
    And User1 cancels the message
    Then User2 should see status Cancelled on the message

I could write the Cancel like this instead:我可以这样写取消:

Feature: Cancelling a message

  Scenario: A User cancels a message
    Given there is a message with id 1234
    And User1 cancels the message
    Then User2 should see status Cancelled on the message

which reads quite well as a feature, however, I would now have to write a step definition for "there is a message with id 1234" that does everything that the Edit feature was doing.它作为一个功能读起来很好,但是,我现在必须为“有一条 id 为 1234 的消息”编写一个步骤定义,它可以完成编辑功能所做的一切。

As mentioned at the start, the setup in these tests takes 95% of the test time so ideally I would like to run these as a series of steps together rather than starting from fresh for each feature.如开头所述,这些测试中的设置需要 95% 的测试时间,因此理想情况下,我希望将这些作为一系列步骤一起运行,而不是从每个功能的全新开始。 eg例如

  • Do the setup once进行一次设置
  • Create a New message创建新消息
  • Edit the message编辑消息
  • Cancel a message取消消息

Is it possible to chain the scenarios or features together and reuse the system state from the previous one?是否可以将场景或功能链接在一起并重用上一个系统 state?

Or do I have to start the system from scratch each time?还是我每次都必须从头开始启动系统?

Is a step definition that calls all the other steps/methods that make up the Edit feature the right way to go for the Cancel or should I write lots of And statements?一个步骤定义是否调用了构成编辑功能的所有其他步骤/方法以正确的方式调用 go 用于取消,或者我应该写很多 And 语句?

I can understand your frustrations with this, but there is no way to have subsequent features build on each other.我可以理解您对此的不满,但没有办法让后续功能相互构建。 Each scenario is meant to be atomic and repeatable.每个场景都意味着是原子的和可重复的。 The problem with scenarios depending on each other is a failed scenario will cause cascading failures in the scenarios that follow.场景相互依赖的问题是一个失败的场景将导致后续场景中的级联故障。 One failure in the application triggers multiple failed tests, causing your team to start thinking the tests are flakey.应用程序中的一次失败会触发多次失败的测试,导致您的团队开始认为测试是不稳定的。

There is nothing wrong with writing a step that simulates the previous scenarios — this is the right way to do it.编写一个模拟先前场景的步骤并没有错——这是正确的做法。 When defining those steps, keep them as atomic as possible so they are very composable.在定义这些步骤时,请尽可能保持它们的原子性,以便它们非常可组合。

To be honest, a 6 step scenario is perfectly fine.老实说,一个 6 步的场景非常好。 The only change I would suggest is making Given versions of your steps.我建议的唯一更改是制作您的步骤的Given版本。 The cancel scenario looks like it has to many When 's.取消场景看起来有很多When

Feature: Cancelling a message

  Scenario: A User cancels a message
    Given there is a user called User1
    And there is a user called User2
    And User1 created a new message with id 1234
    And User2 added the location US to the message
    When User1 cancels the message
    Then User2 should see status Cancelled

Original : You could pull the code out of each of the setup steps and make them functions, call the functions as the code to the steps (performing the same tasks as before), and create a new setup step calling those functions, which would mean they'd have a shared implementation原文:您可以将代码从每个设置步骤中提取出来并使其发挥作用,将函数作为步骤的代码调用(执行与以前相同的任务),并创建一个调用这些函数的新设置步骤,这意味着他们会有一个共享的实现

Alternative : write a tagged Before hook that knows the state of the system under test , even if it is just whether the setup step has occurred, and use that information to reset the system for those scenarios.替代方法:编写一个标记的 Before 钩子,它知道被测系统的 state ,即使它只是设置步骤是否发生,并使用该信息为这些场景重置系统。 You could even perform health checks here to ensure that a full reset can happen if the system needs it.您甚至可以在此处执行运行状况检查,以确保在系统需要时可以进行完全重置。

Or even put this code into the steps themselves, and let them know to skip sections if the health checks have passed (most likely an if statement)或者甚至将这段代码自己放入步骤中,并让他们知道如果健康检查已通过则跳过部分(很可能是 if 语句)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Cucumber-junit 设置 Cucumber 特征的路径? - How do I set the path to my Cucumber features using cucumber-junit? Maven如何使用功能订购来运行测试? - How do I do Maven to run tests using the features ordering? 如何使 Cucumber 功能在 Android 项目中作为本地单元测试运行? - How to make Cucumber features run in an Android project as local unit tests? 如何使用黄瓜JVM,黄瓜Serenity和SerenityObjectFactory进行多态测试 - How do I get polymorphic tests working with cucumber-jvm, cucumber-serenity and SerenityObjectFactory 如果 Cucumber 特征文件中有 1000 个特征文件,我只想执行偶数个特征文件。 怎么做? - If there are 1000 features files in Cucumber feature file and I want to execute only even feature files. how to do that? 如何将正确的Spring上下文连接到我的Cucumber测试? - How do I wire up the correct Spring context to my Cucumber tests? 我的 rest 服务依赖于外部服务。 如何模拟它以在我的 cucumber 测试中使用? - My rest services relies on an external service. How do I mock it to use on my cucumber tests? 如何在browserstack黄瓜java功能并行运行? - How can I run in browserstack cucumber java features in parallel? 使用黄瓜运行多个测试功能以进行 java selenium 宁静测试 - Running multiple tests features with cucumber for java selenium serenity tests 如何运行多个黄瓜功能? - How to run multiple cucumber features?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM