在步骤定义文件之间共享相同的selenium WebDriver

dav*_*cus 4 java selenium spring cucumber-jvm

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

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.

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.

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?

Thank you in advance for your help!

tro*_*oig 7

我建议你使用pico-container作为依赖注入框架来使用cucumber-jvm.

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

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>1.2.3</version>
    <scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)

例:

具有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;
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
   }
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.