10

我有一个应用程序,其中页面重新加载/导航和 iframe 至关重要,而这些部分似乎很难用单元测试覆盖。

我希望能够写smt。像这样:

it('should fire appropriate callbacks on start and page reload', function() {
  app.start();
  expect(app.onStart).toHaveBeenCalled();
  page.reload();
  expect(app.onRestart).toHaveBeenCalled();
}

it('should know whether it runs in iframe or not', function() {
  expect(app.isInIframe()).toBe(false);
  iframe = createTestIframe();
  expect(iframe.getApp().isInIframe()).toBe(true);
}

我所知道的单元测试框架(mocha、Jasmine、QUnit)都旨在在一页上完成整个测试套件,在顶级上下文中。

另一方面,功能测试框架(FuncUnit、TestCafé、Selenium WebDriver)似乎专注于高级抽象,例如“单击元素”、“检查元素的值”等,没有提供深入研究代码执行的能力。

免责声明:总的来说,我对测试还很陌生,所以也许我应该完全从不同的角度看待这个问题。

4

3 回答 3

5

Intern的设计正是为了在这些情况下启用这些类型的功能测试,并且实际上是由于您描述的现有 JS 测试框架无法启用这些类型的交互的问题而创建的。它包括一个功能测试接口,可以像这样工作,假设app在 Node.js 方面,你会做这样的事情:

define([ 'intern!bdd', 'intern/chai!expect', 'my/app' ], function (bdd, expect, app) {
   var it = bdd.it;

   it('should fire appropriate callbacks on start and page reload', function() {
     app.start();
     return this.remote.get('http://path/to/server')
       .then(function () {
         expect(app.onStart).toHaveBeenCalled();
       })
       .refresh()
       .then(function () {
         expect(app.onRestart).toHaveBeenCalled();
       });
   });

   // ...etc.
});

实习生教程更好地概述了单元测试和功能测试之间的区别以及如何使用这两者。与 CasperJS 之类的其他建议不同,它实际上将使用标准 WebDriver API 以及诸如 Sauce Labs 或您自己的 Selenium 服务器之类的服务,针对真实浏览器运行您的功能测试。

于 2014-01-16T05:40:43.737 回答
3

您描述的测试似乎是完整的集成测试,而不是单元测试(刷新/iframe)。

另一方面,您展示的那种单元测试旨在通过​​模拟所有交互部分并单独测试单元来测试程序的单独单元,例如控制器。

对于您想要执行的测试类型(包括 iframes/refreshes),最好使用集成测试工具,例如Selenium IDE

该工具有一个宏记录器,可以记录您在测试中的浏览器操作,并允许重放这些操作并添加断言以检查测试结果。看看这个演示视频,看看它的使用有多简单。

这种集成测试补充但不能替代您显示的单元测试类型。

集成测试的数量比单元测试要少得多,请参阅测试金字塔以了解有关测试和平衡单元和集成测试数量的一些最佳实践。

于 2014-01-12T17:57:07.507 回答
3

你可以试试CasperJS。它在 PhantomJS 中运行功能测试,您可以在测试页面中评估任意代码。对于您的情况,您应该能够执行以下操作:

casper.test.begin('iframe', 1, function (test) {
  casper
    .start('your.page.url')
    .thenEvaluate(function () {
      window.iframe = createTestIframe()
    })
    .then(function () {
      test.assertEval(function () {
        return iframe.getApp().isInIframe()
      })
    })
})
于 2014-01-15T17:28:21.930 回答