Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何对页面导航进行单元测试?_Javascript_Unit Testing_Browser_Window.location - Fatal编程技术网

Javascript 如何对页面导航进行单元测试?

Javascript 如何对页面导航进行单元测试?,javascript,unit-testing,browser,window.location,Javascript,Unit Testing,Browser,Window.location,用例是这样的:我想对页面中运行的代码进行单元测试(在浏览器、QUnit或类似的东西中)。一个页面可以做的事情之一就是导航到另一个页面。我无法捕获此事件,因为: beforeunload无法停止操作(因此第一次导航会中断我的测试) 试图用getter返回旧值和间谍setter重新定义window.location或window.location.href也是被禁止的 我知道有一些安全原因不允许停止导航,但对于开发来说,能够这样做是非常有用的 有没有可能做到这一点(我对testrunner没有直

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

  • beforeunload无法停止操作(因此第一次导航会中断我的测试)
  • 试图用getter返回旧值和间谍setter重新定义window.location或window.location.href也是被禁止的
我知道有一些安全原因不允许停止导航,但对于开发来说,能够这样做是非常有用的

有没有可能做到这一点(我对testrunner没有直接的控制权,所以我不能只在iframe中加载代码,让它导航,然后检查iframe的位置)

编辑:更具体一点:我想测试,根据facebook的登录/连接状态(我使用从github到mock fb的facebook存根),登录按钮上是否安装了正确的处理程序(比如,
$(“#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.");

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

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

您可能应该研究哪些可以轻松测试页面导航之类的内容。

您可以检查这个问题

Selenium确实很好,也很有名,但我个人觉得它很旧,不太实用。我建议使用(请参阅),一个无头Webkit,运行用Javascript或Coffeescript编写的测试

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

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

:)

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

定义可公开访问的导航功能,例如:

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
方法允许您测试应用程序内部是否按预期运行,同时阻止浏览器响应。

好的,是和否。我不是测试整个页面,我只是测试一个单元的行为,在特定条件下做特定的事情。在任何“正常”的情况下,我都可以模拟导航部分,这将是一个很好的旧单元测试。或者可能不是,如果我要测试的东西是$('#btn')。单击()检查在设置的环境中安装了正确的处理程序。。。看起来像介于两者之间的st:“处理程序是在某种情况下安装的”是一个单元测试,但“该处理程序执行正确的导航”更容易被接受…:-/而且处理程序可以选择url DynamicAllysis,因为它是一个无头webkit,如果它可以与JS测试驱动程序一起工作,作为浏览器的角色,那就太好了。这将很好地解决我的问题。@herby我不确定我是否理解你所说的“以浏览器的角色使用JS测试驱动程序”是什么意思。你的意思是用调用替换Webkit引擎?不,使用Ghostbuster作为JS测试驱动程序的浏览器之一。但是,它要复杂得多-它应该加载的东西,而不是。。。这实际上也是从外部进行测试,而不是模拟位置并阻止其在内部导航…@herby Ghostbuster提供测试解析和执行。如果您只是想要一个无头Webkit,请使用它,Ghostbuster就是基于它构建的。然而,它需要与JS测试驱动程序绑定…也许你可以尝试?无头(甚至有头)任何让我模拟location=之类的东西(也就是说,让它们可配置,我可以自己进行模拟)。当然,也可以看到其他不理想的解决方案。也许我应该重新考虑在浏览器中测试我的浏览器代码的想法,寻找一些类似浏览器但特别适合测试的。。。(node.js+jsdom+glue code?)我也提出了这个解决方案(我在那里有
App
名称空间,其中应用程序的各种配置都放在开头,然后用一些单例填充,比如socket.io流到服务器),但这并不是一个真正有效的解决方案——我必须更改代码以使测试正常工作,这是一件坏事(tm)。也许如果我没有更好的解决办法,我会用这个,但我会觉得我是个罪人。代码必须独立于测试实现细节,如果不应该仅仅为了测试可以工作而更改代码的话。无论如何,谢谢。现在,我的想法是将所有“连接到外部世界的连接器”都放在自己的隐藏中,或者将视口iFrame放在一边,并通过API专门与它们通信,因此,我把这件事推迟了一层——如果代码本身足够简短和易懂,也许我会满足于没有完全覆盖facebook连接器登录部分。至于“你的想法查询window.location.href不仅会测试你的应用程序代码,还会测试浏览器本身”——另一方面,它会测试这个问题(“重定向”)好吧,即使它是通过任何库或简单的分配来完成的。这样测试就不那么脆弱了,每当我选择使用另一个代码进行重定向时,我都不需要更改它。即使纯粹主义者的观点认为这样的测试会得到一些认可,并且不能被拼写为纯粹的单元测试。。。