客户端 - 服务器集成测试:模拟还是不模拟?

18

我正在开发一个包含两个应用程序的项目:Android 应用程序(客户端)和 Rest 服务(服务器)。我的 Android 应用程序使用了我的 Rest 服务。

为确保它们都按预期运行,两个应用程序都是分开测试的。 在进行服务器测试时,我准备请求并检查服务器响应。 在进行客户端测试时,我设置了一个简单的 HTTP 模拟服务器,并对客户端的请求进行测试,以检查是否得到不同的模拟响应。

现在,这种技术效果非常好。它给了我喜欢的灵活性。我可以使用不同的测试框架和持续集成环境。但是有一个弱点,即在客户端和服务器的测试用例中,我都指定了相同的 API。我假设例如:

GET /foo-list.json

将返回HTTP 200及json。

[{
    id: 1,
    name: foo1,
}, {
    id: 2,
    name: foo2
}]

所以我重复一遍。如果我更改响应格式,我的客户测试不会失败。

我的问题是关于测试这种情况的良好实践。如何进行真正的集成测试,而不牺牲独立测试的灵活性。 我应该使用模拟服务器还是实际的REST服务来测试客户端?

请分享您的专业经验。

4个回答

10
在您的场景中,您应该继续编写单元测试来测试各个类,并编写集成测试来测试多个应用程序层之间的相互操作(例如业务和数据库层)。
您问道:
“如何进行真正的集成测试而不牺牲独立测试的灵活性?”
您所有的代码都应该使用抽象化,以便您可以使用依赖注入来单元测试类并完全隔离使用模拟依赖项。使用模拟将确保这些测试保持独立,即不与任何其他类耦合。因此,采用这种方法,使用最终的具体类的集成测试不会影响使用模拟类的单元测试。
另外:
“我应该使用模拟服务器还是使用我的实际REST服务的真实实例来测试客户端?”
除了单元测试和集成测试,您还应该进行客户端-服务器集成测试;我使用自动化验收测试来完成这项工作。使用测试框架,如Cucumber(还可以查看专门用于测试移动应用程序的calabash-android),您可以编写测试,测试特定功能和场景,这些功能和场景将与客户端(您的Android应用程序)和服务器(您的RESTful服务)交互。这些客户端-服务器集成测试将启动和停止客户端和服务器的具体实例。

5

模拟是用于单元测试的。您对使用模拟进行测试的描述正是如此。您将客户端和服务器作为单独的单元进行测试。

集成测试测试单元是否能够很好地协同工作。由于接口是REST接口,因此在这种情况下进行模拟没有意义,您必须通过HTTP测试实际内容。

另请参见什么是集成测试和单元测试之间的区别?


那么您建议使用真实的 REST 服务实例来测试客户端,对吗? - promanski
正确!对于集成测试,将单元连接起来,就像它们在生产环境中一样。 - flup
如果我的真实实例崩溃了,而我依赖它来在CI流水线上获得绿色构建,那该怎么办?有哪些可能的解决方法来应对这个问题? - haroldolivieri
1
@haroldolivieri 你可以在测试期间启动一个测试实例。 - flup

1
如果您的服务基于Java,我强烈建议您考虑Spock框架,以模拟可能来自客户端的任何调用。由于Spock只是jUnit的扩展,您还可以尝试在Android上使用它(尽管公平地说,我从未进行过Android开发)。
我认为您需要做两件事:集成测试和单元测试。集成测试将尝试启动Android应用程序并导致它进行服务调用,确保上下文之间友好交互。
但是,在您的常规提交中,我建议对除了待测试类之外的所有内容进行模拟的单元测试。Spock使这个过程非常容易,并且由于它是构建在jUnit之上的,所以只需要一个jar包即可。

如果您需要更详细的解释,请告诉我 - 我意识到这可能对您来说有点太笼统了。 - Jason Lowenthal
你对于整合测试和单元测试的必要性的说法是正确的。我的问题是关于整合测试。当我测试客户端与服务的整合时,我应该模拟服务还是运行一个真实的服务实例? - promanski
1
集成测试的目的是跨越边界进行测试,在某些情况下。在我们的环境中,我可能会使用服务的测试版本来进行集成测试以使其正常工作。您还可以在集成测试上下文中运行类似独立测试服务器的东西。简而言之,为了进行集成测试,我建议找到一种方法让应用程序进行服务调用,而不是将它们模拟掉。 - Jason Lowenthal

1

您完全可以在真实的服务实例上运行自动化端到端测试,没有任何理由不能这样做。您可以在用于运行单元测试的同一台测试机器上运行真实的服务实例,甚至可以在同一个容器中运行。您可以设置配置,以便在运行自动化端到端测试时使用不同的服务器实例URL。

如果您可以针对真实服务运行测试,为什么还要额外工作来创建模拟服务呢?

只有当服务是我无法控制的外部服务时,我才会创建模拟服务!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接