java - 并行运行 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 时,它似乎没有被调用。任何建议将不胜感激。
解决方案
跨多个线程重用驱动程序会话没有意义。相反,可以在同一线程内的测试/场景之间重用驱动程序会话。为此,您需要更新代码以使用线程本地驱动程序实例。
最简单的方法是将qaf-cucumber与property 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的其他功能,例如
- 听众
- 外部数据提供者
- 定位器存储库
- 使用自动屏幕截图等待/断言/验证
- 纯TestNG BDD 实现
推荐阅读
- php - jQuery Ajax 删除按钮有效,但数据库中的数据未删除
- regex - .htaccess 另一个页面的相同重写规则不起作用
- c++ - C++:用字符串向量创建一个元组
- sql - 未使用 ODBC 连接从源获取数据并从变量传递 SQL 查询
- c++ - 我无法在开关盒内打印矢量
- laravel - 如何从一个组中获取用户,并在 laravel 中的两个关系之间建立一个联合?
- c++ - 在我自己的库项目 C++ Visual Studio 中包含一个外部库
- kotlin - 将 RxJava 与 api、room、retrofit 一起使用时的致命信号 11 SIGSEGV (RxCachedTreadS)
- jitsi - 如何打造 Jitsi 独特的房间?
- php - Prestashop 1.7.x - 如何在产品列表中添加产品的运营商?