如何在 cucumber-jvm 步骤之间传递变量

2022-01-22 00:00:00 cucumber java cucumber-jvm

为了在步骤之间传递变量,我让步骤方法属于同一个类,并使用类的字段来传递信息.

To pass variables between steps I have the step methods belong to the same class, and use fields of the class for the passed information.

下面是一个例子:

Feature: Demo

  Scenario: Create user
    Given User creation form management
    When Create user with name "TEST"
    Then User is created successfully

带有步骤定义的Java类:

Java class with steps definitions:

public class CreateUserSteps {

   private String userName;

   @Given("^User creation form management$")
   public void User_creation_form_management() throws Throwable {
      // ...
   }

   @When("^Create user with name "([^"]*)"$")
   public void Create_user_with_name(String userName) throws Throwable {
      //...
      this.userName = userName;
   }

   @Then("^User is created successfully$")
   public void User_is_created_successfully() throws Throwable {
      // Assert if exists an user with name equals to this.userName
   }

我的问题是,在步骤之间共享信息是否是一种好习惯?或者最好将特征定义为:

My question is if it is a good practice to share information between steps? Or would be better to define the feature as:

Then User with name "TEST" is created successfully

推荐答案

为了在步骤之间共享共性,您需要使用 世界.在 Java 中,它不像在 Ruby 中那样清晰.

In order to share commonalities between steps you need to use a World. In Java it is not as clear as in Ruby.

引用 Cucumber 的创建者.

Quoting the creator of Cucumber.

世界"的目的是双重的:

The purpose of a "World" is twofold:

  1. 在场景之间隔离状态.

  1. Isolate state between scenarios.

在场景中的步骤定义和挂钩之间共享数据.

Share data between step definitions and hooks within a scenario.

实现方式因语言而异.例如,在红宝石中,步骤定义中的隐式 self 变量指向当前场景的 World 对象.这是默认情况下的一个实例对象,但如果你使用 World 钩子,它可以是任何你想要的东西.

How this is implemented is language specific. For example, in ruby, the implicit self variable inside a step definition points to the current scenario's World object. This is by default an instance of Object, but it can be anything you want if you use the World hook.

在 Java 中,您有许多(可能连接的)World 对象.

In Java, you have many (possibly connected) World objects.

Cucumber-Java 中 World 的等价物是 所有的对象带有钩子或 stepdef 注释.换句话说,任何类使用@Before、@After、@Given 等注释的方法将是每个场景只实例化一次.

The equivalent of the World in Cucumber-Java is all of the objects with hook or stepdef annotations. In other words, any class with methods annotated with @Before, @After, @Given and so on will be instantiated exactly once for each scenario.

这样就实现了第一个目标.为了实现第二个目标,你有两个方法:

This achieves the first goal. To achieve the second goal you have two approaches:

a) 为所有步骤定义和挂钩使用一个类

a) Use a single class for all of your step definitions and hooks

b) 使用按职责划分的多个类 [1] 并使用依赖项注入 [2] 将它们相互连接.

b) Use several classes divided by responsibility [1] and use dependency injection [2] to connect them to each other.

选项 a) 很快失效,因为您的步骤定义代码变得一团糟.这就是人们倾向于使用 b) 的原因.

Option a) quickly breaks down because your step definition code becomes a mess. That's why people tend to use b).

[1] https://cucumber.io/docs/gherkin/step-organization/

[2] PicoContainer、Spring、Guice、Weld、OpenEJB、Needle

[2] PicoContainer, Spring, Guice, Weld, OpenEJB, Needle

可用的依赖注入模块有:

The available Dependency Injection modules are:

  • 黄瓜微型容器
  • 黄瓜酱
  • 黄瓜-openejb
  • 黄瓜春
  • 黄瓜焊缝
  • 黄瓜针

原帖在这里 https://groups.google.com/forum/#!topic/cukes/8ugcVreXP0Y.

希望这会有所帮助.

相关文章