Передача контекста из JUnit Runner в Cucumber Steps

Я использую Cucumber с бегуном JUnit. Я провожу тесты пользовательского интерфейса приложений с помощью Appium, но для этого вопроса это не имеет значения. Важно то, что я хочу повторно использовать функции и определения шагов в 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
    }

}

И почти то же самое для Android в CucumberAndroidTest.java:

@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 {
        ...
    }
}

Как передать driver из CucumberIOSTest/CucumberAndroidTest в конструктор шагов?

Проблема в том, что только экземпляр CucumberIOSTest/CucumberAndroidTest знает, хочу ли я протестировать теги iOS или Android. GenericSteps не может этого знать. Также я хочу запустить симулятор только один раз для всех тестов на каждой платформе соответственно.

Я попробовал DI, но не нашел способа передать экземпляр WebDriver, который я создал в JUnit Runner. Любые идеи?


person fabb    schedule 07.12.2016    source источник


Ответы (1)


Я думаю, что самым простым решением является использование шаблона проектирования Singleton. DriverFactory должен всегда возвращать один и тот же экземпляр WebDriver. Итак, внутри вашего DriverFactory добавьте «статический экземпляр WebDriver» и метод 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 выглядит так:

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

  @Given("^...$")
  public void ...() throws Throwable {
      ...
  }
}
person mackowski    schedule 07.12.2016
comment
Хм, это действительно работает, спасибо! Мне просто нужно также сбросить экземпляр WebDriver в @AfterClass, чтобы он работал правильно, когда я сначала запускаю тесты iOS, а затем тесты Android. - person fabb; 07.12.2016