微服务的集成测试 | 微服务系列第八篇

文章导读

  • 本文仅代表作者的个人观点;
  • 本文的内容仅限于技术探讨,不能作为指导生产环境的素材;
  • 本文素材是红帽公司产品技术和手册;
  • 本文分为系列文章,将会有多篇,初步预计将会有26篇。

一、比较单元测试和集成测试

在敏捷开发过程中,添加到现有微服务的任何更改或新功能都可能会破坏应用程序功能。 开发人员使用测试框架(如JUnit和TestNG)来创建单元测试,以验证小型自包含代码的功能。

但是,当应用程序(如数据库或外部服务)访问外部系统时,创建单元测试是不够的。 为了测试多个系统之间的通信,开发人员创建了集成测试,以便整个系统运行。

为了减轻开发测试的代码量,使用测试框架扩展来模拟测试中的系统。 Arquillian是一个测试框架扩展,允许在测试期间执行微服务的底层应用程序服务器基础结构,例如Wildfly Swarm。 这提供了运行集成测试所需的资源,无需复杂的测试编码。

二、使用Arquillian实现集成测试

构建集成测试的第一步是使用@RunWith批注对测试类进行批注,并将Arquillian.class类作为测试运行器参数传递。此批注指定测试应作为Arquillian集成测试运行。

要在Wildfly Swarm上运行Arquillian测试,Arquillian要求生成应用程序包,通常是Web应用程序资源(WAR)文件,该文件将部署在Wildfly Swarm容器中。使用Shrinkwrap库来构建此可部署的WAR文件。 Shrinkwrap提供了一个API,允许在启动测试容器之前创建可部署包作为集成测试的一部分。

要使用Shrinkwrap,必须使用@Deployment批注标记测试类中的静态方法,并返回WebArchive类的实例。此注释告诉Arquillian在启动Wildfly Swarm容器之前使用此方法在测试执行期间构建WAR。如果项目使用Maven来管理其依赖项,那么这个带注释的方法必须使用Maven.resolver静态方法来读取项目的pom.xml文件,并发现应用程序运行所需的所有外部JAR依赖项。使用importDependencies方法从Maven存储库下载项目使用的任何外部JAR文件的列表。

解析依赖关系后,使用ShrinkWrap.create静态方法捆绑项目中的所有依赖项,类和配置,以生成符合Java的文件(WebArchive.class)。要实现此目的,请使用addPackages方法将项目中运行测试所需的包和类添加到WAR文件中。然后,要激活CDI,请使用addAsWebInfResource方法将空beans.xml文件添加到Web存档。接下来,使用addAsLibraries方法将从Maven下载的依赖项列表包含在最终文件中。

最后,要触发WildFly Swarm,请通过在使用@CreateSwarm注释标记的静态方法中设置端口号等参数来配置测试服务器。此方法必须返回具有必要参数集的Swarm对象。

在某些测试方法中,可能需要运行时环境信息,例如可以访问REST API的URL。为了解决这个问题,Arquillian提供@ArquillianResource注释来注入运行时信息并在测试方法中使用它。

以下示例是使用Arquillian和Shrinkwrap编写的完整集成测试类。这会在正在运行的WildFly Swarm容器中运行测试:

1 通过使用来自JUnit的@RunWith注释从Arquillian启用扩展来自定义测试用例的执行。

2 从运行时环境中注入信息,例如REST API的URL。

3 使用@Deployment注释负责捆绑应用程序的方法。

4 获取当前项目的所有API依赖项。

五 创建Web归档(WAR)文件。

6 包括项目中的所有类和包。

7 添加空beans.xml文件以触发CDI扩展。

8 从项目中添加API依赖项。

9 创建测试所需的Swarm配置。

以下arquillian.xml文件提供了一些额外的配置,例如端口和主机名,必须从测试源代码外部化:

1 标识用于测试应用程序的容器。

2 在WildFly中配置用于管理目的的端口。

将arquillian.xml文件存储在项目的src / test / resources目录中。

最后,要运行测试,Maven使用的pom.xml文件必须声明Arquillian和Shrinkwrap使用的依赖项。

1 使用Arquillian中的所有依赖项导入org.wildfly.swarm:arquillian工件。

2 使用Shrinkwrap中的所有依赖项导入org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven工件。

三、比较容器内测试和客户端测试

开发人员可能需要在不同条件下执行测试:

检查测试执行的外部结果:在微服务中,开发人员可能需要检查REST API调用的输出,这只有在应用程序运行并且将API称为普通客户端时才可能。

检查容器内运行的测试执行:开发人员可能需要检查生成与预期不同的输出的代码执行结果。

在这两种情况下,微服务必须运行,但后者在将结果转换为人类可读输出之前评估结果。

Arquillian支持这两种方案,但默认情况下它会执行容器内测试。要运行客户端测试,开发人员必须使用@RunAsClient注释。要运行客户端测试,请使用Resteasy和Rest Assured库。

在以下源代码中,测试方法使用@RunAsClient进行批注,并使用Resteasy客户端API来调用REST API。

@ArquillianResource
private URL url;

@Test
@RunAsClient
public void testGet() {
  Client client = ClientBuilder.newBuilder()
          .build()
          .target(this.url.toExternalForm() + endpoint)
          .request(MediaType.APPLICATION_JSON_TYPE)
          .get();
...
}

或者,要运行容器内测试,必须使用@ javax.inject.Inject批注注入测试对象。 测试方法不能具有@RunAsClient注释。

@ArquillianResource
private URL url;

@Inject
private ShoppingCartService service;

@Test
public void testCart() {
  ShoppingCart cart = service.checkOut();
...
}

四、实验展现

首先通过JBDS导入一个已经存在的maven项目:

在JBoss Developer Studio中,通过展开JBoss Developer Studio左窗格中Project Explorer选项卡中的hola项打开HolaResourceFallBackIntegrationTest测试用例,然后单击hola→Java Resources→src / test / java→com.redhat.training.msa。

hola.rest中: 双击HolaResourceFallBackIntegrationTest.java文件。

源代码主要由提供方向的注释组成。 testFallback测试方法必须检查REST端点/ api / hola是否返回Hola de localhost消息。

右键单击HolaResourceFallBackIntegrationTest测试用例,然后在JBoss Developer Studio中选择Run As→JUnit Test。 JUnit选项卡显示测试用例执行的输出,并显示一个Failure Trace面板,其中显示testFallback方法具有AssertionError。 这是预期的,因为调用了fail static方法。

五、在测试用例中启用Arquillian

将测试用例的JUnit测试运行器设置为Arquillian。 在类声明之前添加@RunWith注释。 使用Arquillian.class作为注释参数,如下所示:

实现捆绑UberJar包的deploy方法。

添加@Deployment方法级注释。

为了简化开发,com.redhat.training.msa.hola.rest.ArquillianTestUtils帮助器类提供了deploy方法,该方法捆绑了Arquillian测试用例所需的所有依赖项。

但是,要运行实验,应将microprofile-config.properties文件添加到UberJar中的META-INF目录中。 使用addAsManifestResource方法将此文件包含到存档中。

deploy方法必须具有以下代码:

实现配置WildFly Swarm运行时的方法。

添加@CreateSwarm方法级注释。

为了简化开发,com.redhat.training.msa.hola.rest.ArquillianTestUtils帮助器类提供了newContainer方法,该方法配置WildFly Swarm所需的所有常用参数,例如端口号和环境变量。

将以下代码添加到createSwarm方法:

重新运行JUnit测试用例。

右键单击HolaResourceFallBackIntegrationTest测试用例,然后在JBoss Developer Studio中选择Run As→JUnit Test。 JUnit选项卡显示测试用例执行的输出,并显示一个Failure Trace面板,其中显示testFallback方法具有AssertionError异常。

与之前的执行不同,此测试运行时间比前一次更长。 启动需要更长时间,因为WildFly Swarm已初始化并加载集成测试使用的所有分数。

testFallback方法必须调用/ api / hola REST端点。 要调用它,请在测试方法中使用JAX-RS客户端API。 该方法必须使用ClientBuilder类调用REST端点。

使用ClientBuilder类需要REST端点URL。 要在测试执行期间获取Arquillian提供的值,请向测试用例声明url属性并使用@ArquillianResource对其进行注释。

要调用REST端点,请使用ClientBuilder类构建Client实例,如下所示:

要标识REST端点,请从客户端变量调用目标方法。 使用先前注入的url属性获取REST端点。

使用HTTP GET方法调用REST端点。

要评估测试的输出,请使用assertEquals方法。

重新运行JUnit测试用例。

右键单击HolaResourceFallBackIntegrationTest测试用例,然后在JBoss Developer Studio中选择Run As→JUnit Test。 JUnit选项卡显示测试用例执行的输出。 这次,整个测试通过,并在测试执行后显示绿色条。

原文发布于微信公众号 - 大魏分享(david-share)

原文发表时间:2018-08-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏运维

Redis3.0.7集群部署完整版

Redis集群没有出来前,一直使用Codis集群,现在部署Redis集群看看效果如何。

30120
来自专栏用户2442861的专栏

用GDB调试程序(一)

http://blog.csdn.net/haoel/article/details/2879

11310
来自专栏JackieZheng

Spring集成RabbitMQ-使用RabbitMQ更方便

如果提到Spring,你脑海中对他的印象还停留在SSH三大框架之一,那或许你该好好重新认识这个家伙。 在IT技术日新月异的今天,他还能让你忘不了并与他朝夕相处,...

21490
来自专栏不想当开发的产品不是好测试

性能测试 -- 实际问题

现象: 自动化云主机(10.199.146.xx )上的osp-cart服务过一段时间会自动停掉 分析过程: 1、通过top命令,查看整理的资源情况,发现osp...

20390
来自专栏菩提树下的杨过

maven学习(上)- 基本入门用法

一、下载及安装 1.1 下载maven 3.1.1 先到官网http://maven.apache.org/download.cgi 下载最新版本(目前是3.1...

22380
来自专栏Fred Liang

Python 虚拟环境方案比较

最近在写一个网站后台,由于涉及到阿里云的 SDK ,而阿里云在自己的源(https://mirrors.aliyun.com)上发布的 SDK 要新,因此在设置...

9720
来自专栏陈树义

Java日志框架那些事儿

在项目开发过程中,我们可以通过 debug 查找问题。而在线上环境我们查找问题只能通过打印日志的方式查找问题。因此对于一个项目而言,日志记录是一个非常重要的问...

76190
来自专栏张善友的专栏

将Windows日志转换为Syslog

无论是Unix、Linux、FreeBSD、Ubuntu,还是路由器、交换机,都会产生大量的日志,而这些,一般会以syslog的形式存在。在RFC 3164中定...

509100
来自专栏青玉伏案

JavaEE开发使用Maven管理的SpringMVC工程

前几篇博客已经陆陆续续的聊了一些Spring的东西,今天博客我们就来聊一下SpringMVC。SpringMVC目前在JavaEE开发中可谓占据一席之地,用起来...

244100
来自专栏web编程技术分享

【Java框架型项目从入门到装逼】第七节 - 学生管理系统项目搭建

30770

扫码关注云+社区

领取腾讯云代金券