测试 Spring Cloud 项目

工程 | Marcin Grzejszczak | 2016 年 1 月 4 日 | ...

欢迎来到我作为 Spring Cloud 团队成员的第一篇博文 :)

我加入已经一个月了,分享这段时间发生的一些有趣的事情是值得的。

如果您读过我在Too Much Coding 博客上的任何帖子,那么您就知道我对两件事很着迷——测试和微服务。鉴于我目前所做的一切都与微服务相关,今天的帖子将讨论测试。

Spring Cloud 项目

当我加入 Spring Cloud 团队时,我快速浏览了一下 Github,发现我们有相当多的项目需要管理,包括

所有这些都依赖于 Spring 和 Spring Boot。当然,它们都有自己的版本。这是很多相互依赖的关系,不是吗?

如何测试依赖?

我想确保如果有人在 Spring Core 或 Spring Boot 中做了改动,我们能立即知道我们的库是否仍然正常运行。当然,我们可以在 CI 工具上创建一个重复的构建,但即使集成测试通过,仍然有可能出现类路径和 JAR 打包问题。

我建议写几个端到端测试...

现在,任何人读过我关于微服务部署的这篇文章,可能会说我疯了,因为我在那个特定的场景下完全反对端到端测试。那么,是什么改变了呢?

为什么端到端测试是个好主意?

二元法 - 它是工作还是不工作?

面对如此多的项目,当时我不想漫游所有 Github 仓库,检查它们的测试,然后再次确认一切正常。我想要一个黑盒解决方案,能告诉我应用程序是否正常运行。

跨项目测试

创建的应用程序将使用我们许多不同的项目。端到端测试将发现这些项目中的任何破坏性更改。

应用打包

有几次我检查了测试,运行了./gradlew bootRun,一切似乎都正常。但问题在于java -jar ...无法工作,因为打包有问题。我也想测试这一点。

使用示例

我想创建几个项目来展示 Spring Cloud 的使用方式。我想站在新的 Spring Cloud 用户的角度,有一个地方可以快速搭建整个应用程序世界、基础设施,然后四处点击看看反应如何。

Brewery 项目

鉴于我发表了许多关于微服务的演讲,我已经准备好了示例代码(感谢初始解决方案的合著者 Szimano)。我对其进行了调整、改造和修改,于是就有了 Brewery

高层概览

总体思路是,有 3 个应用程序相互通信:

  • presenting service(展示服务)
  • brewing service(酿造服务)
  • zuul service(Zuul 服务)

presenting service(展示服务)是用户的 UI,用户可以在其中订购酿造啤酒的原料。它的后端也有酿造过程的状态。

这是服务的 UI:

Diagram

brewing service(酿造服务)是一个大型应用程序,负责多种功能。最初它被拆分成几个微服务,但为了简单起见,我们决定减少部署单元的数量。回到功能方面,这些功能是:

  • 收集原料
  • 啤酒熟化
  • 将啤酒装瓶
  • 报告(监听系统中的事件并将它们存储到内存数据存储中)

zuul service(Zuul 服务)只是一个 Zuul 路由器。

这个系统的理念是所有组件都使用 Service Discovery 或 Spring Cloud Stream 相互通信。

查看Readme以获取更多关于项目结构的信息。

可重用性

我想实现的是可重用性。为了使用 Spring Cloud Zookeeper 作为服务注册中心测试 Spring Cloud Sleuth,我不想改变任何代码。只想用不同的参数运行测试。

我们使用 Spring Cloud 的抽象来实现这一点,所以如果我们从 Eureka 切换到 Consul,代码应该完全不需要改变,并且应用程序仍然能够通信(这只是 JAR 和配置更改的问题)。我也想测试这一点。

约定

Brewery 应用中有一系列约定。主要的一个是你的docker-compose yml 文件有一个特定的后缀,与被测试的功能相对应。

  • docker-compose-CONSUL.yml
  • docker-compose-EUREKA.yml
  • docker-compose-SLEUTH_STREAM.yml
  • docker-compose-SLEUTH.yml
  • docker-compose-ZOOKEEPER.yml

每个 docker-compose 文件都知道如何运行整个应用程序和基础设施世界来测试给定的功能。

如何运行应用程序?

首先,你必须使用 Gradle 构建应用程序和它们的 Dockerfile。你也必须传递WHAT_TO_TEST系统参数。基于这个参数选择应用程序的类路径。例如SLEUTH

./gradlew clean build -DWHAT_TO_TEST=SLEUTH --parallel

一旦完成,运行上述 bash 脚本就足够了

docker-compose -f docker-compose-SLEUTH.yml up -d

注意:有时启动顺序很重要,所以如果你想手动操作,请检查给定功能对应的 bash 文件,例如docker-compose-SLEUTH.sh

一般来说,最好在运行测试时同时启动应用程序。怎么做?只需要一行命令。查看下一节了解更多信息。

如何运行测试?

正如文档所说

最简单的方法是

Create a symbolic link somewhere on your drive to the acceptance-tests/scripts/runDockerAcceptanceTests.sh file.
You can execute that script with such options
    -t what do you want to test (SLEUTH, ZOOKEEPER etc.)
    -v in which version of the BOM (defaults to Brixton.BUILD-SNAPSHOT)
    -h where is your docker host? (defaults to '127.0.0.1' - provide your docker-machine host here)
    -r is brewery repo already in place and needs to be reset? (defaults to not resetting of repo)

一旦你运行脚本,brewery 应用程序将被克隆,使用适当的库版本构建,并执行适当的测试。

所以如果你想运行测试,只需复制粘贴下面的代码

git clone https://github.com/spring-cloud-samples/brewery.git
ln -s brewery/acceptance-tests/scripts/runDockerAcceptanceTests.sh  .
bash runDockerAcceptanceTests.sh -t SLEUTH

如果你是 Mac 用户,最后一行应该像这样(例如,192.168.50.60 是你的 docker-machine IP)

bash runDockerAcceptanceTests.sh -t SLEUTH -h 192.168.50.60

如果你已经下载了依赖,所有的构建、下载和测试运行应该在 5 分钟内完成。

如果你已经设置好了所有应用程序,你可以手动运行验收测试。查看下一节了解更多信息。

测试看起来是什么样子的以及如何运行?

验收测试位于 brewery 的 acceptance-tests Gradle 模块下。你可以通过以下方式运行它们:

  • 从 IDE 运行(记住传递正确的-DWHAT_TO_TEST系统参数)
  • 从 Gradle 运行(SLEUTH 示例:./gradlew :acceptance-tests:acceptanceTests -DWHAT_TO_TEST=SLEUTH
    • 如果你在 Mac 上运行,你需要额外传递-DLOCAL_URL=192.168.60.50参数,其中192.168.60.50是你 docker-machine 的 IP。

这些测试是用 Groovy 编写的,使用了 Spock framework。如果你从未听说过 Spock,是时候开始在你的项目中使用它了。查看 Github 代码,其中有 Brewery 中使用的 Spock 测试示例。

如果你将 Spock 与 Spock-reports 结合使用,你可以获得非常漂亮的 BDD 风格的测试输出

spock_reports

端到端测试是万灵药吗?

一切似乎都很棒,但实际上并非如此。端到端测试有其优点,但也肯定有很多缺点。这些包括:

  • 反馈周期长(你必须等待大约 5 分钟才能看到测试是否通过)
  • 难以调试(大约有 8 个应用程序可能出错——你必须检查每个应用程序的日志才能知道哪里出了问题)
  • 网络问题和随机故障(这是最糟糕的情况,因为它通常是随机的——突然数据包损坏了,Zipkin Server 没有收到对测试通过至关重要的 span...)
  • 测试代码位于被测试库之外(幸运的是,测试代码不会改变,但将与应用程序相关的所有代码放在一个仓库中要好得多)

目前的设置满足了我们的需求,但实际上我们希望进一步改进。这就是为什么我们正在考虑对当前的测试方法进行一些改进。

下一步是什么?

目前,端到端测试与 Travis 上的构建一起执行。但是...

  • 最终我们计划让这些测试仅在我们的 CI 服务器上定期运行。
  • 我们将把部分端到端测试作为集成测试移到相应的库中,这样调试任何问题都会容易得多。
  • 我们希望扩展测试,使其也能在 Cloud Foundry 上执行。

目的是从库的代码库中执行的测试获得更快的反馈。此外,我们希望我们的集成测试更可靠。

总结

在这篇博文中,你可以看到:

  • 如何酿造啤酒
  • 一种使用 Docker、Docker Compose、Travis、Bash 脚本和 Gradle 测试开源库的方法
  • 端到端测试的优缺点
  • Spring Cloud 团队对其库进行测试的长期计划
  • 敏捷的工作方式(我们有一个测试方法——端到端测试——但我们知道它的缺点,并正在迭代计划迁移到更好的解决方案)

更新

[2016 年 1 月 15 日] 现在执行端到端测试容易多了

git clone https://github.com/spring-cloud-samples/brewery.git
cd brewery
bash runAcceptanceTests.sh -t SLEUTH

不再需要符号链接(并且 docker-compose 少了很多)!

如果你想运行测试并在最后杀死所有应用程序,只需执行

git clone https://github.com/spring-cloud-samples/brewery.git
cd brewery
bash runAcceptanceTests.sh -t SLEUTH -k

也请查看 Brewery 项目的 readme 获取任何更改:https://github.com/spring-cloud-samples/brewery

获取 Spring 新闻

订阅 Spring 新闻通讯,保持连接

订阅

先行一步

VMware 提供培训和认证,助你加速进步。

了解更多

获取支持

Tanzu Spring 通过一项简单的订阅即可为 OpenJDK™、Spring 和 Apache Tomcat® 提供支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区即将举行的所有活动。

查看全部