14

您如何使用 Karma Runner(ex-Testacular)e2e 场景运行器在 e2e 测试中集成异地/应用外/外部资源工作流?

基本场景:

  1. 应用程序有一个按钮。
  2. 单击按钮将数据发送到服务提供商 X(例如提交到http://service/submit或其他)。
  3. 提供商 X 需要在此 URL 处单击/提交/操作。
  4. Provider X 然后将一些东西发送回我们的应用程序。

我不是在问“你如何存根提供者 X”。我在问您如何实际进行端到端测试——所以我们的测试实际上可以捕捉到第 3 方服务 API 的重大更改。我基本上希望能够驱动一个应用外网站,类似于您使用Selenium 的 Webdriver 之类的东西。

目前我的问题是element( ref ).click()用于尝试第 2 步,它似乎没有加载所需的站点,因此没有 DOM 可操作,无法完成 e2e。

4

1 回答 1

18

使用 Karma 可能无法执行此场景。我将介绍我对 Karma 的工作原理、它与 Webdriver 的比较以及实现此场景所需的条件的理解。

首先,重要的是要记住 Karma 和 angular-scenario 不是一回事。Karma 是用于运行基于浏览器的测试的通用 shell。它启动浏览器进程,启动节点以提供包含测试工具的网页,通过在 websocket 上发送命令来运行测试,然后收集结果。它与运行测试的实际线束/框架无关。它有 Angular 场景运行器(用于 Angular e2e 测试)、Jasmine(通常用于 Angular 单元测试)和其他流行的 JavaScript 测试框架的适配器。

像 Jasmine 这样的测试运行器在与被测代码相同的窗口上下文中执行,这就是它对单元测试有用的原因。相比之下,Angular 场景运行器与被测系统有一定的关系。它在 iframe 中加载整个应用程序,然后在大多数情况下模拟用户事件并测试可见暴露的 DOM 元素上的断言。

因为场景运行器通过 iframe 边界与应用程序交互,所以它受到浏览器的同域策略的约束。不可能在 上提供场景运行器http://localhost:8000,然后加载http://yourapp到 iframe,然后在该 iframe 内触发事件。

解决此问题的一种方法是将场景运行器简单地托管在与您的应用程序相同的服务器上。这是一个简单的例子:

http://plnkr.co/edit/rfqpSq?p=preview

但是,将测试运行程序塞进应用程序并不是很令人满意。Karma 通过内置的 HTTP 代理为您提供了一种解决方法。您可以将 Karma 配置为代理任意数量的不同服务器,以使它们看起来都来自同一来源。只需将它们添加到proxies配置文件的部分:

proxies = {
  '/': 'http://yourapp/',
  '/service/': 'http://service/'
} 

这允许您的 e2e 测试跨域,但要注意的是,当通过表单提交或重定向发生域转移时,它必须是代理 URL。否则场景运行器将失去对 iframe 的控制,将无法继续测试。

请注意,Selenium Webdriver 没有此限制。它在单个浏览器窗口的级别之上运行,因此不受相同域策略的约束。

所以让我们看看你的具体情况。就实际的 HTTP 请求和响应而言,我假设这是您要练习的流程:

  1. 从加载您的应用程序http://yoursite/yourapp.html
  2. 用户提交的表单如下所示:
<form method="POST" action="http://service/remotesubmission">
  ...your form...
  <input type="submit">
</form>
  1. 提供者 X 处理远程 POST,然后重定向到以下位置的表单:
<form method="POST" action="http://service/nextsubmission">
  ...provider's form...
  <input type="submit">
</form>
  1. Provider X 处理表单 POST,然后重定向回您的应用程序。

如果这是实际场景,那么我认为您可以使用 Karma 和 angular 场景运行器进行这项工作的唯一方法是:

  1. 条件化表单中的操作 URL,使其在测试时指向外部服务的代理 URL。
  2. 确保提供程序流中的重定向和操作 URL 保留在代理路径中。我认为目前不可能,但也许可以通过为代理内容设置替换模式的方法来修补 Karma。
于 2013-04-21T21:02:01.347 回答