Ryan Seddon
javascript
Bunyip: client-side unit testing made easy
Let’s face it doing thorough client-side unit testing fills me with rage, throw mobile browsers into the mix and I want to start flipping tables. There are tools out there to somewhat tackle this issue but they either require painful setups or want you to rewrite your unit tests using their framework. What if I told you there’s a tool that is easy to get up and running, doesn’t require you to rewrite your tests and allows you do it all from the command line in desktop and mobile browsers. Watch a video showing it working.
The codestream video can take a while to load sometimes, be patient. {{ < /rawhtml >}} If you want to get stuck in go check out [Bunyip][1] on github and see the readme for instructions on getting up and running. It’s really easy I promise. ## Bunyip {.subtitle02} At [Web Directions Code][2] conference in Melbourne this past May I demonstrated this tool on stage in my talk [“Debugging secrets of a lazy developer”][3]. I started thinking about a tool like this when I joined the Modernizr team and how annoying, but important, it was to utilise the powerful test suite we have. Opening all the browsers and visually checking the test suite results is time consuming, thankfully a series of open source tools and a powerful API made this idea become a reality. ## On the backs of great projects {.subtitle02} The first tool that got Bunyip into a usable state is [Yeti][4] an incredibly powerful tool from Yahoo that allows to push out a html file to any connected browsers from the command line. It launches a little server on your machine that browsers on the same network can connect to. The downside initially was that it required you to use the YUI testing framework, but this tool was way too awesome to ignore it on that factor. So I dug in and discovered how it was sending back the results to the cli and wrote some [adaptors][5] for QUnit and jasmine to work with Yeti. If you use another framework feel free to do a pull request! In the Yeti docs they suggest enabling mobile support by using a service called [localtunnel][6] which allows you to create an SSH tunnel into your local server so you can access it from outside your local network. I found localtunnel to be slow and sporadic with Yeti especially when the test suite was quite large. I settled on another service called [pagekite][7] which gives you 2.5GB of data for free and the ability to register a subdomain after that it’s pretty cheap. You can also check out [showoff.io][8]. Next is a great service called [BrowserStack][9]. BrowserStack lets you test web sites in a whole bunch of browsers but more importantly they offer an [API][10] so you can spin up a browser and pass it a url. Exactly what I needed to make bunyip amazing. When I started building this tool the API only had support for desktop browsers, just before I did my talk they rolled out v2 which included mac and mobile browsers! Since I’m building this as a node module I’m using the very awesome node-browserstack module by Scott Gonzales to make using the API very easy. ## How it works {.subtitle02} As mentioned previously this is reliant on a lot of great OSS. To get into the deeper level on how this works you can comb through the code on github or read on for a high level look. ## Local server {.subtitle02} When you run this command `bunyip -f test/index.html -b "firefox:win/12.0|ie:win/8.0|safari:mac/5.1|iPhone 4S:ios/5.0"` in bunyip the first thing it does is hand off the `-f test/index.html` call to Yeti to spin up a local server that will have an intermediate page that will accessible via localhost:9000. Yeti uses socket.io to notify the cli when a slave connects and vice versa to control when a test should begin. ## SSH tunnel and BrowserStack {.subtitle02} Once Yeti is up and running bunyip will then grab the tunnel service config values from the file you would of setup. In my case it will run the pagekite.py script passing in my port 9000 and my subdomain I want it accessible via bunyip.pagekite.me. We now have our tunnel up and running. Next we can parse the `-b "firefox:win/12.0|ie:win/8.0|safari:mac/5.1|iPhone 4S:ios/5.0"` flag into a usable JSON string we can send off to the BrowserStack API. It looks like this:[
{
"browser": "ie",
"os": "win",
"version": "8.0",
"url": "https://bunyip.pagekite.me/",
"timeout": 480
}
]