如何为(Angularjs)Web 应用程序进行集成测试

Posted

技术标签:

【中文标题】如何为(Angularjs)Web 应用程序进行集成测试【英文标题】:How to do Integration Testing for (Angularjs) Web Apps 【发布时间】:2013-10-05 09:58:34 【问题描述】:

我正在开发一个 Web 应用程序。 它由 2 个部分组成。一个节点休息服务器和一个 angularjs 客户端。

应用的结构是这样的:Rest Server Api Module Angular App

服务器目前经过良好测试。 我有单元测试和集成测试。 集成测试正在访问一个真实的数据库并通过 http 调用其余的 api。 我认为这是服务器测试所能达到的最高水平。 集成测试也运行得很快。 我非常有信心测试服务器的方式足以满足我的用例,并且我对结果感到满意。

但是我正在努力如何测试 angularjs 应用程序。 我对相关指令和模块进行了单元测试。写这些不是问题。

我想编写涵盖用户场景的集成测试。 类似于注册场景:用户访问网站,进入注册表单,然后提交包含数据的表单。

angularjs 团队正在从ng-scenarios 转移到protractor。 Protractor 正在使用 Selenium 运行测试。 因此有两个范围:应用范围和测试范围。

现在我可以想到我可以使用的三种不同的抽象。 而且我不确定哪一个最适合我。

模拟 Api 模块 模拟 Rest 服务器 使用完整服务器

模拟 API 模块

在这种情况下,我不需要设置服务器。所有交互都在浏览器中运行

优势:

不需要服务器

缺点:

api 在浏览器范围内,我必须对其进行篡改。

我真的很喜欢这个解决方案,但我发现很难模拟 Api。 需要在浏览器范围内修改 Api。 因此我需要将修改从测试发送到浏览器。 这个can be done,但是我看不到如何在测试范围内运行像mockedApi.method.wasCalledOnce() 这样的断言

模拟 Rest 服务器

优势:

客户端将保持不变 只需处理一个作用域

缺点:

必须设置休息路线

我可以在 nodejs 中创建一个完整的 Mock Rest Server。 量角器测试是用nodejs编写的,因此可以在测试中完成对服务器的控制。 在我运行测试之前,我可以告诉服务器如何响应。 像这样的东西:server.onRequest(method: 'GET', url: '/').respondWith('hello world')

然后我可以做类似wasCalledOnce的断言

将完整的服务器与数据库一起使用

每个测试都在一个完整的服务器上运行,并且可以将元素添加到数据库中。 每次测试后,可以查看数据库中的预期元素

优势:

可以非常肯定,如果这些测试正在运行,则应用在测试用例中可以正常运行

缺点:

我已经与其余服务器进行了相当激烈的集成测试。这感觉就像再次做同样的事情。 设置取决于完整的服务器

目前的结论

模拟 Api 会完全分离服务器和客户端。 使用 Mock Api 将是更高级别的测试,但需要假服务器 进行完整的集成测试可以获得最佳的可靠性,但这也高度依赖于服务器代码

我应该选择什么?你会怎么做?

【问题讨论】:

看这里tuesdaydeveloper.com/2013/06/… 嗨,Adrian,这篇博文涵盖了使用 Jasmine 和 Karma 对控制器进行的单元测试。我正在寻找集成测试。由于不推荐使用 ng-scenarios(以前用于集成测试),我需要使用量角器进行集成测试。 【参考方案1】:

这是一个很好的问题,与特定工具无关。我不得不在一个大型“绿地”(即从头开始)项目中面临同样的问题。

这里有一个词汇问题:“mock”这个词无处不在,而你所说的“集成测试”更像是“全端到端自动化功能测试”。这里没有冒犯,只是措辞清晰有助于解决问题。

您实际上自己提出了正确答案:#2 存根其余服务器。 #1 是可行的,但很快就会很难开发和维护,#3 是个好主意,但与 UI 测试和 UI 验证无关。

要实现前端的高可靠性,独立于后端,只需 stub 其余服务器,即开发一个愚蠢的简单 REST 服务器,它是幂等的,即。 e.总是对一个 http 请求回答同样的事情。保持幂等性原则将使开发和测试比任何其他选项都非常非常容易。

那么对于一次测试,您只检查屏幕上显示的内容(测试顶部)和发送到服务器的内容(测试底部),这样整个 UI 堆栈只测试一次。

这个问题的完整答案应该值得写一篇完整的博客文章,但我希望你能从我的建议中感受到该怎么做。

最好的问候

【讨论】:

【参考方案2】:

我想我在 Protractor google 小组中回答了同样的问题。我和你的想法很相似,不想要服务器,但想要我的所有测试代码在一个地方(在 Protractor 中),而不是在 Protractor 和浏览器之间拆分。为了实现这一点,我自己动手并为在 Protractor 中运行的 $httpBackend 服务开发了一个代理。它允许配置 $httpBackend 服务,就好像它在 Protractor 中运行一样。我已经研究了一段时间了,目前它的功能相当齐全。如果您能看一下并让我知道我是否遗漏了任何重要的东西,那就太好了。

https://github.com/kbaltrinic/http-backend-proxy

【讨论】:

这看起来不错。我去看看!【参考方案3】:

这是一个很好的问题。我会这样做:

因为您已经对相关指令和模块进行了角度单元测试,所以这是完美的。

另一件完美的事情是您的服务器集成测试正在访问一个真实的数据库,并且还确保通过 http 的其余 api 工作正常。

那么为什么不同时添加一些包含 Angular 和您的服务器的高级集成测试。

如果可以避免模拟,为什么不尽可能节省维护额外代码的工作。

也不错:http://blog.ericbmerritt.com/2014/03/25/mocking-is-evil.html

【讨论】:

【参考方案4】:

这是一种为 Angular 代码编写集成测试的方法。关键概念是以一种方式构建您的代码,使您能够以与 UI 使用它的方式非常相似的方式调用各种函数。不过,正确解耦代码对于在这方面取得成功很重要:

更多:http://www.syntaxsuccess.com/viewarticle/angular-integration-tests

【讨论】:

有用的链接,我在找什么!【参考方案5】:

在我看来,模拟 REST 服务器是最好的、更简洁的选择。试试 Mountebank (http://www.mbtest.org)。一个了不起的虚拟化服务工具。

【讨论】:

以上是关于如何为(Angularjs)Web 应用程序进行集成测试的主要内容,如果未能解决你的问题,请参考以下文章

如何为不同的 SQL Server 文件夹运行相同的 angularjs 应用程序(.NET MVC 5)?

如何为机器学习和预测构建良好的训练数据集?

您如何为代码签名的 Dotnet 程序集添加时间戳?

Angularjs - ng-map - Google Maps Javascript API v3 - 如何为多个标记设置最佳缩放

您如何为 angularjs 可重用组件打包资产?

如何为 .NET Core Web API 进行安全身份验证?