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

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

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

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

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

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

预先感谢您的帮助!

我建议你使用pico-container作为dependency injection框架与cucumber-jvm一起使用。

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

  info.cukes cucumber-picocontainer 1.2.3 test  

例:

具有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的其他类。

 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(); } } 

希望能帮助到你。

这个问题已经过时了,我在问这个问题后不久就离开了项目,但我回过头来看看我们放置的代码(使用单例模式),这就是我们最终得到的结果。 我忘记了为什么我们不能使用pico-container (它可能是一个组织约束)但是如果你可以使用额外的库我记得那个解决方案运行良好。

我将把它作为公认的答案,但希望这个解决方案对于那些发现自己处于几年前我的类似位置的人来说非常有用。

 public class TestingBase { private static TestingBase instance; private static WebDriver driver; private static Thread CLOSE_DRIVER = new Thread() { @Override public void run() { driver.close(); } }; static { Runtime.getRuntime().addShutdownHook(CLOSE_DRIVER); } private TestingBase() { DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); desiredCapabilities.setJavascriptEnabled(true); desiredCapabilities.setCapability("takesScreenshot", false); desiredCapabilities.setCapability("handlesAlerts", true); desiredCapabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, new String[]{ "--web-security=false", "--ssl-protocol=TLSv1", "--ignore-ssl-errors=true", "--webdriver-loglevel=ERROR", "--webdriver-logfile=/var/log/phantomjs/ghostrdriver.log" }); desiredCapabilities.setCapability("elementScrollBehavior",true); driver = new PhantomJSDriver(desiredCapabilities); } public static TestingBase getTestingBase() { if (instance == null) { instance = new TestingBase(); } return instance; } public static WebDriver getDriver() { return getTestingBase().driver; } }