在客户端测试 Javascript
我编写了一个实时 js 应用程序,它具有以下堆栈:
- 用于服务器的 Node.js
- 通信层
- Socket.io 作为前端的
JQuery 来操作 dom 等。对于 #1,我的测试绝对没有问题。我目前正在使用nodeunit,它做得非常出色。
对于#3,我在尝试找出测试方法时遇到了一些麻烦。
我的浏览器端代码通常是这样的:
var user = {
// Rendered by html
id: null,
roomId: null,
foo: null,
// Set by node server.
socket: null,
clientId: null,
...
}
$('button#ready').click(function() {
socket.emit('READY');
});
socket.on('INIT', function(clientId, userIds, serverName) {
user.clientId = clientId;
user.foo = (serverName == 'bar') ? 'bar' : 'baz';
});
我想测试的主要部分包括检查当服务器使用指定参数触发某个数据包时,浏览器端的js是否会做出相应的反应:
即 user.foo = (serverName == 'bar') ? 'bar' : 'baz';
关于如何解决这个问题有什么好的建议吗?
I wrote a real time js app that has the following stack:
- Node.js for server
- Socket.io as a communication layer
- JQuery on the front end to manipulate dom etc.
For #1, I have absolutely no problem testing. I am currently using nodeunit which is doing a fantastic job.
For #3, I am having a little trouble trying to figure out my approach to testing.
My browser side code is generally something like that:
var user = {
// Rendered by html
id: null,
roomId: null,
foo: null,
// Set by node server.
socket: null,
clientId: null,
...
}
$('button#ready').click(function() {
socket.emit('READY');
});
socket.on('INIT', function(clientId, userIds, serverName) {
user.clientId = clientId;
user.foo = (serverName == 'bar') ? 'bar' : 'baz';
});
The main part which I would like to test involves checking if the js on the browser side will react accordingly when the server fires a certain packet with specified arguments:
i.e.
user.foo = (serverName == 'bar') ? 'bar' : 'baz';
Any good recommendations on how to approach this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看 Mocha。它对在节点和浏览器中运行都有很好的支持。我发现它比其他选择(茉莉花、誓言)更可取。
另外,我没有运行像 Selenium 这样的重量级集成设置,而是使用 在一个进程中运行服务器测试和浏览器测试僵尸。它允许一些漂亮的集成工作流程(例如在浏览器上触发某些内容,然后验证服务器上的效果)。
然而,YMMV 因为 Zombie 依赖于 JSDOM(Javascript 中的 DOM 重新实现)。有粗糙的边缘尚未修补/固定,东西破损。如果这是一个问题,请使用真实的浏览器(可能通过 Selenium 来利用)在浏览器中运行 Mocha。
Check out Mocha. It has a very nice support to run both in node and in the browser. I found it vastly more preferable to other options (Jasmine, Vows).
Also, instead of running a heavy-weight integration setup like Selenium, I'm running both server tests and browser tests in one process using Zombie. It allows for some beautiful integration workflows (like triggering something on the browser and then verifying effects on the server).
YMMV however as Zombie is relying on JSDOM (DOM re-implementation in Javascript). There are rough edges on yet patched/fixed, stuff breaks. If that's a problem, run Mocha in the browser using real browsers (harnessed through Selenium perhaps).
尽管 Pivotal 对 jasmine 的支持有点碰运气(新开发很少,github 上有很多未解决的问题/拉请求),Jasmine 是一个非常好的测试客户端代码的工具,主要是因为 茉莉-jquery。
Jasmine 的一般方法非常可靠,Jasmine-Jquery 有很多用于测试 DOM 的出色匹配器,以及出色的 DOM 沙箱。
我发现客户端测试是一个挑战,主要是因为我必须停止在测试中如此严格和规范。
一般来说,您应该以一种“模糊”的方式进行客户端测试,过于具体地测试 DOM 层次结构是一条通往地狱的道路。测试诸如“页面是否包含这些单词”和“div id#my-div 是否包含带有 3 个 li 的 ul 且其内容与此正则表达式匹配的内容”之类的内容。
后者是我开始进行测试的方式,但我发现它非常耗时,并且脆弱的;如果设计师(我)想要破坏结构,则可能会不必要地破坏许多测试。解决这个问题的唯一方法是为每个组件创建“小部件”,这将是理想的,但正如我所说,非常耗时,它实际上成为我办公室的一个笑话:“蒂姆,你这周做了多少测试? 2?3?哇,3 次测试。”
无论如何……
通过松散测试并专注于重要的事情(例如页面层次结构中特定位置中特定内容的工作流程和数据“存在”),您可以获得进行客户端测试的 90% 的好处。
编辑:此外,请确保将业务逻辑尽可能地分解为独立于 DOM 的单元。这会让你的生活变得更加轻松,并且通常会带来更好的架构,这是一个优点。
编辑 2:您可能想了解 Rails 世界如何使用 Capybara/Cucumber 或 Selenium 来实现这一点。
As much as Pivotal's support for jasmine is a bit hit and miss (minimal new development, lots of unanswered issues/pull-requests on their github), Jasmine is a really good tool for testing client-side code, mainly because of jasmine-jquery.
Jasmine's general approach is pretty solid and Jasmine-Jquery has a lot of great matchers for testing the DOM, as well as great DOM sandboxing.
I found testing on the client-side a challenge, mainly because I had to stop being so rigid and prescriptive in my tests.
Generally, you should approach client-side testing in a kind of 'fuzzy' way, testing the DOM hierarchy too specifically is a road to hell. Test things like, "Does the page contain these words" over "Does div id#my-div contain a ul with 3 li's with content that matches this regex"
The latter is how I started doing tests but I found it incredibly time consuming and fragile; if the designer (me) want to mess with the structure, it'd could unnecessarily break many tests. The only way to get around it is to create 'widgets' for each component, which would be ideal but as I said, very time consuming, it actually became a running joke at my office: "how many tests you done this week Tim? 2? 3? Wow 3 tests. Good work."
Anyway…
You can get 90% of the benefit of doing client-side testing by testing loosely, and focusing on what's important, such as workflow and data 'presence' over specific content in a specific location in the hierarchy on the page.
edit: Also, ensure you break the business logic into units that are independent of the DOM, as much as humanly possible. That makes your life a lot easier, and generally leads to better architecture, which is a plus.
edit 2: You might want to look into how the Rails world does this using Capybara/Cucumber or Selenium.