首页 > 解决方案 > 并行运行 Cucumber 场景时可以重用驱动程序实例吗?

问题描述

我编写了一个 Cucumber TestNG 测试,它并行运行多个测试。目前我为每个场景创建驱动程序,我的 Hooks 类如下所示。

public class Hooks {


    private TestContext testContext;

    @Inject
    public Hooks(TestContext testContext) {
        this.testContext = testContext;
    }

    @Before
    public void initializeTestContext(final Scenario scenario) {
        this.testContext.initializeContext();
    }


    @After
    public void after(final Scenario scenario) {
        LOG.debug("Executing After Hook");
        if (shouldScreenshot(scenario)) {
            embedScreenshotToReport(scenario);
        }
        this.testContext.destroyContext();
    }

    @Before("@skip_scenario")
    public void skipScenario(Scenario scenario) {
        LOG.info("Skipping scenario: {}", scenario.getName());
        Assume.assumeTrue(false);
    }

    private boolean shouldScreenshot(Scenario scenario) {
        return scenario.isFailed() && Screenshot.isRequired();
    }

    private void embedScreenshotToReport(Scenario scenario) {
        final byte[] screenshot = ((TakesScreenshot) testContext.getWebDriver()).getScreenshotAs(OutputType.BYTES);
        scenario.embed(screenshot, "image/png");
    }
}

我的 TestsContext 类如下所示。

@ScenarioScoped
public class TestContext extends WebUITest {

    private static final String DEFAULT_DRIVER_NAME = "default";

    private WebDriver webDriver;

    public WebDriver getWebDriver() {
        return this.webDriver;
    }

    public void initializeContext() {
        System.out.println("DEBUGGING Test Context: driver created");
        this.webDriver = initializeDriver(URL.getTestHostURL(), DEFAULT_DRIVER_NAME);
    }

    public void destroyContext() {
        System.out.println("destory method called");
    }
}

我的带有 TestNG 的 Runner 类如下所示。

    glue = {"com.cucumber.test.glue.hook",
                "com.cucumber.test.glue.stepdef" },
        features = "features/MyFeature.feature",
        plugin = {"pretty", "html:build/brazil-cucumber-tests/cucumber-pretty"},
        strict = true)

public class ParallelRunner extends AbstractTestNGCucumberTests {

    @Override
    @DataProvider(parallel = true)
    public Object[][] scenarios() {
        return super.scenarios();
    }
}

我正在考虑在并行测试中重用相同的驱动程序实例,但这可能吗?如果是这样,我该如何实例化驱动程序?Cucumber 似乎没有 beforeAll 类型的方法,当我在 Hooks 类中使用 beforeAll of testNG 时,它似乎没有被调用。任何建议将不胜感激。

标签: javacucumbertestngcucumber-jvmcucumber-java

解决方案


跨多个线程重用驱动程序会话没有意义。相反,可以在同一线程内的测试/场景之间重用驱动程序会话。为此,您需要更新代码以使用线程本地驱动程序实例。

最简单的方法是将qaf-cucumberproperty selenium.singletone = 1一起使用。此设置将为在同一线程中运行的测试方法/场景重用驱动程序会话。如果您改变主意并想为每个场景集使用新会话 selenium.singletone=Methods

任何你想要驱动对象的地方,你都可以从测试库中获得:

WebDriver webDriver = new WebDriverTestBase().getDriver();

您的代码可能如下所示:

public class Hooks {


    private TestContext testContext;

    @Inject
    public Hooks(TestContext testContext) {
        this.testContext = testContext;
    }

    @After
    public void after(final Scenario scenario) {
        LOG.debug("Executing After Hook");
        if (shouldScreenshot(scenario)) {
            embedScreenshotToReport(scenario);
        }
        this.testContext.destroyContext();
    }

    @Before("@skip_scenario")
    public void skipScenario(Scenario scenario) {
        LOG.info("Skipping scenario: {}", scenario.getName());
        Assume.assumeTrue(false);
    }

    private boolean shouldScreenshot(Scenario scenario) {
        return scenario.isFailed() && Screenshot.isRequired();
    }

    private void embedScreenshotToReport(Scenario scenario) {
        final byte[] screenshot = ((TakesScreenshot) new WebDriverTestBase().getDriver().getScreenshotAs(OutputType.BYTES);
        scenario.embed(screenshot, "image/png");
    }
}

@ScenarioScoped
public class TestContext extends WebUITest {
//nothing to do for driver management!....
//just set driver.name property
//code below is only for compatibility
    public WebDriver getWebDriver() {
        return new WebDriverTestBase().getDriver();
    }
    public void destroyContext() {
        System.out.println("destory method called");
    }
}

您可以利用QAF的其他功能,例如


推荐阅读