本文介绍了在步骤定义文件之间共享相同的selenium WebDriver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我们正在努力采用Cucumber在我们的Java8 / Spring应用程序上运行功能测试。我们希望我们的步骤定义文件尽可能保持DRY,因此计划在不同的功能文件中使用相同的步骤定义。由于我们使用selenium WebDriver 来驱动我们的测试,我们需要在步骤定义之间共享相同的驱动程序。

Right now we're working on adopting Cucumber to run functional tests on our Java8/Spring app. We want our step definition files to remain as DRY as possible and as such plan on using the same step definitions in different feature files. Since we are using a selenium WebDriver to drive our tests, we need to share the same driver between step definitions.

为了说明为什么有多个驱动程序对我们来说是一个问题,想象一个功能文件定义了两个步骤:一个导航​​到一个页面,另一个断言该页面上出现一条线。如果两个步骤碰巧在单独的文件中定义,则第一步定义将使用其驱动程序导航到该页面。到第二步定义运行针对其驱动程序的断言时,它还没有导航到页面(因为这些操作转到了另一个驱动程序)并且测试失败。

To demonstrate why having multiple drivers is an issue for us, imagine a feature file that defines two steps: one to navigate to a page, and another to assert that a line appears on that page. If both steps happen to be defined in separate files, the first step definition will use its driver to navigate to the page. By the time the second step definition runs the assertion against its driver it hasn't navigated to the page (since those actions went to the other driver) and the test fails.

我们尝试实现每个步骤定义文件将扩展的基类(包含驱动程序)。事实证明,Cucumber实例化了每个步骤定义类的实例,因此我们最终得到的每个步骤定义都有不同的 WebDriver 实例。

We tried implementing a base class (that contains the driver) that each step definition file would extend. As it turns out Cucumber instantiates an instance of each step definition class, and therefore we end up with each step definition having different WebDriver instances.

我们考虑过在每个步骤定义文件中使用Spring注入 WebDriver 的实例,但我相信这会导致上述相同的问题。

We thought about using Spring to inject an instance of the WebDriver in each step definition file, but I believe this would cause the same problem described above.

我知道单身模式可以用来实现这一目标,但是我们的模式看起来像是一个常见的问题而单身模式就像是矫枉过正。这实际上是接近它的正确方法吗?或者我错过了一些非常明显的东西?

I know that the singleton pattern can be used to achieve this, but ours seems like such a common problem and the singleton pattern feels like overkill. Is this actually the right way to approach it? Or am I missing something really obvious?

提前感谢您的帮助!

推荐答案

我建议您使用作为依赖注入框架与 cucumber-jvm 一起使用。

I reccomend you to use pico-container as a dependency injection framework to use with cucumber-jvm.

使用PicoContainer,您可以拥有一个带有实例的基础类WebDriver,然后将此基类自动传递给任何其他类。如果您愿意,甚至可以直接传递网络驱动程序。

With PicoContainer, you can have a 'base' class with the instance of WebDriver, and then pass this base class automactically to any other class. Or even you could pass directly the web driver if you prefer.

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>1.2.3</version>
    <scope>test</scope>
</dependency>

示例:

基类与WebDriver的实例:

Base class with the instance of WebDriver:

public class ContextSteps {

   private static boolean initialized = false;

   private WebDriver driver;

   @Before
   public void setUp() throws Exception {
      if (!initialized) {
         // initialize the driver
         driver = = new FirefoxDriver();

         initialized = true;
      }
   }

   public WebDriver getDriver() {
      return driver;
   }
}

通过pico-container DI访问webDriver的其他类。

Other class who access webDriver through pico-container DI.

public class OtherClassSteps {

   private ContextSteps contextSteps;

   // PicoContainer injects class ContextSteps
   public OtherClassSteps (ContextSteps contextSteps) {
      this.contextSteps = contextSteps;
   }


   @Given("^Foo step$")
   public void fooStep() throws Throwable {
      // Access WebDriver instance
      WebDriver driver = contextSteps.getDriver();
   }
}

希望有所帮助。

这篇关于在步骤定义文件之间共享相同的selenium WebDriver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 13:52