当前位置: 首页 > 知识库问答 >
问题:

Cucumber JVM认为所有(@Given、@When、@Then)注释都是可互换的

琴俊良
2023-03-14

我很残酷地注意到,在cucumber-JVM中,当您定义步骤名称看似相同的特性时,它们被认为是可以互换的。

Feature: Grab that cash with both hands and make a stash

  Scenario: Spend it
    Given Jack has 5 dollars
    When  Jack wants to buy Lear Jet
    Then  He doesn't have enough cash

  Scenario: acquire it
    Given Jack is broke
    But   his wealth is slowly growing
    When  Jack has 5 dollars
    Then  He can afford a pack of gum

  Scenario: own it
    Given Jack is broke
    But   he has a job that's paid 5 dollar an hour
    When  He works an hour
    Then  Jack has 5 dollars
@Given("^Jack has 5 dollars$")
public void set_it() throws Throwable {
    this.jack = new Person();
    jack.setCashAmount(5);
}

@When("^Jack has 5 dollars$")
public void wait_it() throws Throwable {
    jack.waitFor(wealth(is(equalTo(5))));
}

@Then("^Jack has 5 dollars$")
public void check_it() throws Throwable {
    assertThat("Jack should have 5 dollars by now",
               jack.getCashAmount(),
               is(equalTo(5)));
}

我用cucumber运行这个功能(使用 mvn/intelliJ 插件/日食插件/神奇水晶球/其他荒谬的媒介)

我收到以下消息:

cucumber.runtime.DuplicateStepDefinitionException: Duplicate step definitions in my.project.MySteps.wait_it() in file:[...] and my.project.MySteps.set_it() in file:[...]
    at cucumber.runtime.RuntimeGlue.addStepDefinition(RuntimeGlue.java:33)
    at cucumber.runtime.java.JavaBackend.addStepDefinition(JavaBackend.java:151)
    at cucumber.runtime.java.MethodScanner.scan(MethodScanner.java:68)
    at cucumber.runtime.java.MethodScanner.scan(MethodScanner.java:41)
    at cucumber.runtime.java.JavaBackend.loadGlue(JavaBackend.java:86)
...

还有其他一些无关紧要的台词,我会饶恕你的。

cucumber似乎没有区别@给定("a")@当("a")@然后("a")(和@和@但是我真的不知道它们最初是为了什么,因为这些只是“和我刚刚做的一样”的语法糖)

但是正如实现所表明的,这三个步骤彼此之间有很大的不同。每一句都恰当地描述了测试应该做什么,随后的实现是明确的。

    < li >“给定”步骤应设置测试前提条件 < li >一个“何时”步骤应该触发一个操作或等待一个操作 < li >“然后”步骤应该在之后声明系统的状态。

我在那里错过了什么?

有没有办法告诉 Cucumber 如何不仅依赖正则表达式,还依赖步骤类型(对我来说,这应该是默认行为)?

共有2个答案

韩欣怿
2023-03-14

您的诊断是正确的——注释并不重要,只有正则表达式才重要。

此外,您可以使用自己喜欢的语言定义自己的注释集作为关键字。您如何理解和使用它们取决于您。

查看一下< code>cucumber-java.jar -您会在< code>cucumber.api.java包(也包括非拉丁字母)中找到不同语言的不同注释集,例如< code > en _ pirate version:< code > Avast ,< code>Aye,< code>Blimey,< code > bridge ,< code > Letgoandhaul ;)

它们中的每一个都没有特定的顺序或语义 - 它们只是正则表达式持有者。

编辑

批注独立于功能文件中使用的表达式。您可以在功能文件中使用默认的给定/时间/然后和en_pirate AvastAyeBlimey 注释 - Cucumber 将匹配它们。

但是,功能文件本身由Gherkin解析器解析(正如下面@Ar3s正确指出的那样),您可以使用受支持的口语之一,而不是通过将

#language: <language code, eg. fr>

在特征文件的第一行。您可以在Gherkin i18n JSON中找到默认英语关键字和其他语言之间的映射。尽管如此,特征文件的语言和注释的语言不需要匹配。

微生嘉
2023-03-14

是的,这就是它应该如何工作。步骤名称本身应该足够清楚,可以看出它是关于测试设置(给定)、某个操作(When)还是验证结果(Then)。

动作步骤通常可以这样措辞,它包含一个动词,为了区分设置和断言,我同意这有时是相当困难的。在这里,您必须提出自己的约定,一种可能性是:

Given Jack is broke
 When Jack earns 5 dollars
 Then Jack should have 5 dollars
 类似资料:
  • 我知道可以使用特定于领域的语言在cucumber中编写接受用例,但是在实现这些步骤时,@givid、@when、@then注释在步骤定义中使用,那么如果不需要使用dataprovider或分组或并行执行并使用IDE运行,那么是否需要TestNg或Junit? 因为@test通常用于只使用TestNg的完整测试场景,所以当也使用Cucumber时,是否需要使用@test注释?如果是,那么它如何与@g

  • 在将来还有一些zip()满足不了的场景。如复杂的架构,或者是仅仅为了个人爱好,你可以使用And/Then/When解决方案。它们在RxJava的joins包下,使用Pattern和Plan作为中介,将发射的数据集合并到一起。 我们的loadList()函数将会被修改从这样: private void loadList(List<AppInfo> apps) { mRecyclerView

  • 我使用的是:Wildfly 8.2、JSF 2.2(Mojarra 2.2.8)、Omnifaces 2.1和Java7。 问题是我已经创建了一些对象,并且每个请求都会被重新创建(null)。我也尝试过使用conversationScope,但同样的情况也发生了。 使用会话范围它的工作原理。 控制器: 每次回发时,都是,导致NPE。 视图: 我已经做了一些测试,在没有primefaces的情况下执

  • 功能:LinkedIn注册我想将此模板用于我的功能文件 @nimit场景大纲:验证LinkedIn网站是否启动并运行给定环境是否启动以使用TestData验证LinkedIn网站”“当用户导航到LinkedHome页面时,欢迎页面应显示给用户然后'立即加入 公共类LinkedSignupScenarios { }

  • And/Then/When 使用Pattern和Plan作为中介,将两个或多个Observable发射的数据集合并到一起 And/Then/When操作符组合的行为类似于zip,但是它们使用一个中间数据结构。接受两个或多个Observable,一次一个将它们的发射物合并到Pattern对象,然后操作那个Pattern对象,变换为一个Plan。随后将这些Plan变换为Observable的发射物。

  • 我正在开发一个使用 JPA 和Hibernate的项目,我刚刚注意到实体没有任何关系注释,例如@ManyToOne、@OneToOne等。所以我的问题是,JPA / Hibernate是否为每个案例添加了默认注释? 这里有一个例子 JPA是否默认在此属性中添加@OneTo的注释?