如何对页面导航进行单元测试?
用例是这样的:我想对页面中运行的代码进行单元测试(在浏览器、QUnit 或类似的东西中)。页面可以做的事情之一就是导航到另一个页面。我在捕获此事件时遇到问题,因为:
- beforeunload 无法停止该操作(因此第一个导航离开会破坏我的测试)
- 尝试重新定义 window.location 或 window.location.href ,并且 getter 返回旧值并且间谍 setter 也被
禁止了解出于安全原因不允许停止导航,但对于开发而言,能够这样做确实很有用。
有没有可能做到这一点(我无法直接控制测试运行程序,因此我不能只在 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.");
但如果当然,没有实际的导航。如何进行测试?
Use case is this: I want to unit test (in browser, QUnit or something of the kind) a code run in a page. One of the things a page can do is to navigate away to another page. I have problem catching this event, because:
- beforeunload cannot stop the action (so the first navigation-away breaks my test)
- trying to redefine window.location or window.location.href with getter returning old value and spying setter is prohibited, too
I understand there are security reasons that disallow possibility to stop navigating away, but for development it is really useful to be able to do so.
Is there any possibility to do this (I have no direct control over test runner, so I can't just load the code in the iframe and let it navigate and then examine location of the iframe)?
EDIT: To be a little more specific: I want to test, whether, based on the logged/connected status from facebook (I use facebook-stub from github to mock fb), there is the right handler is installed on the login button (say, $('#login-btn')
), which by clicking navigates the page to facebook oauth dialog, server-flow (the details here are not important).
So I would like to be able to do this kind of thing:
// 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.");
but if course, without actual navigation. How to do the test?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您所做的实际上不是单元测试,更像是验收测试。
您可能应该研究 selenium Web 驱动程序,它可以轻松测试页面导航等内容。
What you are doing is really not unit testing, more like acceptance testing.
You should probably look into selenium web driver which can easily test stuff like page navigation.
我现在发现你无法监视二传手(这就是我在下面推荐的)。我已经写好了解决方案,所以我想我会发布它,以防没有该限制的人访问此页面...
定义一个可公开访问的函数来导航,例如:
现在,在您的测试中,您可以存根对
MyNameSpace.navigate()
的调用并确保它被正确调用。这是一个示例(不确定您使用的是什么测试框架,所以如果实现不清楚,请告诉我)。设置和拆卸:
以及您的测试,重新实现:
您查询
window.location.href
的想法不仅会测试您的应用程序代码,还会测试浏览器本身(即,浏览器在以下情况下是否正确重定向):我的应用程序设置了window.location.href
)。专用的navigate
方法允许您测试应用程序内部是否按预期运行,同时防止浏览器响应。I'm seeing now that you can't spy on a setter (which is what I'm recommending below). I've already written up the solution, so I think I'll post it in case someone without that restriction should visit this page...
Define a publicly-accessible function to navigate, for instance:
Now, in your tests, you can stub out the call to
MyNameSpace.navigate()
and ensure it is invoked properly. Here's an example (not sure what testing framework you're using, so let me know if the implementation is unclear).Set up and tear down:
And your test, re-implemented:
Your idea to query
window.location.href
would not only test your application code, but the browser itself (i.e. does the browser redirect properly when my application setswindow.location.href
). A dedicatednavigate
method allows you to test that your application internals are operating as expected and simultaneously prevent the browser from responding.你可以检查这个 JavaScript 测试你能走多远?问题。
Selenium 确实很好,也很出名,但我个人觉得它相当老旧,不太好用。我建议使用 Ghostbuster (参见 介绍),无头 Webkit 运行用 Javascript 或 Coffeescript 编写的测试。
您给定的测试用例将写成如下:
:)
You could check this How far can you go with JavaScript testing? question.
Selenium is indeed good and well-known, but I personally find it quite old and not so usable. I'd advise using Ghostbuster (see introduction), a headless Webkit running tests written in Javascript or Coffeescript.
Your given test-case would be written as follows:
:)