Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit Testing for Rails, including an autotest script to make TDD life easier for the autotest-addicted.
It was too many steps, too many different projects, and too much dependence on prototypejs. So let’s fix this via the spanky new newjs (introduced here):
It installs all assets, gives you a rake test:javascripts task, gives you script/js_autotest, and finally (and most importantly), creates the application_test.html test stub.
As always, you can also run a single test file by loading it into a browser.
Prototype independence
Previously, the test suite – unittest.js – had a dependency on prototypejs. This was wonderful if you’re developing in prototypejs, but could cause some grief if you weren’t.
newjs now comes packed with an identical test suite – jsunittest – but it is built without a dependency on prototypejs.
Merb et al support
I wrote a rails generator because I used Rails. If a merb/other framework (Ruby or non-Ruby) wants a similar generator, just ask. Its pretty simple – I copy over the rails_generators folder into a merb_generators folder in newjs and change some things based on your frameworks’ structure.
Alternate test suite support
If you like another test suite, and want it included in the generators, this might require some additional effort on your part. It probably has different mechanisms for launching runners etc; whereas I was able to steal the rake tests + support libraries from prototypejs. But, it can be done.
Peepcode
These tools will be discussed in animated detail in the forth coming Peepcode “JavaScript Unit Testing”.
Want to start a new JavaScript project for a library or widget/badge for your website?
You know you should do TDD but wouldn’t know how to get started, what support libraries you need and where to get them from?
You need tools to deploy your library, your website etc?
You’d like a consistent structure to your project so that IDEs could provide support (toggle btw src/person.js and test/unit/person_test.html) [I haven’t done this bit yet, I’m sure I’ll add it to the JavaScipt Unit testing textmate bundle one day soon].
I fell instantly in love with Rails for a couple reasons:
rails & script/generate commands – they teach you what files you need
and where they should go
Ajax support – the marketing phrase “its as easy to use Ajax as not to” took me
away from ASP.NET where the new Ajax.NET library was non-trivial to use; RJS
didn’t exist at this stage, but Rails’ JavaScript support was still awesome
TextMate – though I didn’t get to use it for 18 mths til I bought a Mac
Later I fell in love with Ruby, for its meta-programming, syntactical possibilities
and free TDD support within Rails.
Then I fell out of love with JavaScript. Partly because Rails started generating JavaScript for me, and ultimately because I didn’t have test support. Whether you use Rails JavaScript helpers, or write your own unobtrusive JavaScript libraries you’re still living in an unhappy world without tests; let alone without TDD.
I still wrote JavaScript because it still needed writing. But a lot of my JavaScript
became “write-once, modify-never” affairs. Not just because I had no tests,
but each project had a different structure, different deployment processes, etc.
Finally, this year I figured out “TDD for JavaScript”. For every 1000 blog articles about Rails or Ruby, there is 0-1 article on unit testing JavaScript. Or perhaps I just don’t know how to use Google. Soon, the “JavaScript Unit Testing” PeepCode will be finished, so hopefully it will add to this lacking body of knowledge.
What I needed now was one-line starter-kit for new JavaScript projects that included:
A standard structure for JavaScript libraries/projects
In-built testing support, with rake tasks and script/generate unit_test
generators
Tasks for deploying distribution files (via version numbers)
Tasks for managing the project website
I don’t think there is one already, thus my hand was forced: newjs.
Installation & Getting Started
Installation and maintenance of generated JavaScript projects requires the installation of Ruby and RubyGems.
The command-line application newjs is installed as below, for any operating system (except the ‘sudo’ part – use as necessary):
sudo gem install newjs
You’ll note it uses RubiGen because I like to cheat when it comes to generating things.
To kick-off your new project/library, run the command-line app newjs:
And you thought you wanted to create all that by hand…
TDD for JavaScript
Personally, I can never remember what basic HTML + JavaScript goes in the test HTML files. I quite like the javascript_test plugin for Rails, which allows you to generate a test HTML stub. So I’ve included a version of it
here.
Two actually: one for unit tests and one for functional tests.
Merb 0.4 will include generators (via RubiGen) to make it uber-easy for developers to create Merb apps. Here’s a HOWTO screencast (lifted from rubyconf talk) on getting the required gems from SVN, and setting up a Merb to use ActiveRecord.
The video also shows how your generated model/controllers can either have test::unit OR rspec test files generated.
As Albert Einstein said “All your base belong to us.”
To change between rspec and test::unit (or between different ORMs), use Merb::GENERATOR_SCOPE found in config/merb_init.rb, rather than hack script/generate as I do in the video
Prior to following the video tutorial, you need to checkout the two edge gem sources:
svn co http://svn.devjavu.com/merb/trunk merb
svn co http://svn.devjavu.com/merb/plugins/merb_activerecord
The videos don’t have voice overs, because if I’d done that then I’d have been completely bored when I gave my talk. As it was, I think half my talk was videos and screencasts – I felt like a TV host… it was odd. But, you’ll get the gist.
For more step-by-step instructions, see the man who helped write the Merb generators – Daniel Neighman (irc – hassox).
I took a video recorder to the RejectConf, like I did in Portland. Unfortunately, there were two reasons I didn’t record any of them.
Firstly, there didn’t seem to be any obvious place to position the camera.
Secondly, it was deemed critical that everyone does their talks in the dark. The conference isn’t run in the dark, local Ruby groups don’t run meetings in the dark but consecutive RejectConfs have been run by adminstrators with a dark fetish. Great for drinking beer and heckling presenters. Bad for video recording.
The makers of the JVC HDD camcorder – a nifty device with a 20G HDD in it – don’t make it possible to record in the dark. Not because it doesn’t have a “night time mode” – apparently it does – but when you are already in the dark, you can’t figure out how to turn it on.
Ok, fine, if I’d made an effort I could have figured it out. So, let’s use excuse #1 as the reason for not recording the presentations.
Its a valid excuse, the Pirate Cove was chock-a-block full of people. The local Berlin Ruby Group did an awesome job of finding a great “underground”-esque venue.
Fortunately a fellow Australian – Marcus Crafter – had a front row position, and a MacBook Pro. With said device, he captured my talk on RubiGen (and John Barton’s).
RejectConf video of RubiGen
In 5 minutes, I make a Merb generator, using RubiGen and NewGem. Nifty stuff indeed.
There were lots of other awesome presentations (that is perhaps a dubious inference that mine was awesome), but it was dark, I had beer in both hands, and I was too busy yelling “AUSTRALIA!!!” to write notes.