当前位置: 首页 > 知识库问答 >
问题:

使用cucumber junit平台引擎和Selenium WebDriver运行测试会打开太多线程

潘安平
2023-03-14

我曾尝试配置一个现有的Maven项目,以使用cucumber junit平台引擎运行。

我用这份回购协议作为灵感。

我添加了所需的Maven依赖项,就像使用spring boot starter父版本2.4.5和cucumber jvm版本6.10.4的链接项目一样。

我设置junit-Platform属性如下:

cucumber.execution.parallel.enabled=true
cucumber.execution.parallel.config.strategy=fixed
cucumber.execution.parallel.config.fixed.parallelism=4

在runner类中使用注释@Cucumber,在带有步骤定义的类中使用注释@springbootest

我正在使用一个CucumberHooks类在场景前后添加逻辑,我猜它会干扰运行程序,因为我正在使用注释:

import java.util.List;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EventHandler;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.TestRunFinished;
import io.cucumber.plugin.event.TestRunStarted;
import io.github.bonigarcia.wdm.WebDriverManager;

public class CucumberHooks implements ConcurrentEventListener {

@Autowired
private ScenarioContext scenarioContext;

@Before
public void beforeScenario(Scenario scenario) {
    scenarioContext.getNewDriverInstance();
    scenarioContext.setScenario(scenario);
    LOGGER.info("Driver initialized for scenario - {}", scenario.getName());
    ....
    <some business logic here>
    ....
}

@After
public void afterScenario() {
    Scenario scenario = scenarioContext.getScenario();
    WebDriver driver = scenarioContext.getDriver();

    takeErrorScreenshot(scenario, driver);
    LOGGER.info("Driver will close for scenario - {}", scenario.getName());

    driver.quit();
}

private void takeErrorScreenshot(Scenario scenario, WebDriver driver) {
    if (scenario.isFailed()) {
        final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
        scenario.attach(screenshot, "image/png", "Failure");
    }
}

@Override
public void setEventPublisher(EventPublisher eventPublisher) {
    eventPublisher.registerHandlerFor(TestRunStarted.class, beforeAll);
}

private EventHandler<TestRunStarted> beforeAll = event -> {
    // something that needs doing before everything
    .....<some business logic here>....
    WebDriverManager.getInstance(DriverManagerType.CHROME).setup();
};

}

我试着从io中替换@Before标签。cucumberjava@beforeach来自组织。朱尼特。木星api,它不起作用。

我该如何解决这个问题?

共有1个答案

空正豪
2023-03-14

所以事实证明,parallism主要是一个建议。Cucumber使用JUnit5sForkJoinPool HierarchycalTestExecutorService,它构建了一个ForkJoinPool

ForkJoinpool上的文档:

对于需要单独或自定义池的应用程序,可以使用给定的目标并行级别构造ForkJoinPool;默认情况下,等于可用处理器的数量。池试图通过动态添加、挂起或恢复内部工作线程来维护足够的活动(或可用)线程,即使某些任务在等待加入其他任务时被暂停。然而,面对阻塞的I/O或其他非托管同步,不保证进行此类调整。

所以在一个ForkJoinpool内,当曾经有一个线程阻塞时,例如因为它开始与web驱动程序异步通信,另一个线程可以被启动以保持并行性。

由于所有线程都等待,因此会向池中添加更多线程,并启动更多web驱动程序。

这意味着你需要依靠ForkJoinpool来限制你必须自己完成的网络驱动程序的数量。你可以使用像ApacheCommons pool这样的库,或者使用计数信号量来实现一个基本的池。

@Component
@ScenarioScope
public class ScenarioContext {

    private static final int MAX_CONCURRENT_WEB_DRIVERS = 1;
    private static final Semaphore semaphore = new Semaphore(MAX_CONCURRENT_WEB_DRIVERS, true);

    private WebDriver driver;

    public WebDriver getDriver() {
        if (driver != null) {
            return driver;
        }

        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        try {
            driver = CustomChromeDriver.getInstance();
        } catch (Throwable t){
            semaphore.release();
            throw t;
        }
        return driver;
    }

    public void retireDriver() {
        if (driver == null) {
            return;
        }

        try {
            driver.quit();
        } finally {
            driver = null;
            semaphore.release();
        }
    }
}    

 类似资料:
  • 有没有任何一个测试REST API的使用硒网络驱动程序Maven TestNG。请分享信息或样本项目

  • Apache ShardingSphere 提供了完善的测试引擎。 它以 XML 方式定义 SQL,每个引擎分别为 MySQL、PostgreSQL、SQLServer 和 Oracle 数据库运行测试用例。 为了方便上手,测试引擎无需修改任何 Java 代码,只需修改相应的配置文件即可运行断言。

  • 我创建了maven项目,它由junit和spock测试组成。两个测试的代码。 在我的本地机器中,当我运行mvn测试时,它会欺骗两个测试类。我在git仓库上部署了项目,并为maven项目配置了jenkins。我推这个项目的存储库和执行作业,但是詹金斯只检测JUnit测试的AppTest类。我已经改变了pom.xml并添加了文件regadring到。我的项目结构。 文件组织的内容。spockframe

  • 我创建了一个多线程步骤,最大线程限制为10; 在处理了200万条记录文件后,我可以在日志文件中看到创建的线程太多,即使我将限制设置为10个线程。你能告诉我为什么吗?非常感谢。 2019-07-02T17:02:298968129857信息[batch-thread35348]com。db。wmdl。价格档案。工作一批听众。PriceFileReaderListener([])-PriceFileR

  • 我有一个带有静态ConcurrentQueue的类。一个类接收消息并将其放入队列中,而这个类上的另一个线程从该队列中读取消息并一次处理一个。使用cancellationtoken中止该方法。 清空队列的方法如下所示: 我的测试方法如下: 因此,我在自己的线程中启动我的出列方法,并使用一个新的取消令牌。然后我将一些消息排队,给进程一秒钟时间来处理它们,然后使用源代码。Cancel(false)结束线

  • 问题内容: 这是一个简单的Go http(tcp)连接测试脚本 如果我在Ubuntu中运行它,我将得到: 其他帖子说,以确保连接,这就是我在这里所做的全部。还有人说,要增加最大连接数的限制或尝试使用,但仍然行不通。 如何在单个服务器上运行数百万个tcp连接goroutine?仅在2,000个连接时崩溃。 谢谢, 问题答案: 我认为您需要更改您的最大文件描述符。我之前在我的一个开发VM上遇到了相同的