在Docker中运行并行测试

有时,当您在CI环境上运行测试时,您希望并行运行测试。 这种并行性是在MavenGradle之类的构建工具中编程的,或者是通过使用Jenkins插件编程的。

如果您将Docker用作提供对应用程序外部依赖关系(例如数据库,邮件服务器,ftp服务器等)的测试工具,则可能会发现一个大问题,原因可能是

Docker Hos t是其中之一,当并行运行测试时,所有这些都将尝试启动具有相同名称的容器。 因此,当您(并行)启动第二项测试时,由于尝试在同一Docker主机上启动两个名称相同或两个容器中具有相同绑定端口的容器,因此将出现与该冲突容器名称有关的失败。

至此,您可以做两件事:

  • 每个并行测试可以有一个Docker主机
  • 您可以重用相同的Docker主机并使用Arquillian Cube Star Operator

Arquillian Cube是Arquillian扩展,可用于在测试中管理Docker容器。

要使用Arquillian Cube,您需要在计算机上运行Docker守护程序(它可以是本地的,也可以不是本地的),但是可能是在本地。

Arquillian Cube提供了三种定义容器的方法:

  • 定义docker-compose文件。
  • 定义容器对象。
  • 使用容器对象DSL。

在此示例中,我将向您展示如何使用docker-composeContainer Object DSL

通过星号运算符,您可以向Arquillian Cube指示您要随机生成多维数据集名称,并且还可以调整链接。 这样,当您并行执行测试时,不会因为名称或绑定端口而发生冲突。

让我们来看一个例子:

plugins {
    id "io.spring.dependency-management" version "1.0.2.RELEASE"
}


apply plugin: 'java'

repositories {
    mavenCentral()
    jcenter()
}

dependencyManagement {
    imports {
        mavenBom 'org.jboss.arquillian:arquillian-bom:1.1.13.Final'
    }
}

dependencies {

    testCompile 'junit:junit:4.12'
    testCompile 'org.jboss.arquillian.junit:arquillian-junit-standalone'
    testCompile 'org.arquillian.cube:arquillian-cube-docker:1.3.2'
}

test {
    maxParallelForks = 2
    testLogging.showStandardStreams = true
}
#src/test/docker/docker-compose.yml

redis*:
  image: redis:3.0.7
  ports:
    - "6379"
@RunWith(Arquillian.class)
public class TestOne {

    @HostPort(containerName = "redis*", value = 6379)
    private int portBinding;


    @Test
    public void should_print_port_binding() throws InterruptedException {
        System.out.println(TestOne.class.getCanonicalName() + " - " + portBinding);
        TimeUnit.SECONDS.sleep(4);
    }

}

您可以在泊坞窗,compose.yml文件中看到一个典型的码头工人,撰写文件的一个重要变化,就是这名以星号(*)操作符[Redis的*]结束。 这是您指示Arquillian Cube的名称,该名称应为每次执行动态生成。
然后有三个测试(这里仅显示第一个),它们看起来都一样。 基本上,它打印以控制台绑定端口以连接到服务器。 最后是build.gradle文件,该文件并行执行两个测试。 因此,如果您在Gradle中运行测试( ./gradlew test ),您将看到两个测试同时执行,并且当其中一个测试完成时,其余测试将被执行。 然后,如果您检查输出,您将看到下一个输出:

org.superbiz.parallel.runner.TestOne STANDARD_OUT
    CubeDockerConfiguration:
      serverUri = tcp://192.168.99.100:2376
      machineName = dev
      certPath = /Users/alex/.docker/machine/machines/dev
      tlsVerify = true
      dockerServerIp = 192.168.99.100
      definitionFormat = COMPOSE
      clean = false
      removeVolumes = true
      dockerContainers = containers:
      redis_9efae4a8-fcb5-4f9e-9b1d-ab591a5c4d5a:
        alwaysPull: false
        image: redis:3.0.7
        killContainer: false
        manual: false
        portBindings: !!set {56697->6379/tcp: null}
        readonlyRootfs: false
        removeVolumes: true
    networks: {}



org.superbiz.parallel.runner.TestThree STANDARD_OUT
    CubeDockerConfiguration:
      serverUri = tcp://192.168.99.100:2376
      machineName = dev
      certPath = /Users/alex/.docker/machine/machines/dev
      tlsVerify = true
      dockerServerIp = 192.168.99.100
      definitionFormat = COMPOSE
      clean = false
      removeVolumes = true
      dockerContainers = containers:
      redis_88ff4b81-80cc-43b3-8bbe-8638dd731d8e:
        alwaysPull: false
        image: redis:3.0.7
        killContainer: false
        manual: false
        portBindings: !!set {56261->6379/tcp: null}
        readonlyRootfs: false
        removeVolumes: true
    networks: {}
    
    //......
    
org.superbiz.parallel.runner.TestThree > should_print_port_binding STANDARD_OUT
    org.superbiz.parallel.runner.TestOne - 56261

org.superbiz.parallel.runner.TestOne > should_print_port_binding STANDARD_OUT
    org.superbiz.parallel.runner.TestOne - 56697

org.superbiz.parallel.runner.TestTwo > should_print_port_binding STANDARD_OUT
    org.superbiz.parallel.runner.TestOne - 56697

因此,您可以在日志中看到,容器名称不是redisredis * ,而是redis后跟一个UUID 。 您还可以看到在打印输出时,每种情况下的装订端口都不同。

但是,如果您不想使用docker-compose方法,则还可以使用还支持star运算符的Container Object DSL以编程方式定义容器。 在这种情况下,示例如下所示:

@ClassRule
public static ContainerDslRule redisStar = 
  new ContainerDslRule("redis:3.2.6", "redis*")
  .withPortBinding(6379);

方法是相同的,但是使用容器对象(您需要Arquillian Cube 1.4.0才能与容器对象一起运行)。
请注意,由于Arquillian Cube可以处理命名或端口绑定问题,因此借助此功能,您可以以任意程度的并行执行来运行测试。 请注意,在容器之间进行链接的情况下,您仍然需要使用star运算符,它将在运行时解析。

要了解有关星算子的更多信息,只需检查http://arquillian.org/arquillian-cube/#_parallel_execution

源代码: https : //github.com/lordofthejars/parallel-docker

翻译自: https://www.javacodegeeks.com/2017/05/running-parallel-tests-docker.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值