How can I test client side coffeescript/js using node with expresso/jasmine/<other>
I have a web app where the client side stuff is written with coffeescript and loaded with require.js.
I would like to be able to isolate and test this stuff using a node based test runner such as expresso (although other suggestions are welcome) so that I can integrate the client side testing with our CI server - which is currently Team City.
Here's my directory set up:
.
├── coffee
│ ├── models
│ ├── node_modules
│ │ └── expresso
│ ├── spec
│ ├── tests
│ └── views
├── static
│ └── js
│ ├── lib
│ ├── models
│ ├── tests
│ └── views
These are hooked up using require.js like so:
deps = [
"lib/backbone", "models/websocket_collection", "/static/js/lib/date.js"
]
define(deps, (Backbone, ws) ->
# module code and exports here
And loaded into the browser like so:
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="my_mod" src="/static/js/my_mod.js"></script>
In an idea world now I'd like to be able to have a test module that looks like:
{Model1, Model2} = require "models/some_module"
exports.test_a = ->
assert.equal # etc etc
I have several problems (having not really used node server side except when I played with zombie.js)
How do I tell node where all of my plain javascript dependencies are (in static/js/lib) some of these are as downloaded, but backbone.js has been marked up with require.js define stuff like so
define(function(require, exports, module) { (function(){
How do I actually run the tests? I've tried r.js (which as I understand it is supposed to be a bridge between browser side require and node's require)
the problem I'm getting is:
ReferenceError: define is not defined
I've also tried to require("allplugins-require") which is the script I load browser side to collect all of my client code, but that seems to break node's require.
- Is anybody doing this?
- If you're not doing开发者_StackOverflow this how are you testing your code (bonus points for integration with CI)?
- Any alternatives to require.js for managing client side dependencies that might play a bit better on the server side?
I'd be very happy to hear alternative approaches that people are using.
Thanks, Ben
The docs for running requirejs via r.js in node are here. In particular, r.js replaces node's require with its own. It can load node-only packages/modules that are installed via npm as long as the npm-installed modules are not visible to the require.js config.
The other caveat is that r.js needs to be a sibling file to the main.js, the top level app js file that is run in the node environment.
The latest code for r.js will support loading requirejs as a node module (as in require('requirejs') and that will give a better integration story. That change will be in the 0.26.0 release.
I spent a long time trying to get this to work and eventually gave up. I did get it working, by referencing all of my require.js dependencies in a global variable and using that for the node.js tests, but the design was so ugly that I felt that I had defeated the point.
My current approach is:
- write my JavaScript modules as CommonJS modules
- Use the Jasmine BDD node integration to test my modules server-side
- Use stitch to make the CommonJS modules work client-side
This is working well for me, with the following caveats:
- Client-side debugging is difficult because stitch concatenates all my scripts. I found that leaving out libraries like jQuery from the stitch configuration helped with this.
- I don't have any way to debug server-side. There is a node.js debugger but it has not worked with the last few versions of node.
Ok, a few days hacking and I've now got my client side code (some of it anyway) packaged as commonjs modules and tested with jasmine-node.
If anyone's interested I've forked jasmine-node to add outputting of an xml file that integrates with a CI server. This is working pretty well.
I'll report back after I get stitch up and running.
Here's my fork: https://github.com/boothead/jasmine-node
精彩评论