After sharing how we do automated testing on our fronted in my previous post I wanted to share too how we test our backend services using our API. You can find the extended version of this post in our blog
API /集成测试必须更快地开发和运行,因为它们不需要任何用户界面来进行交互,因为它们直接命中了应用程序中设计的端点。
The platform behind
我们的后端平台遵循微服务模式,将应用程序分解为处理整个业务中一个孤立部分的小型服务。 我们遵循六角形的体系结构(又名端口和适配器),以避免它们高度耦合并促进测试活动。 为了公开所有端点,我们使用了由GraphQL的BFF使用的API。
关于基本代码,它是用PHP编写的,并且遵循域驱动设计(DDD)模式。 最终,我们拥有的是完全隔离业务各方面的不同有界上下文(BC)。
The test tool
为了对此进行测试,我们选择了Gauge,它是一个用于编写和运行测试的开源工具。
仪表是由ThoughtWorks创建的,并得到了广泛社区的支持。 它可以在任何平台上使用,并且支持多种语言来编写测试代码。 我们喜欢的两个关键功能是BDD,它支持数据驱动的执行,使您的测试更具可扩展性。
为了自己编写测试方案,Gauge使用规范和概念文件。 基本上,规范文件是包含以一组步骤编写的方案的文件,而概念文件只是可以在方案中重复使用的步骤的集合。
A spec file
Create Booking Request
======================
Tags: booking
Create booking request and charge (OK)
- - - - - - - - - - - - - - - - - - - - - -
* Login with "test-user"
* Create a booking lead for listing id "999999" with move in "2021–01–01" and move out "2021–01–31"
* Create a booking request from booking lead
* Charge booking
* Wait until the booking request is converted into booking
以上是一个规范文件的示例,其中一种方案使用Markdown语言编写。 该场景仅描述了他们在不同步骤中所做的事情。 这些步骤中的每个步骤都有后面的测试代码,但是它们也可以与概念文件相关,因为它们本身可以是一组步骤。
A concept file
# Charge booking
* JSON from file "./bookings/chargeBookingRequest.json" is set as variable "chargeJson"
* Set path "/payment/booking-requests/{id}/chargeNow" as name "charge" replacing path variable "{id}" with variable "bookingRequest"
* An HttpSampler with name "chargeBR" and path in variable "charge" and type "PUT" and port "xxx" and json "chargeJson"
* Response code is equal to "204"
在这里,我们展示了在规格文件中介绍的“收费预订”步骤的示例。 您会看到该步骤后面的所有步骤,这意味着每次我们从规格文件中调用“收费预订”时,所有这些步骤都将运行。 我们通常在以下情况下这样做:
- 仅一项高级任务就需要很多小的步骤我们不想在规范文件级别显示太多逻辑我们将在许多测试场景中重用此步骤
Step implementation
让我们以步骤“ An HttpSampler,名称为” chargeBR”,路径为变量“ charge”,键入“ PUT”,端口“ xxx”和JSON“ chargeJson”的示例为例。
@Step("An httpSampler with name <name> and path <path> and type <type> and port <port> and json <json>")
public void setHttpSamplerNameTypePortBodyGiven(String name, String path, String type, Integer port, String json) {
// Java code to send an http request with the passed on parameters
}
注意@步注解。 它表示该功能是规格文件中使用的步骤。
Build
为了管理和构建项目,我们使用Maven。 Maven是Java项目中使用的Apache广泛使用的构建自动化工具,尽管它也可以用于其他语言。 我们从一开始就一直在使用它,并且由于我们必须维护内部和外部的大量依赖关系,因此对我们很有用。
由于我们所有的API测试都放在同一位置,因此它们都放在同一存储库中。 因此,在更新测试集合后,无论是添加新测试还是重构,都在将更改推送到master分支以确保一切正常之后立即触发构建。 这样,我们就为BC提供了最新版本的测试,以供您使用和运行。
Setting up the CI
如果您还记得我们的第一篇文章,我们将Brigade用作CI系统,而BC则以相同的方式使用它。 对于每个BC,我们都有一个Brigade文件来指示必须在此类管道中运行的事件。 这样,GitItNow(内部开发的工具)可以非常轻松地与管道进行交互,并为整个过程带来可见性。
上方是我们其中一个BC的管道示例。 对于api-tests事件,它将从测试存储库中获取最新的成功构建并运行它。
还值得一提的是,我们在Ci运行中启用了并行化,以便能够更快地运行它们,并在出现任何问题时迅速做出反应。
Summary
在这里所有评论中,我们最终得到了一个健壮的框架,该框架使我们能够跟踪部署的后端代码的质量,并在出现红旗的情况下迅速做出反应。 完美吗? 不,我什么也没说。 我们仍会处理附带问题,例如由于误导数据或其他类型的人为错误而导致的队列阻塞或误报。 但是,还有其他一些方面,例如BDD方法给我们带来的可扩展性,到现在为止已经开发了很多步骤,以至于我们几乎不需要开发更多的步骤,而是使用现有的步骤。
希望你喜欢这个职位🚀