Developer Day Notes 7: JavaScript Testing in Rails

by Larry Karnowski

It’s TAFT, not TATFT* (*except JavaScript).

Want to test a simple js app. Let’s test with Blue Ridge, first by installing the plugin to the example app (app is avail. on GH).

It has some basic js, looks a lot like RSpec or Micronaut. Doing “rake test:javascripts” runs the tests on the command line and “rake js:fixtures” to get a project.html file he can open a browser and run tests from.

If you install the TextMate bundle and hit Apple-R, it’ll open a TextMate window and run the tests there.

The app comes with some basic functionality: a form for a Project (which has a js class), you can add rows to the form, and it has a stub reply of “Ask again later”. So in Blue Ridge, let’s create the javascript spec for the Project js class: “script/generate javascript_spec project”.

The first run of this skeleton fails because the main project js uses the jQuery defaultValue plugin. So he stubs it out in the spec_helper.js and his specs run.

He writes a test for a function to pull all the languages out of the example form, then turns to create a fixture for the test. The simple way is to edit the test HTML file and create the form elements. It works.

But when he creates another test for the empty set when there are no languages, that file method gets clunky fast. So he uses a fixture() method using jQuery DOM creation methods in his spec to define the fixture, as well as setup/teardown code to instantiate fixtures and clear them afterwards.

With a quick Rakefile edit, it’s easy to make the default “rake” task run the JavaScript tests after the usual Ruby tests.

So what are all the moving parts? First, ScrewUnit is a js port of RSpec. Rhino is the Java implementation of JavaScript so you can run it in the JVM from the command-line. The env.js is a fake implementation of the DOM that is loaded for ScrewUnit. You can do every sort of normal DOM manipulation at the CLI.

We use Run Code Run, an app we run at Relevance for continuous integration.

There’s a nice Blue Ridge fork of the ScrewUnit TextMade bundle on karnowski’s GitHub account.

Next, testing and coding the response to the form. There’s a js mock library called Smoke bundled with Blue Ridge that makes this testing straightforward, feels a lot like mocha.

He works very step-by-step “do the simplest possible thing”, very XP style where code will do things like “return ‘no’;” instead of doing actual work to drive the creation of good tests. Suggests doing “ping pong” pair development where one person writes tests and the other person writes implementation.

“Has anyone here does Test-Driven Development of JavaScript? (No hands.) Well, now you can.”

Q&A:

Q: Putting fixtures in code seems like redundancy. Can you remove it? A: Yeah, it’s sort of redundant, but you have to have it because the browser and cli work differently.

Q: (Something about js standards.) A: The JS community is not test-infected, outside of jQuery. I’d like to see that change, and Blue Ridge go from Rails plugin to gem so it can be used more places.