18

我正在使用两个应用程序开发项目:android app (client) 和 rest service (server)。我的 android 应用程序消耗了我的休息服务。

两个应用程序都经过单独测试,以确保它们按预期开展业务。在服务器测试期间,我准备请求并检查服务器响应。在客户端测试期间,我设置了一个简单的 http 模拟服务器并针对不同的模拟响应测试客户端的请求。

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

GET /foo-list.json

将返回带有 json 的 HTTP 200

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

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

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

请分享您的专业经验。

4

4 回答 4

10

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

你问:

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

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

还:

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

除了单元和集成测试,您还应该执行客户端-服务器集成测试;我使用自动化验收测试来做到这一点。使用诸如 Cucumber 之类的测试框架(还可以查看专门为测试移动应用程序而编写的 calabash-android),您可以编写测试来测试与客户端(您的 Android 应用程序)和服务器(您的 Android 应用程序)交互的特定功能和场景(您的 RESTful 服务)。这些客户端-服务器集成测试将启动和停止客户端和服务器的具体实例。

于 2013-10-24T10:27:20.720 回答
5

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

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

另请参阅集成测试和单元测试有什么区别?

于 2013-10-24T19:41:42.193 回答
1

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

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

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

于 2013-10-24T20:24:28.890 回答
1

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

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

但是,在您的常规提交中,我建议使用单元测试来模拟除被测类之外的所有内容。Spock 使这很容易做到,而且由于它是建立在 jUnit 之上的,所以它只需要一个 jar。

于 2013-10-23T03:52:26.257 回答