为微服务架构编写端到端测试

微服务架构的一个主要方面是应用程序形成为松散耦合的服务的集合,每个服务可以独立地部署并且通过某种轻型协议相互通信。

现在假设您要为Cart Service编写端到端测试。您很快就会发现它并不容易,让我列举一些原因:

  • 购物车服务需要知道如何启动定价服务目录服务MongoDB(如果您想要涉及前端以及Coolstore GWWebUI)。
  • 购物车服务需要为两种外部服务准备一些数据(固定装置)。
  • 您使用网络与服务进行通信。可能会发生一些测试失败,不是因为真正的故障,而是因为基础设施问题或其他服务有任何错误。因此,这些测试的可能性变得不稳定并且开始失败,因为当前服务中引入的任何更改都更高。
  • 在更复杂的情况下,在成本(部署到云),时间(启动所有基础架构和服务)和维护时间方面,运行这些测试可能会很昂贵。
  • 很难在开发人员计算机中运行它们,因为您需要在计算机上安装所有部件。

因此,端到端测试不是测试微服务的最佳方法,但您仍需要一种从服务的开始到结束进行测试的方法。

有必要找到一种“模拟”这些外部依赖关系的方法,而不必注入任何模拟对象。我们需要做的是欺骗被测服务,因此它确实认为它正在与真实的外部服务进行通信,而实际上并非如此。

允许我们这样做的方法是Service Virtualiztion。服务虚拟化是一种模拟组件应用程序(如基于API)的行为的方法。

您可以将服务虚拟化视为您过去在OOP中实现的模拟方法,而不是在对象级别进行模拟,而是在服务级别进行模拟。这是对企业的嘲弄。

有很多服务虚拟化工具,但根据我的经验,在JVM生态系统中,更好的工具之一是Hoverfly

让我们看看Cart Service的“端到端”测试是怎样的。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    properties = "CATALOG_ENDPOINT=catalog")
public class CartServiceBoundaryTest {
    @Autowired
    private TestRestTemplate restTemplate;
    @ClassRule
    public static HoverflyRule hoverflyRule = HoverflyRule.inSimulationMode(dsl(
        service("catalog")
            .get("/api/products")
            .willReturn(success(json(ProductsObjectMother.createVehicleProducts())))
    ));
    @Test
    public void should_add_item_to_shopping_cart() {
        final ShoppingCart shoppingCart = this.restTemplate.postForObject("/api/cart/1/1111/2", "", ShoppingCart.class);
        assertThat(shoppingCart)
            .returns(0.0, ShoppingCart::getCartItemPromoSavings)
            .returns(2000.0, ShoppingCart::getCartItemTotal)
            .returns(-10.99, ShoppingCart::getShippingPromoSavings)
            .returns(2000.0, ShoppingCart::getCartTotal)
            .extracting(ShoppingCart::getShoppingCartItemList)
            .hasSize(1);
    }
}

这个服务是使用Spring Boot实现的,所以我们使用的是Spring Boot Test框架。这里的重要部分是使用CATALOG_ENDPOINT属性指定部署Catalog服务的URL 。对于此测试,它设置为目录

下一个重点是Hoverfly类规则部分。在该规则中,指定了以下内容:

  1. 在测试之前启动HTTP代理,并将来自JVM的所有传出流量重定向到该代理。
  2. 它记录了当完成对主机目录的请求并且路径是/ api / products时,它必须返回给定json文档的成功结果。

测试本身只使用TestRestTemplate(它是一个休息客户端)并验证您可以向购物车添加一些元素。

请注意,您无需配置启动HTTP代理的位置或配置任何端口,因为Hoverfly会自动配置JVM网络参数,以便任何网络通信都通过Hoverfly代理。

请注意,现在您不需要知道如何启动Catalog服务,也不需要知道如何使用正确的数据对其进行配置。

您正在其边界内测试整个服务,从传入消息到传出消息到其他服务,而不模拟任何内部元素。

您可能想知道“如果当前服务还依赖于数据库服务器会发生什么?”

在这种情况下,您什么也不做,因为服务本身知道正在使用哪个数据库服务器以及它需要的数据类型,您只需要启动数据库服务器,填充所需的数据(夹具)并执行测试。对于这种情况,我建议您使用Arquillian Cube Docker从Docker容器启动数据库服务,这样您就不需要在需要运行测试的每台机器上安装它,而Arquillian Persistence Extension则用于将数据库维护到已知状态。

在下一个评级服务示例中,您可以简要了解如何将它们用于持久性测试:

public class ApueCubeRatingServiceTest {
  // Starts in local dockerhost (docker machine or native) mongo docker image before running the test class
  @ClassRule
  public static ContainerDslRule mongodbContainer = new ContainerDslRule("mongo:3.2.18-jessie")
      .withPortBinding(27017);
  //Defines APE (Arquillian Persistence Extension to work as rule)
  @Rule
  public ArquillianPersistenceRule arquillianPersistenceRule = new ArquillianPersistenceRule();
  // Defines to use MongoDb as NoSql Populator
  @MongoDb
  @ArquillianResource
  NoSqlPopulator populator;
  @Test
  public void should_calculate_average_rating_when_adding_an_already_inserted_item() {
    createPopulatorConfiguration()
                .usingDataSet("single_rating_with_double.json")
                .execute();
    // Execute test
  }
  @After
  public void tearDown() {
    createPopulatorConfiguration().clean();
  }
  private NoSqlPopulatorConfigurator createPopulatorConfiguration() {
          return populator.forServer(
              mongodbContainer.getIpAddress(),
              mongodbContainer.getBindPort(27017))
              .withStorage(TEST_DATABASE);
  }
}

通过这种方法,您可以确保服务的所有内部组件按预期工作,并避免微服务中端到端测试的片状性质。

因此,任何微服务中的端到端测试与整体应用程序中的端到端测试并不完全相同; 您仍在测试整个服务,但保持受控环境,其中测试仅依赖于服务边界内的组件。

合同测试如何适应?那么,这里显示的所有内容都可以用于合同测试的消费者和提供者方面,以避免启动任何外部服务。通过这种方式,正如许多作者所总结的那样,如果您使用合同测试,这些将成为新的端到端测试。

原文标题《Writing End to End Tests for a Microservices Architecture》

作者:Alex Soto

译者:February

不代表云加社区观点,更多详情请查看原文链接

原文链接:https://dzone.com/articles/writing-end-to-end-test-for-a-microservices-archit-1

原文作者:Alex Soto

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python开发者

python的高性能web应用的开发与测试实验

前者导致其性能天然就被编译型语言在性能上落后了许多。而后者则在多核并行计算时代,极大的限制了python的应用场景。

36180
来自专栏小白课代表

最优秀好用的免费文件压缩/解压缩工具软件

若常常需要与 Mac 用户交换文件,或是购买一些国外的数字商品(如我购买的日本同人志),常常会遇见压缩包打开是一片一片的乱码文件名的状况。编码问题一直是造成乱码...

11910
来自专栏友弟技术工作室

Mac Book 上的touch id妙用1password6用 Touch ID 授权 sudo

使用新版的macbook或pro都是支持Touch ID。 Touch ID在工作生活中,有哪些妙用。 今天介绍一下我常用的touch id 1passwor...

38980
来自专栏熊二哥

Linux快速入门01-基础概念

4年多前,刚到上海时报过一个关于Oracle的培训班,在那里接触到了Linux,不过一直都没真正去试着使用它。现在经过慢慢的成长,越来越觉得,Linux是每一个...

23550
来自专栏VMCloud

【解析向】腾讯云的Windows Server日志配置收集工具是个什么鬼?(5)

且听笔者一句劝,无论是Windows还是Linux抑或是Unix都是大部分理论是相同的,与其与人争吵对比这几个平台之类的差异,不如好好研究下底层的各个子系统...

26570
来自专栏Fundebug

XSS攻击之窃取Cookie

译者按: 10 年前的博客似乎有点老了,但是XSS 攻击的威胁依然还在,我们不得不防。

19850
来自专栏24K纯开源

Final Cut Pro X效果插件开发总结

一、介绍       最近公司需要针对Final Cut Pro(FCP)开发一款效果插件,用于对公司自己开发的视频格式进行后期处理。Final Cut Pro...

42380
来自专栏电光石火

idea 创建的maven+spring+mybatis项目整合 报错无法创建bean

最近在做一个由maven构建的spring+spring mvc+mybatis项目,刚开始的时候是用自己的电脑Win10环境下的eclipse写的,托管到了码...

37060
来自专栏北京马哥教育

服务器程序源代码分析之二:php-fpm

php作为排名top2 互联网开发工具,非常流行,可以参考:中国最大的25个网站采用技术选型方案 php这个名称实际上有两层含义 广义的php 是指用后缀名为....

38540
来自专栏Fundebug

Web应用架构入门之11个基本要素

译者: 读完这篇博客,你就可以回答一个经典的面试题:当你访问Google时,到底发生了什么?

14430

扫码关注云+社区

领取腾讯云代金券