将上下文从JUnit Runner传递到Cucumber Steps

时间:2016-12-07 08:27:57

标签: android ios junit appium cucumber-junit

我使用Cucumber和JUnit跑步者。我使用Appium进行应用程序UI测试,但这对于这个问题无关紧要。相关部分是我想在iOS和Android上重用功能和步骤定义,并且将selenium驱动程序实例从JUnit传递到步骤,因为我只想启动测试服务器一次。

我有这样的事情:

login.feature

Feature: Login
@android_phone @ios_phone
Scenario: Successful login
    Given ...

CucumberIOSTest.java

@RunWith(Cucumber.class)
@CucumberOptions(
        glue = {"classpath:my.stepdefinitions"},
        tags = {"@ios_phone,@ios_tablet"}
)
public class CucumberIOSTest {

    private static WebDriver driver;

    @BeforeClass
    public static void setUp() throws Exception {
        // setup code that starts up the ios simulator via appium 
        driver = DriverFactory.createIOSDriver();
    }

    @AfterClass
    public static void tearDown() {
        // shutdown ios simulator
    }

}

CucumberAndroidTest.java中的Android几乎相同:

@RunWith(Cucumber.class)
@CucumberOptions(
        glue = {"classpath:my.stepdefinitions"},
        tags = {"@android_phone,@android_tablet"}
)
public class CucumberAndroidTest {

    private static WebDriver driver;

    @BeforeClass
    public static void setUp() throws Exception {
        // setup code that starts up the android simulator via appium 
        driver = DriverFactory.createAndroidDriver();
    }

    @AfterClass
    public static void tearDown() {
        // shutdown android simulator
    }

}

这些步骤位于GenericSteps.java(现在只有一个文件):

public class GenericSteps {
    public GenericSteps(WebDriver driver) {
        this.driver = driver;
    }

    @Given("^...$")
    public void ...() throws Throwable {
        ...
    }
}

如何将driverCucumberIOSTest / CucumberAndroidTest传递给Steps构造函数?

问题是只有CucumberIOSTest / CucumberAndroidTest实例知道我是否要测试iOS或Android代码。 GenericSteps无法知道这一点。另外,我只想分别为每个平台上的所有测试启动模拟器。

我尝试了DI,但是我没有找到一种方法来传递我在JUnit Runner中创建的WebDriver实例。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我认为最简单的解决方案是使用Singleton设计模式。 DriverFactory必须始终返回相同的WebDriver实例。所以在你的DriverFactory中添加'static WebDriver instance'和getWebDriver()方法。

public final class DriverFactory {
  private static WebDriver instance = null;

  public static synchronized WebDriver getWebDriver() {
      if (instance == null) {throw RuntimeException("create WebDriver first")};
      return instance;
  }
  public static synchronized WebDriver createAndroidDriver() {
      if (instance == null) { 
         // setup code that starts up the android simulator via appium 
         instance  = yourWebDriver
      }
      return instance;
  }
  ...
}    

现在您的GenericSteps cal看起来像这样:

public class GenericSteps {
  public GenericSteps() {
      this.driver = DriverFactory.getWebDriver();
  }

  @Given("^...$")
  public void ...() throws Throwable {
      ...
  }
}