Testing 客户机-服务器集成测试:模拟还是非模拟?

Testing 客户机-服务器集成测试:模拟还是非模拟?,testing,mocking,client-server,client,integration-testing,Testing,Mocking,Client Server,Client,Integration Testing,我正在开发两个应用程序:android应用程序(客户端)和rest服务(服务器)。我的android应用程序使用我的rest服务 这两个应用程序都分别进行了测试,以确保它们按预期完成业务。 在服务器测试期间,我准备请求并检查服务器响应。 在客户端测试期间,我设置了一个简单的http模拟服务器,并根据不同的模拟响应测试客户端的请求 现在,这项技术非常有效。它给了我我喜欢的灵活性。我可以使用不同的测试框架和持续集成环境。但有一个弱点。在这两个(客户机和服务器)测试用例中,我都指定了相同的api。我认

我正在开发两个应用程序:android应用程序(客户端)和rest服务(服务器)。我的android应用程序使用我的rest服务

这两个应用程序都分别进行了测试,以确保它们按预期完成业务。 在服务器测试期间,我准备请求并检查服务器响应。 在客户端测试期间,我设置了一个简单的http模拟服务器,并根据不同的模拟响应测试客户端的请求

现在,这项技术非常有效。它给了我我喜欢的灵活性。我可以使用不同的测试框架和持续集成环境。但有一个弱点。在这两个(客户机和服务器)测试用例中,我都指定了相同的api。我认为

GET /foo-list.json
将返回带有json的HTTP 200

[{
    id: 1,
    name: foo1,
}, {
    id: 2,
    name: foo2
}]
所以我重复一遍。如果我更改响应格式,我的客户端测试不会失败

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


请分享您的专业经验。

如果您的服务是基于Java的,我强烈建议您研究Spock框架,以模拟可能来自客户端的任何类型的调用。由于Spock只是jUnit的一个扩展,您也可以将其用于Android(不过,公平地说,我从未做过Android开发)

我想说你想做两件事。集成测试和单元测试。集成测试将尝试启动android应用程序并使其进行服务调用,确保上下文之间友好地交互


然而,在您的常规提交中,我建议您进行单元测试,以模拟除被测类之外的所有内容。Spock使这一点非常容易做到,因为它构建在jUnit之上,所以只需要一个jar。

在您的场景中,您应该继续编写单元测试来测试单个类,并编写集成测试来测试多个应用程序层(例如业务层和数据库层)之间的交互操作

你问:

“如何在不牺牲独立测试灵活性的情况下进行真正的集成测试”

您的所有代码都应该使用抽象,这样您就可以使用依赖项注入来使用模拟依赖项完全隔离地对单元测试类进行测试。使用模拟将确保这些测试保持独立,即不与任何其他类耦合。因此,采用这种方法,使用最终具体类的集成测试不会影响使用模拟类的单元测试

此外:

“我应该使用模拟服务器还是rest服务的真实实例来测试客户端?”


除了单元和集成测试之外,您还应该执行客户机-服务器集成测试;我使用自动验收测试来完成这项工作。使用Cucumber之类的测试框架(也可以是Checkout,它是专门为测试移动应用程序而编写的),您可以编写测试特定功能和场景的测试,这些功能和场景将与客户端(您的Android应用程序)和服务器(您的RESTful服务)交互。这些客户机-服务器集成测试将启动和停止客户机和服务器的具体实例。

模拟用于单元测试。您对模拟测试的描述正好描述了这一点。您可以将客户机和服务器作为单独的单元进行测试

集成测试测试单元是否协同工作良好。由于该接口是一个REST接口,因此模拟没有任何意义,您必须通过HTTP测试真实的东西


另请参见

没有理由不能使用真实的服务实例运行自动端到端测试。您可以在用于运行单元测试的同一台测试机器上运行一个真正的服务实例,可能在同一个容器中。您可以将配置设置为使用服务器实例的不同URL来运行自动端到端测试

如果可以对真实服务运行模拟服务,为什么还要额外创建模拟服务呢


如果服务是我无法控制的外部服务,我只会创建一个模拟服务

如果你想让我详细说明的话,请告诉我-我意识到这个答案对你来说可能有点太笼统了。关于集成和单元测试的必要性,你是对的。我的问题是关于集成测试的。当我测试客户机与服务的集成时,我应该模拟服务还是应该运行服务的真实实例?在某些情况下,集成测试的目的是跨边界测试。在我们的环境中,我可能会使用服务的测试版本进行集成测试,以实现这一点。您可能还能够获得像独立测试服务器这样的东西,作为集成测试上下文的一部分运行。简短回答-是的,要进行集成测试,我建议找到一种让应用程序进行服务调用的方法,而不是模仿它们。因此,您建议使用rest服务的真实实例测试客户端。对吗?对!对于集成测试,将单元连接起来,因为它们将在生产中使用。如果我的真实实例出现故障,并且我依赖于此在CI管道上进行绿色构建,该怎么办?对于这个缺点,可能的解决方法是什么?@haroldlivieri您可以在测试期间启动一个测试实例