使用 Arquillian 和 LocalStack 离线测试 AWS 云堆栈

位置:首页>文章>详情   分类:Java教程   阅读(118)   2023-12-09 15:34:57

当您在 AWS 云堆栈(例如 DynamoDB、S3 等)上构建应用程序时,您需要针对这些组件编写测试。您可能有的第一个想法是拥有一个用于生产的环境和另一个用于测试的环境,然后针对它运行测试。

这适用于集成测试、部署测试、端到端测试或性能测试,但对于组件测试,如果您可以在本地和离线运行 AWS 云堆栈,速度会更快。

Localstack 提供此功能。它提供了一个功能齐全的本地 AWS 云堆栈,因此您可以离线开发和测试您的云应用程序。

Localstack 提供了多种启动所有堆栈的方法,但最简单的方法是使用 Docker 映像。因此,如果您运行 atlassianlabs/localstack,那么您将启动堆栈并使用下一个配置运行:

  • API 网关位于 http://localhost:4567
  • 位于 http://localhost:4568 的 Kinesis
  • 位于 http://localhost:4569 的 DynamoDB
  • 位于 http://localhost:4570 的 DynamoDB 流
  • 位于 http://localhost:4571 的 Elasticsearch
  • S3 位于 http://localhost:4572
  • Firehose 位于 http://localhost:4573
  • Lambda 位于 http://localhost:4574
  • SNS 在 http://localhost:4575
  • SQS 位于 http://localhost:4576
  • 红移在 http://localhost:4577
  • 位于 http://localhost:4578 的 ES(弹性搜索服务)
  • SES 在 http://localhost:4579
  • 位于 http://localhost:4580 的 Route53
  • 位于 http://localhost:4581 的 CloudFormation
  • 位于 http://localhost:4582 的 CloudWatch

所以下一个问题是如何自动化启动容器的所有过程,运行测试并最终停止一切并使其可移植,所以如果您在 Linux 或 MacOS 中使用 Docker,则无需担心?答案是使用 Arquillian Cube

Arquillian Cube 是一个 Arquillian 扩展,可用于管理测试中的 Docker 容器。要使用它,您需要在计算机上运行一个 Docker 守护进程(它可以是本地的也可以不是),但它可能会在本地。

Arquillian Cube 提供了三种不同的方式来定义容器:

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

在此示例中,我将向您展示容器对象 DSL 方法,但其他任何方法也适用。

您需要做的第一件事是在构建工具上添加 Arquillian 和 Arquillian Cube 依赖项。

  
 <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.arquillian.cube</groupId>
        <artifactId>arquillian-cube-docker</artifactId>
        <version>1.6.0</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.arquillian</groupId>
        <artifactId>arquillian-bom</artifactId>
        <version>1.1.13.Final</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk</artifactId>
      <version>1.11.86</version>
    </dependency>
    <dependency>
      <groupId>org.jboss.arquillian.junit</groupId>
      <artifactId>arquillian-junit-standalone</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.arquillian.cube</groupId>
      <artifactId>arquillian-cube-docker</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.6.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

然后您可以编写测试,在本例中测试您可以创建一个存储桶并使用在 Docker 主机中启动的 S3 实例添加一些内容:

  
 import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.S3Object;
import java.io.ByteArrayInputStream;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.arquillian.cube.docker.impl.client.containerobject.dsl.Container;
import org.arquillian.cube.docker.impl.client.containerobject.dsl.DockerContainer;
import org.jboss.arquillian.junit.Arquillian;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(Arquillian.class)
public class S3Test {

    @DockerContainer
    Container localStack = Container.withContainerName("localstack")
        .fromImage("atlassianlabs/localstack:0.5.3.1")
        .withPortBinding(IntStream.rangeClosed(4567, 4578).boxed()
            .collect(Collectors.toList()).toArray(new Integer[0]))
        .withPortBinding(8080)
        .build();


    @Test
    public void should_create_bucket_and_add_content() {
        final AmazonS3Client amazonS3Client = new AmazonS3Client();
        amazonS3Client.setEndpoint("http://" + localStack.getIpAddress() + ":4572/");

        String bucketName = "my-first-s3-bucket-" + UUID.randomUUID();
        String key = "MyObjectKey";

        amazonS3Client.createBucket(bucketName);

        assertThat(amazonS3Client.listBuckets()).hasSize(1);

        amazonS3Client.putObject(bucketName, key, "abcdef");
        final S3Object object = amazonS3Client.getObject(bucketName, key);

        assertThat(object.getObjectContent()).hasSameContentAs(new ByteArrayInputStream("abcdef".getBytes()));

    }

}

需要考虑的重要事项:

  1. 您使用 Arquillian runner 为您的测试添加注释。
  2. 对用于定义容器的属性使用@DockerContainer注解。
  3. 容器对象 DSL 只是一种 DSL,它允许您配置要使用的容器。在这种情况下,localstack 容器具有所需的端口绑定信息。
  4. 测试仅连接到 Amazon S3 并创建一个存储桶并存储一些内容。

不需要其他任何东西。当您运行此测试时,Arquillian Cube 将连接到已安装的 Docker(机器)主机并启动 localstack 容器。当它启动并运行并且服务能够接收请求时,就会执行测试。在该容器停止并销毁之后。

提示 1:如果您不能使用 Arquillian 运行器,您也可以使用 JUnit 类规则来定义容器,如下所述:http://arquillian.org/arquillian-cube/#_junit_rule

提示 2: 如果您计划在整个组织中使用 localstack,我建议您使用 Container Object 方法而不是 DSL,因为这样您就可以将 localstack 容器对象打包到一个 jar 文件中,并导入到您需要使用它的所有项目中。您可以在 http://arquillian.org/arquillian-cube/#_arquillian_cube_and_container_object 阅读

因此,现在您可以为在 AWS 云 上运行的应用程序编写测试,而无需连接到远程主机,只需使用本地环境即可。

我们不断学习,

亚历克斯

标签: Java教程
地址:https://www.cundage.com/article/jcg-test-aws-cloud-stack-offline-arquillian-localstack.html