英文:
Testing microservices?
问题
我知道这个问题有点主观,但我对该怎么做感到困惑。目前我正在使用Go + Go-kit编写一些微服务。我想以集成测试的方式测试这些微服务的端点,但我不确定该如何进行。我唯一能想到的方法是编写shell脚本来访问这些端点并检查响应。但这似乎是一个笨拙的方法,不是一个明智的做法。我觉得应该有更好的方法来解决这个问题。有人有什么建议吗?
英文:
I know this question is a little subjective but I am lost on what to do here. At the moment I am using Go + Go-kit to write some microservices. I'd like to test the endpoints of these microservices in an integration test type fashion but I am unsure how to go about it. The only thing I can think of is to have shell scripts that hit the endpoints and check for responses. But this seems like kludge and not a real smart practice. I feel like there should be a better way to do this. Does anyone have any suggestions?
答案1
得分: 1
端到端测试的另一种替代方法是消费者驱动的合同(CDC)。
尽管拥有一些端到端测试是有用的,但它们也有一些缺点,例如:
-
消费者服务必须知道如何启动提供者服务。这听起来像是不必要的信息,当服务数量开始增加时,可能很难维护;
-
启动一个服务可能会很慢。即使我们只谈论几秒钟,这也会增加构建时间的开销。如果一个消费者依赖于多个服务,这些时间都会累积;
-
提供者服务可能依赖于数据存储或其他服务才能正常工作。这意味着现在不仅需要启动提供者,还需要启动其他一些服务,可能还有一个数据库。
CDC的思想简要描述如下:
- 消费者定义对服务的特定请求的期望结果
- 提供者和消费者就此合同达成一致
- 提供者持续验证合同是否得到履行
这些信息来自这里。阅读更多关于这个文章的内容,即使它是针对Java的,也可能会有用。
英文:
An alternative approach to end-to-end testing is Consumer-Driven Contract (CDC).
Although is useful to have some end-to-end tests, they have some disadvantages like:
-
the consumer service must know how to start the provider service. This sounds like unnecessary information, likely difficult to maintain when the number of services start ramping up;
-
starting up a service can be slow. Even if we’re only talking a few seconds, this is adding overhead to build times. If a consumer depends on multiple services, this all starts adding up;
-
the provider service might depend on a data store or other services to work as expected. It means that now not only the Provider needs to be started but also a few other services, maybe a database.
The idea of CDC is described shortly as:
- The consumer defines what it expects from a specific request to a service
- The provider and the consumer agree on this contract
- The provider continuously verifies that the contract is fulfilled
This information is taken from here. Read more on this article, it can be useful even if it is specific to Java.
答案2
得分: 0
你可以使用标准的Go单元测试来实现这个,使用httptest包。这个包可以让你创建模拟的Request
和ResponseWriter
对象,可以传递给任何Handler
或HandleFunc
。你可以创建适当的Request
,将其传递给你的处理程序,然后从ResponseRecorder
中读取响应并与预期的响应进行比较。
如果你正在使用默认的mux(调用http.Handle()
来注册处理程序),你可以针对http.DefaultServeMux
进行测试。我过去在微服务中使用过它,并取得了良好的结果。它也适用于处理程序的基准测试、路由和中间件。
英文:
You can do this in a standard Go unit test using the httptest package. This allows you to create mock Request
and ResponseWriter
objects that can be passed to any Handler
or HandleFunc
. You create the appropriate Request
, pass it to your handler, then read the response out of the ResponseRecorder
and check it against the expected response.
If you're using the default mux (calling http.Handle()
to register handlers) you can test against http.DefaultServeMux
. I've used it for microservices in the past with good results. Works for benchmarking handlers, routing, and middleware as well.
答案3
得分: 0
你应该始终使用golang的原生unit testing framework来测试每个单独的服务(请不要使用shell脚本!)。httptest似乎不错,但我认为有更细粒度的测试边界会更有帮助 - 你应该为代码的每个功能块真正拥有一个_test.go文件。较小的测试更容易维护。
至于涉及多个微服务的整体集成测试,你不应该在开发时进行这些测试。建立一个暂存区并在那里运行测试。
这是我的建议。
英文:
You should always use golang's native unit testing framework to test each individual service (please, no shell script!). httptest seems fine, but I would argue it is helpful to have finer-grained test boundaries -- you should really have one _test.go for each functional block of your code. Smaller tests are easier to maintain.
In terms of overall integration tests that involve multiple microservices, you shouldn't do them at development time. Set up a staging area and run the tests over there.
My 2 cents.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论