【问题标题】:distributing cucmber junit5 tests in docker在 docker 中分发黄瓜 junit 5 测试
【发布时间】:2021-07-20 02:49:39
【问题描述】:

我有一个在 azure 构建和发布管道上运行的黄瓜项目。

我已经安装了 docker 和 docker-compose,我可以使用 docker-seleniumdocker-compose 打开容器和网格

我想分发黄瓜测试,有点像as explained here。但在那个链接中,它使用testng 进行了解释,而我将junit5 与黄瓜一起使用。结合我们对cucumber parallelism in junit5 的了解,我将如何实现这一点,特别是链接的以下部分?

@Parameters({"Port"})
@BeforeClass
public void initiateDriver(String Port) throws MalformedURLException {
            if(Port.equalsIgnoreCase("9001"))
    {
        driver = new RemoteWebDriver(new URL("http:localhost:4444/wd/hub"), DesiredCapabilities.chrome());
        driver.manage().window().maximize();
    }
    else if(Port.equalsIgnoreCase("9002")){
        driver = new RemoteWebDriver(new URL("http:localhost:4444/wd/hub"), DesiredCapabilities.firefox());
        driver.manage().window().maximize();
    }
}

据我了解,如果我提到cucumber.execution.parallel.enabled=true,在junit-platform.properties 中,它将在每个功能文件中并行运行,我如何在下面提到port 来实现

  1. 在一个容器中运行每个功能
  2. 有没有办法将不同功能文件的每个场景分布在单独的容器中?

【问题讨论】:

  • 您正在混合来自cucumber-junitcucumber-junit-platform-engine 的指令。他们完全不同。一个用于 JUnit 4,另一个用于 Junit Platform (JUnit 5)。
  • 我将链接编辑为仅包含 junit5 info 。我们如何才能完成上述任务?

标签: cucumber cucumber-jvm


【解决方案1】:

我找不到在场景级别并行化junit5 测试的任何解决方案,因此我将testNGcourgette-jvmcucumber-guice 结合使用。它开箱即用并在场景级别运行并行测试

只需在黄瓜中包含类似的跑步者类。我的测试进一步使用RemoteWebdriver 在 selenium 网格上打开多个实例。确保网格已启动并正在运行,并且节点已注册到网格。

import courgette.api.CourgetteOptions;
import courgette.api.CourgetteRunLevel;
import courgette.api.CucumberOptions;
import courgette.api.testng.TestNGCourgette;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@Test
@CourgetteOptions(
        threads = 10,
        runLevel = CourgetteRunLevel.SCENARIO,
        rerunFailedScenarios = true,
        rerunAttempts = 1,
        showTestOutput = true,
        reportTitle = "Courgette-JVM Example",
        reportTargetDir = "build",
        environmentInfo = "browser=chrome; git_branch=master",
        cucumberOptions = @CucumberOptions(
                features = "src/test/resources/com/test/",
                glue = "com.test.stepdefs",                   
                publish = true,
                plugin = {
                        "pretty",
                        "json:target/cucumber-report/cucumber.json",
                        "html:target/cucumber-report/cucumber.html"}
        ))
class AcceptanceIT extends TestNGCourgette {
}

RemoteWebdriver 配置是

protected RemoteWebDriver createDriver() throws MalformedURLException , IOException {
                   
                 Properties properties = new Properties();                
                ClassLoader loader = Thread.currentThread().getContextClassLoader();                
                  String hubURL = "http://192.168.1.7:65299/wd/hub";
                  System.setProperty("webdriver.gecko.driver", "/Users/amit/Desktop/amit/projects/misc/geckodriver");
                 
                    FirefoxProfile profile = new FirefoxProfile();
                    DesiredCapabilities capabilities = DesiredCapabilities.firefox();
                    capabilities.setCapability(FirefoxDriver.PROFILE, profile);
                    capabilities.setPlatform(Platform.ANY);    
                    FirefoxOptions options = new FirefoxOptions();
                    options.merge(capabilities);                 
                   driver.set(new RemoteWebDriver(new URL(hubURL),options));
                   return driver.get();
        }

cucumber-guice 相关配置

    import io.cucumber.guice.ScenarioScoped;    
    @ScenarioScoped
          public class Global {
          public RemoteWebDriver driver;
           
          public Global() throws MalformedURLException, IOException {
                driver = new DriverFactory().getManager();
               // getManager() should have driver from above createDriver()

          }
    }

在您的 stepdefs 中注入 Global 类,如下所示(进行必要的导入)。您也可以注入辅助类,guice 将在每个场景中提供它

 @Inject
   Global global;
 
  //then you can do
   global.driver.get(site);

黄瓜酱的 pom

 <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-guice</artifactId>
      <version>${cucumber.version}</version>
      <scope>test</scope>
    </dependency>

如果您想使用docker-compose 打开网格并将您的测试指向http://localhost:65299/wd/hub,请使用下面的配置。端口根据以下文件

version: "3"
services:
  selenium-hub:
    image: selenium/hub:3.141.59-20210607
    container_name: selenium-hub
    ports:
      - "65299:4444"

  chrome:
    image: selenium/node-chrome:3.141.59-20210607
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444


  firefox:
    image: selenium/node-firefox:3.141.59-20210607
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444
    deploy:
      mode: replicated
      replicas: 7

【讨论】:

    【解决方案2】:

    通常您会让 CI 运行 a matrix of tests。这个测试矩阵已经可以并行运行不同的作业。 矩阵中的每个作业都可以执行所有测试或一部分测试。您可以使用标签来包含或排除对某些作业配置的某些测试。这可确保浏览器和操作系统的特定问题立即显现出来。

    这也稍微简化了问题。当您不使用不同的浏览器类型启动 Selenium Grid 时,您不必找到一种聪明的方法来将每个测试连接到正确的浏览器。

    相反,您每个作业只需使用一种浏览器类型启动 Selenium Grid。网格启动后,每个作业都可以使用多个远程 Web 驱动程序并行运行测试。 然后,您所要做的就是确保您的测试不会尝试使用更多的浏览器,然后网格可用。这可以通过设置一些配置参数来完成:

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

    您必须将这些 configuration parameters 用于您的测试执行。一种方法是使用 maven 配置文件,但还有许多其他方法可以做到这一点:

            <profile>
                <id>parallelism</id>
                <build>
                    <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-failsafe-plugin</artifactId>
                            <configuration>
                                <properties>
                                    <configurationParameters>
                                    cucumber.execution.parallel.enabled=true
                                    cucumber.execution.parallel.config.strategy=fixed
                                    cucumber.execution.parallel.config.fixed.parallelism={env.CONCURRENT_TESTS}
                                    </configurationParameters>
                                </properties>
                            </configuration>
                        </plugin>
                    </plugins>
                </build>
            </profile>
    

    你可以像这样把它绑在一起:

    test:
      stage: test
      script:
        - ./start-selenium-grid $BROWSER $CONCURRENT_TESTS
        - mvn test -Pparallelism
      parallel:
        matrix:
          - OS: Windows
            OS_VERSION: 10
            BROWSER: [Chrome, Firefox, Edge]
            CONCURRENT_TESTS: 4
          - OS: OS X
            OS_VERSION: Big Sur
            BROWSER: [Chrome, Firefox, Edge, Safari]
            CONCURRENT_TESTS: 2
    

    总之。首先为不同的浏览器并行运行构建作业。然后在每个作业中,针对多个 Web 驱动程序并行运行测试。

    【讨论】:

    • 如果让我们在矩阵中说我们为一个浏览器打开一个容器。在这个工作中,我们如何控制在哪个容器上运行哪个特性文件。如果有办法控制场景,那就更好了。
    • 这就是标签的用途。
    猜你喜欢
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    相关资源
    最近更新 更多