5

用例是这样的:我想对页面中运行的代码进行单元测试(在浏览器、QUnit 或类似的东西中)。页面可以做的事情之一是导航到另一个页面。我无法捕捉到这个事件,因为:

  • beforeunload 无法停止操作(因此第一次导航中断了我的测试)
  • 尝试使用 getter 返回旧值和监视 setter 重新定义 window.location 或 window.location.href 也是被禁止的

我知道有一些安全原因不允许停止导航,但对于开发来说,这样做真的很有用。

有没有可能这样做(我无法直接控制测试运行程序,所以我不能只在 iframe 中加载代码并让它导航然后检查 iframe 的位置)?

编辑:更具体一点:我想测试,基于来自 facebook 的记录/连接状态(我使用来自 github 的 facebook-stub 来模拟 fb),是否在登录按钮上安装了正确的处理程序(说,$('#login-btn')),通过单击将页面导航到 facebook oauth 对话框、服务器流(此处的详细信息并不重要)。

所以我希望能够做这种事情:

// set up fb mock to not be connected
fbAsyncInit(); // simulate the startup of app
$('#login-btn').click();
equal(document.location.href, "http://www.facebook.com/oauth/...", "OAuth dialog not started.");

但如果当然,没有实际的导航。如何进行测试?

4

3 回答 3

5

您所做的实际上不是单元测试,更像是验收测试。

您可能应该研究一下selenium Web 驱动程序,它可以轻松测试页面导航等内容。

于 2011-11-14T20:56:18.543 回答
1

我现在看到你不能监视二传手(这是我在下面推荐的)。我已经写了解决方案,所以我想我会发布它,以防没有这个限制的人访问这个页面......

定义一个可公开访问的函数进行导航,例如:

MyNameSpace.navigate = function( url ) {
    window.location.href = url;
};

现在,在您的测试中,您可以将调用存根MyNameSpace.navigate()并确保它被正确调用。这是一个示例(不确定您使用的是什么测试框架,所以如果实现不清楚,请告诉我)。

设置和拆除:

setUp( function() {
    this._navigate = MyNameSpace.navigate;
    MyNameSpace.navigate = function( url ) {
        this.calledWith = url;
    };
});
tearDown( function() {
    MyNameSpace.navigate = this._navigate;
});

你的测试,重新实现:

test( function() {
    // set up fb mock to not be connected
    fbAsyncInit(); // simulate the startup of app
    $('#login-btn').click();
    equal(MyNameSpace.navigate.calledWith, "http://www.facebook.com/oauth/...", "OAuth dialog not started.");
});

您的查询想法window.location.href不仅会测试您的应用程序代码,还会测试浏览器本身(即当我的应用程序设置时浏览器是否正确重定向window.location.href)。专用navigate方法允许您测试应用程序内部是否按预期运行,同时阻止浏览器响应。

于 2011-12-30T01:27:25.130 回答
0

你可以检查这个JavaScript 测试你能走多远?问题。

Selenium 确实不错,也很有名,但我个人觉得它很老,不太好用。我建议使用Ghostbuster(参见简介),这是一个运行用 Javascript 或 Coffeescript 编写的测试的无头 Webkit。

您给定的测试用例将编写如下:

phantom.test.root = "http://localhost/"     # or whatever your testing env's root

phantom.test.add "Facebook login", ->       # this adds a test
  @get '/yourLoginPage', ->                 # relative to the previous root
    @body.click '#login-btn'
    @assertLocation "http://www.facebook.com/oauth/..."
    @succeed()                              # all tests must succeed

:)

于 2011-11-21T17:52:16.577 回答