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

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(347)   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 云 上运行的应用程序编写测试,而无需连接到远程主机,只需使用本地环境即可。

我们不断学习,

亚历克斯

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

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...