Cucumber: 不能扩展定义步骤或钩子的类

3
我从别人那里接手了一个测试的大项目,其中主要的Java类是CommonSteps、CommonBase和CommonScript。它们目前的关系如下:
CommonSteps扩展自CommonBase CommonBase扩展自CommonScript
问题出在下一个方法上,当我尝试使用“mvn clean install”运行项目时:
@After
public void tearDown(Scenario scenario) {
  if (scenario.isFailed()) {
    // Take a screenshot...
    final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
    scenario.embed(screenshot, "image/png"); // ... and embed it in the report.
  }
}

我遇到了以下错误:
我该如何开始使用依赖注入,删除与继承有关的所有内容?

是否有限制,不得不扩展基类就能使用步骤或钩子类。您添加的代码非常标准。如果您将此方法剪切粘贴到另一个类或不扩展另一个步骤或钩子类的新类中,则应该可以正常工作。 - Grasshopper
为了重用相同的步骤定义,有人创建了一个名为CommonSteps的类,并将其包含在粘合路径中。因此,它的定义对测试中的所有特性文件都可用。然而,将此方法移动到另一个不扩展钩子类的类中是行不通的。 - Jesús
这个方法在哪个类中? - tom
可能是Cucumber类扩展步骤定义和钩子的重复问题。 - Roberto Pegoraro
4个回答

4
黄瓜在每个场景运行之前都会创建定义步骤的所有类的新实例。每当需要运行一个步骤时,它就会在这些实例中的一个上调用 stepdef 方法。
如果您在 A 类中定义了一个名为 foo 的 stepdef 方法并且您有一个扩展自 A 的 B 类,则会得到 a 和 b 实例。foo 方法将在这两个实例上都可用,并且黄瓜无法决定在哪个实例上调用方法。
这就是为什么我们不允许它的原因。
解决方案是使用组合而不是继承。您可以通过依赖注入来实现组合——Cucumber 支持几个流行的 DI 框架。

0

正如所述,Cucumber不允许您扩展步骤定义基类。我刚刚遇到了这个错误,试图在两个不同的集成测试配置文件中重用一套步骤定义(应用程序是SpringBoot+Java8,但至关重要的是,我们使用Groovy编写Cucumber步骤定义..)。

我找到的解决方案/解决方法是在Groovy trait中定义常见的可重用的注释步骤定义,然后有一个或多个具体类实现该trait,并简单地定义/覆盖来自trait的任何行为,最重要的是,声明我想要运行的Spring int-test配置文件。这似乎很有效。


0

我遇到了同样的问题,并按照这里描述的方法解决了它。

使用PicoContainer实现依赖注入和共享状态。

在此处您可以找到最新版本,考虑此帖子的日期:https://mvnrepository.com/artifact/io.cucumber/cucumber-picocontainer/7.2.3

您只需要添加PicoContainer的依赖项即可。无需进行任何配置。

我使用了构造函数依赖注入。我不知道PicoContainer是否支持其他类型的依赖注入,例如setter方法或注解。

考虑到您提到的类,在应用依赖注入时,它们应该像以下示例一样:

public class CommonScript {
}


public class CommonBase {
    private final CommonScript commonScript;

    public CommonBase(CommonScript commonScript) {
        this.commonScript = commonScript;
    }
}


public class CommonSteps {
    private final CommonBase commonBase;

    public CommonSteps(CommonBase commonBase) {
        this.commonBase = commonBase;
    }
}

按照上述结构,您可以:

  1. 创建步骤定义并在您的".feature"文件中重复使用它们;
  2. 定义钩子;
  3. 共享状态;

参考资料:


0

您可以在步骤定义中定义您的@Before或@After步骤,然后在基类中添加方法

步骤定义:

   @After
public void after(Scenario scenario) {
    this.scenario = scenario;
}

基类方法:

    public static Scenario scenario;

    public Scenario tearDown(Scenario scenario){

        if (scenario.isFailed()) {
    final byte[] screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
    scenario.embed(screenshot, "image/png"); 
   }
 return scenario;
 }

我没有看到tearDown()上的任何调用,它应该如何工作? - Čamo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接