038 JSJ Jasmine with Justin Searls

Download MP3



01:33 - Justin Searls





JAMISON:  Holy cow! JOE:   That was not annoying. CHUCK:  What’s not annoying? MERRICK:  He is punching a bag of Fritos? JOE:  Yeah. [Laughter] CHUCK:   Well, I was closing it up so they don’t get stale as fast. JOE:  You’re very thorough. Those are going to be the least stale… MERRICK:  Do you have like a Frito resealer or something? [Laughter][shrill sound] CHUCK:  Okay, sealed. [This episode is sponsored by Component One, makers of Wijmo. If you need stunning UI elements or awesome graphs and charts, then go to Wijmo.com and check them out.] [Hosting and bandwidth provided by the Blue Box Group. Check them out at Bluebox.net.] CHUCK:   Hey everybody, and welcome to Episode 38 of the JavaScript Jabber show. This week on our panel, we have Jamison Dance. JAMISON:   Hi guys! CHUCK:   Joe Eames. JOE:   Howdy? CHUCK:  Merrick Christensen. MERRICK:   What’s up? CHUCK:  AJ O’Neal is trying to join the call. He’s here. AJ:   Yo! Yo! Yo! Coming at you live from the Rental Agreement sphere of Provo, Utah. MERRICK:  He lives! CHUCK:  I’m Charles Max Wood from DevChat.tv. And this week, we have a special guest. That’s Justin Searls. JUSTIN:  Hello. CHUCK:  So, why don’t you tell us a little bit about yourself, Justin? JUSTIN:  Okay. Well, now that I’m on the spot, my name is Justin. I’m a software developer. I live in Columbus, Ohio. About a year ago, me and a guy named Todd Kaufman started a new company called Test Double. Previously, he and I had been doing consulting for a long, long time. And we’re up to eight people now. And we have a good time building software with an emphasis on terrific interaction design which has resulted in us kind of developing a specialty for well-crafted frontend code, predominantly JavaScript. And I imagine that’s probably why I’m here today. CHUCK:  Awesome. Alright. Well, we brought you on to talk about Jasmine. Jasmine was written by, was it Pivotal Labs?   JUSTIN:  Yeah, Pivotal Labs guys. A guy names Christian Williams who I think has since moved on to Square, and D.W. Frank who’s still at Pivotal. They wrote the core library and me and a whole bunch of other people in the community have piled on with different runners and add-ons and extensions in the sort of like little ecosystem of the 25 people who write unit tests for JavaScript. CHUCK:   All 25 of you, huh? JUSTIN:   Well, it’s not a lot, right? It’s been a fun journey of being one of the very few people who really, really got excited or chose to get excited about making it easier for folks to write tests in JavaScript or as easy as it would be for whatever servers and language they’d be using. I kind of have this pet theory that a lot of people sort of secretly, in the back of their mind, long for the days, before there was a social expectation that they test their code and sort of revel in the fact that socially it’s totally acceptable to not test your JavaScript. Whereas if you’re a Ruby developer, I think everyone expects there to be tests. So, I’m kind of here to ruin the party for people, is usually my role on teams. [Laughter] CHUCK:  Cool! JAMISON:  So why do you think that is? Why do you think people don’t test their JavaScripts as much? JUSTIN:   I think there’s a lot of reasons, some of it is cultural. So really very few people have ever set out to become JavaScript developers someday just by nature of the fact that JavaScript is the only language that runs in browsers, we’re all kind of stuck with it to a certain extent. And whenever you’re stuck with something, you’re much less likely to be motivated to really master it especially because if it wasn’t your primary choice of language that you’d want to be writing. One of the things I like to look at is the history of Ruby on Rails and its development where you sort of see from the top on down, every major Rails release included some headlining feature who’s sole purpose was to help developers get by writing less actual JavaScript. And they’re still doing it right like with Pjax, Turbolinks, and RJS. [Laughter] MERRICK:  It’s one of the most heartbreaking things about Rails for me. JUSTIN:   Yeah, me too. And I think that that’s sort of like -- to call it the Ruby community like a culture isn’t fair but I think until a couple years ago, it was the extremely prevailing view that I ran into was that if a problem could possibly be solved, if a solution could be so contorted as to be solved in the server side, absolutely do that. And then funnel it down to the client side to the point that user interfaces should be really snappy and developed with the users’ experience in mind. And I found a lot of Ruby developers sacrificing good user experience so that they could improve their developer happiness which kind of makes sense because a lot of developers who came to Ruby in the first place, came because they wanted to work in an environment where they would be happy over these other concerns that they’ve kind of had in the past. AJ:   But now they have CoffeeScript, so I think that they’re at least grateful for that. CHUCK:   Yeah. I have to say as a Rails developer, I love CoffeeScript. JOE:   And they can pretend like they’re not writing their JavaScript. MERRICK:   Such hipsters. JAMISON:   Great. [Laughter] AJ:  It’s like a face for JavaScript that’s palatable for Ruby kids. CHUCK:   Yeah. JAMISON:  I like it. AJ:  I do too. But anyways, I think it’s great. I’m just trolling. JOE:   Is it like chocolate-covered broccoli when you’re keeping your kids’ dinner? [Laughter] CHUCK:  I’m going to have to try that now. JUSTIN:   Does anyone on the panel not like CoffeeScript? AJ:   I don’t use it for my projects because I haven’t felt like it gives me enough wings but I don’t dislike it, by any means. JOE:   I’m not crazy about it but I wouldn’t say I dislike it.   MERRICK:  I think it’s cute but I wouldn’t go out with her. [Crosstalk] JUSTIN:   …on Tbd and Jasmine, and I often ask people what their thoughts are about CoffeeScript in particular because I personally use CoffeeScript now. And I usually get about half the room, at any given training, of people who say they don’t like CoffeeScript and then I ask them to keep their hand up if they’ve ever tried it. And usually, only one or two hands remain. So, I think that there’s a cultural resistance especially within the JavaScript community against CoffeeScript, and I’m still trying to suss out why exactly. AJ:   I think CoffeeScript is great. But it’s another layer of abstraction that I haven’t found worth to trade particularly because I’m not a huge fan of having to build subs if you can avoid it. That’s one of the big reasons I’m a big fan of AMD. But, yeah. JAMISON:   You can do it without a build step, there’s required JS plug-ins that will just transpile it down the file. AJ:  Come on, man. I’ve written plenty of those things for Typescript and Suite, I’m all about that. But it’s just, I don’t know, man.    CHUCK:   But anyway, let’s get into what Jasmine is. From what I can tell, it’s more of a unit testing library. JUSTIN:   Yep, it’s a unit testing library that looks and feels a lot like RSpec because being written by the Pivotal guys who predominantly write Ruby on Rails with test driven RSpec. The ESO is pretty much one to one, you know. You wrap example groups of tests with the function ‘name describe’ individual tests. You pass anonymous functions to a function named ‘it’ to specify a test. There’s ‘before each’ and ‘after each’ and custom matchers have a similar ways with RSpecs with the expectation library then Jasmine ships which is pretty similar. So, if you’re familiar with RSpec, Jasmine should look very familiar to you. And being from Pivotal where they kind of practice something that approximates -- I don’t know, it’s my understanding anyway. I don’t know. I’ve never worked for Pivotal. But it’s my understanding that the Pivotal way is, they favor isolation testing where they can. So, Jasmine very much is an opinionated framework about writing really, really isolated unit tests. So, there’s no convenient way to write an integration test with Jasmine and I’ve tried and failed miserably. So, it’s really just unit testing and specially isolated unit testing. CHUCK:  So then, I’m trying to kind of understand the case for it in the sense that if you’re -- how can I put this? So if you’re building a complicated frontend for your website, then does it do well with the DOM stuff and the integration stuff or is it more focused on, say event handlers and things like that? JUSTIN:  The framework’s agnostic to all of that, the only real relationship that the framework has with the DOM is the fact that it is almost always used with an existing DOM right there. In fact, I don’t think there’s anything in the library that requires the DOM to exist. And in fact, that’s one of the reasons why Win Node.js became popular. Jasmine was one of the first test runners that was used because it needed to be DOM free. I think the motivation for Jasmine, if I remember correctly, had to do with Enyo, the app framework for webOS. So like, the developers at Pivotal had been using Screw uniter or one of the other myriad JavaScript unit testing tools. But because of webOS, there was no DOM object there to play with, Jasmine is actually completely DOM agnostic. So, what that means is that it can test anything. I’ve never run into anything that I haven’t been able to write a test for, but it’s up to you to make that happen and organize your code in a way just like with the Java environment, in a way that produces testable designs. CHUCK:   So, when you need to test the DOM, do you just put dummy objects into the DOM? JUSTIN:  Yeah. That’s personally what I do. So, if you kind of just think of wind [inaudible] or something, or [inaudible] or something, at least I can only speak from my experience. I try to start with just the most integrated thing I can because it requires the least handling of the internal implementation of something. So if I don’t understand a particular test stack, I’m going to try to write a really integrated test that just exercises everything when it’s all plugged together. And then as I start to gain a more nuanced understanding of stuff, I will start to kind of try to write more isolated test against isolated units because that requires a real mastery over the APIs that I’m talking to. And in the case of the DOM, the journey that a lot of people take when I’ve coached dozens of people on JavaScript testing now, they’ve stop running -- say, they’re a Ruby developer. So, they’ve got these ERB templates that have Ruby in them. They want to start by writing tests against the actual parse stat and generated HTML through ERB, which would of course be very expensive because to write a JavaScript test, you’d actually need your Rails server running to process these ERB templates. So they realize that’s pretty expensive. So then, they move on to well, maybe if I just grab a snapshot of the HTML that results and then user share an HTML fixture for all of my tests. Which of course, that creates all of the problems of any other shared fixture in a unit testing environment where it just becomes a tragedy of the commons and you can’t really understand the contract between the code that you’re writing, the test that you’re writing, and then the HTML that it requires. So, they get a little bit more deeply nested where you’re kind of inserting big blocks of HTML inside of each spec but that looks ugly. So then, you just try to get better at that. Where I finally ended up after several years of JavaScript testing is, I wrote a little library called Jasmine-fixture. And the idea of Jasmine-fixture is, since I’m usually using jQuery to select stuff from the DOM, what I’d really like to do is just hand a jQuery selector to this library, it has a method called Affix. So, I hand this method called Affix jQuery selector and then the contract between me and Affix is that it will ensure that the DOM has elements that will match that jQuery selector later. So usually, my DOM set up is a one-liner at the top of a test for a function. So like, affix something that is DOM space pop bar, and that will make sure that it has stuff, it will inject stuff into the DOM that first has the class field with a check piled element with an ID bar. And that way, if I use that jQuery selector in my production code, I just magically have that there form in the DOM and it cleans up for me after the fact. JOE:  Nice. So what about Jasmine’s feature with its -- there’s a little DOM node inside that’s just built into the basics of Jasmine, and anything that you put inside there, it keeps getting reset. Is that the one that you’re talking about as like the common fixture about the tragedy of the commons? JUSTIN:   I’m not sure when this was introduced but I do know that the rule of thumb is that any stuff that you inject into the DOM should go into an element in the test runner HTML page which is something that you would be application own, or intermediate framework between you and Jasmine. It should have a div with an ID Jasmine underscore content, I want to say. And anything that goes in there, that’s like you’re one blessed place to put stuff into the DOM whether that comes up after you or not, I’m actually not sure. I know it was added at some point later if it does. But my framework cleans up after itself. When I talk about tragedy of the commons, I’m really talking about sort of the situation where, let’s say we have this really big HTML file that represents many pieces of our application. It’s like an entire page. And maybe that page would normally have like five, six, seven different JavaScript widgets or components or discreet nested functions that would all use that page, that page’s mark up. If I had five or six, seven different functions and they’re all totally separate and the only thing they have in common is that they use that mark up or depend on that markup. If I turn that into a flat HTML file and then included or incorporate it in such a way that my test grabs the entire HTML document and shoves it into the DOM, there’s a way to make it so that it has all of the bits that my test needs in order for me to write a test that passes, that exercises my code. But the problem is that many tests are sharing that one HTML file.  And so if later on, I come to it and one of those seven functions changes and I need to add to that HTML file, I’ll go to find that HTML file and I’ll add to it. But no one will ever be able to safely remove from that shared fixture. So it’ll just get uglier and uglier and uglier. If you’ve ever seen in Ruby, a tool like Factory Girl. Something like Factory Girl, those files tend to only get bigger with time because you never know really clearly whether it’s safe to make something shorter or not because even if something’s ugly, there’s always the risk that if I delete something I’m going to knock some other test out of orbit. Because there’s no clear abstract of which test needs what about this factory and if I’m just reading a test -- and when I say factory, I guess I’m meaning factory or fixture interchangeably. When I’m just reading a test, I want to know exactly, I want that test to specify exactly what the source code needs to do and anything that’s some external helper, I would need to go and pull that file up and read and understand what it’s specifying about the code that I’m writing. JOE:  So your Jasmine fixture kind of fixes that because right at the top of your test, you can write in your selectors that then tell you what the HTML is going to look like? JUSTIN:  Exactly, so that each test specifies only the bare minimum of what it needs. And that makes the test more portable if you ever want to trash your implementation and start over. It forces you into writing code that has minimal dependencies on the markup on the page which is separately probably a good practice to follow. CHUCK:  So, I guess my question comes into then, what if you have a DOM that is generated by a framework or something similar. So, you’re using Ember.js or XJS in the case of one of the projects I’m working on, and you want to get Jasmine around that. Do you wind up instantiating entire views into your DOM so you can test it? Or how do you manage that? JUSTIN:  That’s actually a really good question because I think it depends on the nature of the framework and how much magic is going on in the framework. Because if it’s a lot, if it’s doing a lot of heavy lifting for you and you’re finding that you’re doing a lot of test set up just to make the framework happy, just so that you can write a particular test that goes end to end through the DOM, over time, it starts to get more complex, starts to look more and more like an integration test. And Jasmine is just not the best tool for the job for integration testing. I prefer to use something that was like a fully automated web test at that point. So in general, if I’ve got a heavy handed framework that I’m dealing with, I’ll try to build a little tiny adapter wrapper around it, otherwise find out some other way to isolate myself from it and then just write isolation tests with Jasmine of the code that I’m writing and not write tests that cover framework code. CHUCK:  That’s interesting. I’m still trying to formulate exactly how I would manage the approach because sometimes you are using X to look up elements or look up objects in the system or components, I guess is what they call them. And so, you have to figure out whether that works if they’re instantiated or whether or not you can get away with just setting up the DOM and saying, “Look here, use this.” Or, yeah. MERRICK:  So Justin, we’ve talked a lot about, pretty much all the talk we’ve had so far is about JavaScript testing and integration with the actual DOM, right? So testing stuff that actually talks to the DOM. My own personal experience with JavaScript testing is that anytime I’m writing tests to integrate with the DOM, once my DOM interactions get past the most basic levels, that my tests become so bloated and brittle, therefore the tests themselves get to be like 50-lines long as I’m creating and trying to mimic what the functionality is that I’m trying to hook up with, that I often kind of abandon that effort. I feel like the amount of effort it takes to test just gets to be so high that it’s not worth it anymore. And so I try to just test just inside of the DOM, just inside of the UI and test my JavaScript objects, and separate them out cleanly from the DOM. Have you found that or have you found mechanisms and ways to avoid that problem so that you’ve never had any problem testing some kind of component that actually interacts with the Dom? JUSTIN:  The short answer is, I don’t have that problem. The medium length answer is, fear not because you’re in good company. I think a lot of people operate under the same MO that you just described. So, it’s something that I hear  a lot and a lot of people talk about how they only write isolation tests or only write JavaScript unit tests at a later beneath DOM interaction because they find it difficult to, in a clean straightforward and easy to maintain way, test DOM interaction at a unit level. So what you’re describing, I personally haven’t run into that and part of it is just that I’ve been pretty aggressive about identifying what part about testing this DOM interaction. And for a long time, it was the fixture stuff and I talked about that Jasmine fixture plug-in I wrote to make it easy to interject at the beginning of a test. But there’s lots of other stuff that makes it hard too. And in your example, when you’ve got a lot of DOM interaction going on or your JavaScript is responsible for maybe lots of manipulation of the DOM in lots of different ways, you could end up with a very long test. So in your example, if I had a 30 or 40 or 50-line test, I’d probably suspect that the JavaScript that I’ve got under test, the function that’s under test is probably doing too many things and I’d listen to that test pain and instead of throwing out the test or trying to test more cleverly, I’d probably try to figure out, “How do I write the lines so that each of the units under test is only doing a couple of things?” MERRICK:  So, one of the things that I specifically found was very challenging is especially an event based responsive. So I’ve got some JavaScript component that’s going to respond to an event that’s fired on the DOM, right? And especially if that event that’s fired on the DOM may be animated. So one event fires, then an animation occurs, and then at the end of the animation, another event is supposed to fire and cause something to happen, right? Setting all that up in the DOM just gets to be so unwieldy, I usually give up at that point. JUSTIN: It’s a frustration I can definitely relate to. Until a few months ago, I kind of rolled my own little lightweight frameworks to abstract me from events in particular. I think events are useful for, helps build smaller JavaScript units like in terms of functionality if we can just introduce a little bit of code that makes the event binding kind of feel more like configuration. So, if you guys are familiar with Backbone views, at the top of a Backbone view, you just toss it an object literal of events of both events that trigger on a user interface and then a jQuery selector and then mapping that to like a stringy name of a method on an object to be invoked. So that this event object literal is this static thing that you want it to be and everything after that are just individual functions that are very narrow and targeted about the interactions that you have with the DOM. And you’re not actually worried about testing. “Hey does all this event gook end up working out?” Because that’s presumably Backbone’s job and presumably Backbone is well-tested. So then, your unit test isn’t concerned with the events per se, only the functionality that you’ve bound to them. MERRICK:   Interesting. And sometimes what I’ve done to kind of make that process is if you know that you’re supposed to respond to a different event, you don’t necessarily have to inject something into the DOM you can just trigger an event and assert that whatever callback gets called in an event. The animation case is a little bit more difficult. JUSTIN:  So in that case, what I would try to do is separate the responsibility of the dude who’s doing the event binding and test that by exactly like you’re saying, simulate the event or invoke the event. [Inaudible] actually the thing that takes an action when that event occurs and put that under test, you get totally divergent types of set-up and assertions. But if you separate the problems, then both tests become a lot easier to write than one big test that mashes up both those responsibilities. MERRICK:   Sure. CHUCK:  I am a little bit curious about the syntax in Jasmine. So, you talked a little bit about describe and it and I am very familiar with RSpec myself. But I was wondering if you could just explain the utility in some of these different features and example groups and describe and it and all that stuff. JUSTIN:  I’m very wary of, in an audio podcast format getting into detailed discussions of syntax. You all have a lot more experience with that than I do. So, I hope it’s not too confusing at any point. The Jasmine ESL as it were, the actual public methods that are available to you to construct specs is very, very simple. It’s definitely a subset of RSpec features by far. The rules of it are pretty basic. I mean, at the top of a listing you’ll say, “Describe the first argument is a string to describe what you’re describing.” The second is an anonymous function. And then, similar to RSpec, what you’ll end up with are nested example groups where maybe a describe can -- let’s say, we’re testing invoice, an object named invoice and it has two methods, open and close. We might have, at the top of our listing, describe and then the string invoice anonymous function. And then inside that, two more describes that just sit next to each other and the first one describes the open methods of the string open with another nested anonymous function inside of it and another one to, later on in the listing, to describe the close method with an anonymous function inside of it. The example group organization is similar to RSpec that way. When you want to write an actual spec, the expectations have to all be put inside of a ‘it’. So, to create a new specification, you’d say “It, pass in a string which is a name of what you want to specify”, and yet another anonymous function. If it sounds like I’m saying the words ‘anonymous function’ a lot, if you’re writing Jasmine and JavaScript, you’re going to be writing function, left paren, right paren, left curly brace, right curly brace really frequently. And so, if [inaudible] that’s what pushed me over the edge to adopt CoffeeScript because it’s so much just lexically cheaper to create a new anonymous function in CoffeScript. AJ:  Yeah, those arrows are super nice. JUSTIN:  Exactly, because then you’re just hitting dash and right bracket. AJ:  I’ll give you that, those arrows are really nice. CHUCK:  So, one thing I really like about RSpec and Jasmine is specifically the ‘describe’. You can group together specs, or tests, or whatever you want to call them that are related to each other. So for example, if you’re testing a function on an object that you want to kind of get all the different edge cases and that gives you three or four tests that you have to run, then you can put a describe around it that says, “Testing open function on the invoice object,” for example. And then, you just have ‘it’. It opens the invoice with un-invoiced hours, it opens a blank invoice, it opens… And so, you can put those in there and it really breaks it down nicely. Now, one thing I like about RSpec is that you can run it without actually running the specs or tests. So, you can actually just get a read-out of what those strings are as they’re nested. Does Jasmine do that? JUSTIN:  It doesn’t do that and it also doesn’t have tremendous support for pending specs. If you want to mark a ‘describe’ block pending or an ‘it’ pending, you can put an X in front of it and it won’t count against you. But it’s difficult, from a reporting standpoint afterwards, to figure out what’s pending and what’s not. So, I don’t know about that. But obviously, just to piggyback off what you just said, another huge benefit of the RSpec and Jasmine style with nested example groups is that nesting, what it buys you is the ability to write dry tests because the before each’s that you write, the tests set up at every one of those levels, cascades down. So if I’ve got, going back to this invoice example, maybe I have each at the very, very top that creates me my new subject, my invoice and maybe does some other trivial set up. JAMISON:  I have a question for you about the async support in Jasmine because honestly it’s the thing that bothers me the most about it and the reason I don’t use it. It basically seems like Jasmine’s idea of supporting asynchronous tests is to check for stuff being done. So yeah, you need to test some async operation so that async operation needs to then modify some flag that your test can check on. Why is it done that way and have you thought about changing it? Or not you, I don’t know how involved you are in writing that. But have people in Jasmine talked about changing it? JUSTIN:  Honestly, I’m not sure. I don’t use it. My personal take is that if I have asynchronous code, it doesn’t mean I don’t have to write asynchronous tests. And in fact, it’s often advantageous for me to right synchronous tests of asynchronous code. So, outside of node… JAMISON:  Can you expand on that? What do you mean? JUSTIN:   Let’s take AJAX as a simple example because I think that’s the most common type of asynchronous code that folks do. So, let’s say I’m using jQuery and I say [inaudible] some URL. And then I pass, as a second parameter, an anonymous function to call back to. If I wanted to write a test for that, that was really asynchronous because it’s asynchronous, I’d be calling through to actual jQuery$.git. I’d have to create some fake server to provide a fake response and then call my callback. Like you described, I’d have to use the Jasmine async API in order to force Jasmine to wait until my async operations are done. Mocha, which is a computing JavaScript testing tool, has async API but it’s still a little bit obnoxious because you have to tell it when you’re done just by nature of the fact that it would have no idea otherwise. So, what I do personally is whenever I’ve got an asynchronous dependency, because I write isolated unit tests, I’m probably dealing with Test Doubles everywhere. So if I’ve got an object that I’ve declared as being responsible for my AJAX operations, I’m probably talking to a fake one. And if I'm talking to a fake one, I could just [inaudible] the function that I pass it for me. So, Jasmine comes with Spies. Spies are the Test Doubles or in common terms, the mocks that ship with Jasmine. I would say in our example, using $.git, I might spy on $.git, then every time in my subject code, the $.git gets called, that simply gets recorded for later. And in my test, I can say, “Hey dollar, get the most recent call, get the arguments, then look at the second argument that’s a function reference.” And then I could put that function reference under test immediately just like it was any other function. I could just invoke that. I could even test it under multiple contexts. I don’t actually have to let the asynchronous thing go and be asynchronous in my test. So, I call it [inaudible] so I could re-sync what was going on asynchronously because it just gives me way more control on the test. Now that would be appropriate if I was trying to do integration tests and prove that everything works when it’s all plugged together. But for isolation testing, I think that strategy makes a lot of sense. And so it’s never been a problem for me. But if you were trying to write asynchronous tests in basic test code in Jasmine, I’m sure it’s probably pretty painful. AJ:  Yeah, one of the other things Jamison is I’ve seen Derick Bailey actually wrote kind of a shim on top of Jasmine’s polling that gives you the mocha style syntax where you can get like a done argument. JAMISON:  Yeah, sweet. JUSTIN:  Derick and I talked a little bit about that, I think he was doing some consulting in Washington. And he preferred that for that aspect. So, it’s cool to hear that he followed through and added something on. AJ:  Yeah, I mean it’s basically just a layer of abstraction over the top of what Jasmine’s already doing but it exists. JAMISON:  So Justin, do you prefer Jasmine Spies over Sinon? JUSTIN:  Yes, Jasmine Spies get me almost everything that I want out of Test Doubles. The couple of things that it didn’t give me, I added on in my own little thing before I knew Sinon existed. And I hadn’t met Chris, the author of -- is it pronounced Sinon? JAMISON:  I don’t know, you tell me. JUSTIN:  So I’ll call it Sinon. So [inaudible] I hadn’t met him, I hadn’t had a chance to meet him other than a few Tweet exchanges back and forth, and I really can’t speak for it. My only impression of Sinon.js is that it’s kind of a kitchen sink of Test Doubles. So it’s got locks, it’s got spies, it’s got pretty much every feature under the sun that you might be familiar with, from whatever other mocking framework you’ve used before. Personally, I don’t like it because I think that Test Doubles are so confused by people. They don’t understand why they exist other than for their own convenience. I think that it’s important for Test Double libraries to be relatively opinionated and narrow and consistent. So for example, my favorite Test Double library of all time is Mockito for Java. And Mockito’s Read Me is extremely opinionated. It will tell you in order, “Here’s the 30 things you can do for it.” And by the time you get to number nine, it’s warning you. It’s like, “Get the heck out. If you’re doing this really frequently, you’re in trouble and here’s why.” I think that’s the approach that I like to see from a Test Double framework. And that’s why Jasmine spies are very simple and bare bones. You know, they knock out of orbit a function that you want to replace and they listen quietly for every invocation against those functions and then you can go and make assertions against them later. Or you can set up the behavior that you want to happen at the top. The one thing that they didn’t do that I thought was a huge mess is that they don’t have any way to do conditional stubbing. So let’s say, I’ve got a function called ‘Foo’ and I pass it an ID and it returns you some object that finds it by the ID. If I want it to return ‘Foo’ when I pass at one, and I want ‘find’ to return bar when I pass at two, there’s no additional coding in out of the box Jasmine which is to me a huge oversight. So, I found something called Jasmine Stealth and it adds a whole bunch of extra kind of add-ons like argument captors and argument latches to Jasmine spies. But beyond that, that’s been plenty for my purposes. JAMISON:  So, what about the ability to take an actual object and lock a whole object rather than just a single function? Because Jasmine spies don’t do that well. JUSTIN:  Right. So there’s two things. One, Jasmine provides a little helper utility called Jamine.createSpyObj and you pass the name and an array of functions that you’d like that object to have. Which is helpful for dependencies that you have that don’t require the view operator be used against them. So like if the code under test is going to be instantiating the thing, call against that fake object isn’t going to be terribly helpful. And so, when I started using backbone, the prototype  will give a new keyword all over the place for each of your backbone. I actually [inaudible] myself  a little helper called Spy On Constructor and what that does is it gives you the same bag of spies when you first call them. But it knocks the entire constructor out of orbit. So if somebody were to say, new whatever backbone.model, it will return a new object of just those spies. So, that’s actually what I use when I need to knock an entire class out. JOE:  With that, do you have to specify what methods? Like for example, on model, do you have to specify all the methods on model that you actually want to spy on? JUSTIN:  [Inaudible] better or worse. And I personally, I don’t mind it because I like to write really minimal tests and I like my tests to specify what exactly I’m depending on about this thing. So that, if I ever pull my test out and pull my single unit out, I can see very clearly what are the two things that I need from this dependency, like if I were to ever have to replace that dependency later or rewrite it. But yeah, it’s not going to automatically look at or create one of these things, count all of its functions and then hand it back to you. And maybe that’s something Sinon does. I don’t know. I’m not familiar. JOE:  Yeah, Sinon does that. But the problem is, you actually have to construct the object first. So if there’s any by-products from the construction of the object, then you’re sunk. JUSTIN:   Yeah. And when I was writing the Spy On Constructor method, I went through the same thought exercise and realized I certainly didn’t want to be constructing objects on people’s behalf when they were only asking for a fake one. JOE:  So Jasmine Stealth, is that published on GitHub? JUSTIN:  Yes. So, we’ve covered two of my little add-ons. I maintain three Jasmine extensions right off my GitHub. So, my last name is Searls which is spelled like the word pearls but with an S instead of a P. Github.com/searls/jasmine-stealth and Github.com/searls/jasmine-fixture. And those are the two that we chatted about so far. CHUCK:  So, what else is Jasmine missing then? [Laughter] JUSTIN:  Well, the third thing that I added is called Jasmine Given. CHUCK:  Oh, okay. I know where you’re going. Go ahead. JUSTIN:  If anyone happens to be, and sounds like Chuck might be, familiar with RSpec given, Jim Weirich who is just one of my favorite people and also a brilliant Ruby developer and just developer generally, he recorded a neat little library that’s like 18 lines long for RSpec, given does, it replaces keywords that people tend to use in RSpec like ‘let’ which is a way to create objects that we need, ‘before each’ which is to do actions that we need in order for our DOM string tests to run. Action that we take normally takes place in a ‘before each’, the thing that’s under test. And then, ‘it’ just like the assertion layer of what we’re testing. Well, it was clever because he just did an English language mapping to use in the simplest way possible which is ‘given’, ‘when’, and ‘then’. So you can say, ‘given’ I have this thing, and then you can create ‘when’ I take this action, ‘then’ I expect this result. And it creates nice beautiful little condensed one-line actions instead of to use multi-line blocks like you might see ‘it’s that might look like traditional J Unit, X Unit methods where they’re doing a lot of thing in each ‘it’. Our preferred style was let us have one action per given or when or then. And it ends up being really easy to re-factor if you follow through on that and dry stuff up and pull stuff up, down and move stuff around. And so in parallel to that, I realized I really, really like spec style. And so, I ported it to Jasmine with a tool called Jasmine Given which just provides the same DSL for Jasmine. I don’t use [inaudible] anymore in Jasmine. I only use the given, when, then syntax because I just find that it’s a lot denser and cleaner and you see the re-factor and maintain my specs afterwards. JAMISON:  So, let me see if I understand this. ‘Given’ replaces the ‘describe’, ‘when’ replaces the ‘before each’, and ‘then’ replaces the ‘it’. Is that right? JUSTIN:  Actually, I still use describe. The describe sets up the example group. ‘Given’ replaces ‘before each’, ‘when’ also replaces ‘before each’ and ‘then’ replaces ‘it’. So, [inaudible] tool for each ‘it’ anymore. CHUCK:  So basically, what it is, is that you do all the set up, those are the ‘given’s, you take the action, those are the ‘when’s, and since you’re doing them all in ‘before each’s, the action occurs and that action occurs ‘before each’ of the ‘then’s, and the ‘then’s are ‘it’. So, ‘it’ should have changed this in the DOM or ‘it’ should have created a new object or whatever. A lot of this was inspired by cucumber. And cucumber is another testing framework in Rub that had the keywords ‘given’, ‘when’, and ‘then’. And with ‘then’, you actually defined blocks or essentially functions if you were to do the equivalent in JavaScript and you would parse values out of the -- so, if you said, “Given I have a user with username George and Email George@Example.com” then it would pull that out of the definition. It would do a whole bunch of regex stuff. And a lot of folks didn’t really care for that. But they did like the readability of the ‘given’, ‘when’, ‘then’. And so, instead of writing your own custom function for it, basically what you’re doing is you’re saying, “Given this step,” and that step is whatever it is that you’re doing in your set up. It’s kind of a neat thing. I’ve seen some RSpec given tests and I have to say that I tend not to use it and it’s mainly because I haven’t found a good style for writing those tests that really give me a large win in the readability area. I tend to prefer the ‘describe’ and ‘it’, the ‘before each’ and ‘let’ and do that kind of work. It just seems more straightforward to me. Though sometimes, if I have somebody either looking at my tests or if it’s something that really does kind of lend itself over to the procedural nature of some of these workflows, then the ‘given’, ‘when’, ‘then’ really does pay off. JUSTIN:  Yeah, just like CoffeeScript. I didn’t like the given style at first either until I really gave it a serious try. And once I did, I was sold. A couple of things that Jasmine Given does too, just to make things denser and more readable, is maybe like 60% of the assertions that I write are simply, “Thing on the left side equals thing on the right side.” So, if a then returns exactly false, that will trigger a test failure and print out in the test failure which is the compiled source code that failed. And then, it’s just like a slightly slimmer test instead of having to say expect thing on the left to equal thing on the right, instead of using the assertion API just to make sure that two things are the same thing. AJ:  So, we’ve talked a lot about the syntax and stuff like that. How do you run Jasmine? I know that there’s just a browser run and you can open up a web page and run your tests and stuff. But how do you do it in practice? JUSTIN:  That’s a very good question because it’s changed dramatically over time. AJ:  I was going to say, one of the strongest points about Jasmine seems like it’s the most supported by lots of different things. It has all these plug-ins. It has lots of plug-ins as well for different runners and stuff. So, it’d be cool to hear about those. JUSTIN:  It’s a double-edged sword. It’s really nice that there’s community support that’s provided convenient like automated runners for different back engine environments because typically, like we said at the outset, JavaScript isn’t the first language of very many developers. Typically, people are saying, “I’m a Java developer, on Java back-ends and I need to text my JavaScript. Help me do it easily.” Well, it usually means that they need a build tool that’s going to generate for them the Jasmine HTML runner concatenate or combine, or pull, or find all of their JavaScripts and all of their specs and put it into that runner and then run the tests. So, each of the backend environments tends to have just some dude in the community who writes a runner or a build plug-in that makes that possible. So it’s a good step up to that. It’s bad because it’s like a graveyard. And I’ve contributed to it, of plug-ins that are out of date or build plug-ins that don’t get a lot of love anymore and because they haven’t been blessed by Pivotal aren’t really well-supported or might behave differently with what people expect. So for me, I know that there are runners for Node, there’s Jasmine Node, there’s Jessie, there’s Jezebel for Java. I maintain the Jasmine Maven plug-in. CHUCK:  So, do you just run it as part of your regular test suite then? JUSTIN:  It would be part of the test life cycle phase in Maven terms. And yeah, as you were doing your build, it would heedlessly, using HTML element, execute all of your tests. CHUCK:  Okay. JUSTIN:   Let’s see, for Ruby, there’s a whole bunch of different options. Pivotal maintains the canonical Jasmine Gem, the official one. But unfortunately recently, it didn’t support the asset pipeline appropriately. So Rails 3.1, which came out over a year ago, supports CoffeeScript and asset manifests everything that sprockets gives you. And because the official gems didn’t do that, their gems crop-up, like one called JasmineRice and I maintain one called Jasmine-Rails. There’s another headless one called Jasmine-Headless-Webkit. So there’s a whole bunch in the Ruby community. And now, what we’re sort of landing on is the best created ones. There’s actually one on Node but for the purpose of testing browser software, browser JavaScript, and my two favorite there are Testacular which I believe is funded by Google. It’s like an Angular.js team member doing it, if I recall correctly. And Testem, I really, really like Testem. It’s a very, very cool tool. It’s node-based. But at the end of the day, we’re just talking about you know, making it able to find your JavaScript. So there’s no reason you wouldn’t be able to use it if your JavaScript is organized inside of another project inside of a Rails project. Testem is fantastic for having a really, really great interactive console that’s multi-tabbed and can easily capture additional browsers. So you could have your tests running on every single file change with multiple different versions of multiple browsers. I like Testem a lot. To somebody who’s almost just coming in, I always point them to the simplest possible thing because there’s almost too many different ways to run JavaScript, run Java specs. And I guess that’s part of why I feel a little bit uncomfortable is I really wish that the story were a lot clearer for, “If you’re in this environment, I recommend this one.” And right now, I don’t have a really good answer. JAMISON:  What’s the simplest possible thing that you’d point them to? Or are you saying that there isn’t one? JUSTIN:  Well, the very simplest thing, just to get started, just download the Jasmine distribution and any HTML page that you manually maintain, every time you add a script, you add a script to that runner. And (a) it’s good because it fosters an understanding of what’s really going on and how the tests execute; but (b) it doesn’t add the extra complexity of how to a hook this into the CI necessarily right on day one before you’ve even gotten a chance to write any tests. So that’s the simplest thing I could imagine. MERRICK:   I think that’s a good case too because it’s fairly simple to hook that up into the CI even with just PhantomJS and maybe using Grunt Jasmine, like a grunt-jasmine task that you’re going to be running for your CI, it’s not a far leap. It’s not like you’re going in the wrong direction by starting with an HTML file. JUSTIN:   And you know, I have written selenium tests in environments that literally load a plain vanilla HTML file and make sure that they see green, right? And that’s one way to hook into CI that’s like a very simple solution and that might be good enough. CHUCK:  Alright. Well, we’re getting close to the end of our time. Are there any other aspects of Jasmine that we haven’t talked about that we need to cover? JUSTIN:  The only other one I want to mention is if you’re listening to the podcast and you just want to get started in a very, very simple way, I maintain a website called TryJasmine.com and you can go there in a browser and type specs and type source and hit run and it comes preloaded with all of those little Jasmine helpers that I talked about today, as well as backbone and underscore and jQuery. And a lot of folks, when they’re just sort of spiking out ideas, will go try TryJasmine.com and just play inside of the form editor, kind of like a JS Fiddle. CHUCK:  Awesome. Alright. Well, let’s get into the picks then. Jamison, what are your picks? JAMISON:  I just have one this week, I found it a couple days ago. It’s this slide deck by a guy from Parse, they make this mobile like Cloud API platform. And it’s on Running MongoDB on AWS and it’s very helpful. There are slides but he has detailed presenter notes in them so you can pretty much understand what he’s talking about just from reading through them. They’re short and they’re sweet and there’s lots of good stuff that I’ve learned from reading them that I didn’t know before. So if you are interested in MongoDB, and especially in running it just on EC2 in Amazon, check this out. CHUCK:  Alright. Joe, what are your picks? JOE:  I have two picks. The first one is the book, The Clean Coder by Robert Martin, affectionately known as Uncle Bob. If you are a developer and you have not read that book, then you are missing out on something on your career. It is definitely one of those things that every developer should read, absolutely. I would probably pick that book over any other book for a must read for all developers. And my second pick, which I know that Merrick is going to pick this same thing, is Squire.js and I’ll let Merrick explain it when he does his picks. CHUCK:  Great. Merrick, why don’t you go ahead then? MERRICK:  Yeah, sure. So, one of my picks is obviously Squire.js as well. It’s a project that Joe and I released officially last night. We’ve been using it here at Domo for a little while and it essentially lets you mock and stub AMD modules. So yeah, if you want to look into that, it’s just on my Github.com/IAmMerrick/Squire.JS. My other picks are Macklemore. He’s going to be in town here in Utah this Saturday. So, I’m pretty stoked for his concert. And the Rdio, the new Rdio app. Their new IOS app is just amazing. CHUCK:   Awesome. AJ, what are your picks? AJ:   Okay. One, I’m going to pick Square Up. I like Square. I’ve used it a few times to receive payments for DJ’ing gigs and I just used it this morning to rent some equipment. So, I’m pretty happy. Also, I want to pick, I think it’s AllRecipes.com and MyRecipes.com because I found some pretty good recipes for Indian food and for pizza on there. And they have a really nice way of printing it out so you can print it out as four by six cards without the advertisements, without the pictures on both of those sites actually. And makes it really easy to look over your ingredients list and put stuff together. And I’m going to pick the great state of Utah, just because… [Laughter] CHUCK:   Cool. Alright. So, I’m going to do a few picks. My first pick is I’m sure I’ve picked this before but it’s something that I’ve been dealing with today and that is Jenkins CI. I’ve been working with my boss to get it set up - my boss being my client. Anyway, he’s like the director of the project that I’m working on which sort of makes him my boss. Anyway, it’s a really cool CI machine. I really like it and it has plug-ins for most of what I ever need to use it for. Since it works so well, we’ve been playing with that. The other thing that I want to pick is the Podcast app. I haven’t really been a big fan of pod catchers on my phone. But Apple really has come out with just a stupendous app. It doesn’t do everything that I want, but it does most of what I want. And so, I just synched it with my podcast collection on iTunes and it brought everything over. And then, what I’ve been doing is slowly but surely, as I listen to shows, I’ve been telling my phone to subscribe to them. And when I do that, it works out pretty well to just hold the stuff down as long as there’s room on the hard drive on my phone. So anyway, those are my picks. Justin, what are your picks? JUSTIN:  Well, I was going to pick Time Warner Cable. But they kind of let me down on my ability to speak clearly over Skype today so they’re out. No, I’m just kidding. I would never pick an ISP. So, I’ve got three, if that’s okay. CHUCK:  Yep. JUSTIN:   And I’ll start with the one where I’m tooting my own horn because this is something we didn’t get a chance to mention during the conversation. That’s the tool that we’ve been working on our Test Double and we’re using on our client projects right now called Lineman. In railroad terminology, a lineman tended to be a person who was promoted from the position of grunt. And so, it’s a tool that kind of sits a layer above grunt in your workflow, if you do node for like task management. The idea behind Lineman is I was really sick of giving presentations at conferences about how to improve your JavaScript. And then, when people asked me for practical advice, I’d have to tell them, “Well, first install Ruby and then install all of these other tools to make your life easier.” So Lineman is a very, very simple little install that is a web app productivity manager. It concatenates all your files. It watches all of your file changes. It runs all of your tests, It uses Testem for its test runner. And then, come build time, you can write in the CI heedlessly. Come build time, it will concatenate all of that for you and produce you a nice little static executable, not executable, static HTML JavaScript CSS apps that you can just deploy on to the web for any single page client side app work that you’re doing.  So, we love Lineman a lot. And if you search my name and Lineman, hopefully you’ll find it. I guess we share URL here though, don’t we? CHUCK:  Yep, just put it into the chat. JUSTIN:  Number two real quickly, Star Talk podcasts. I really like Neil Degrasse Tyson’s podcast, Star Talk Radio. It’s really quirky and strange and sort of this dual interview format where he normally does an interview with a famous person. But that interview only took 10 minutes, so he fills like an hour of radio time by having somebody in the booth with him dealing with that interview or listening to it piecemeal and kind of commentating on the interview. It‘s just a little bit [inaudible]. But that’s a fun podcast to listen to because Neil Degrasse Tyson is just fascinating. And then, my last pick is a PC game called To the Moon. And if you like old school RPGs or if you like video games for the story element, this is a pure story RPG. There is no action, you cannot die. It is only about four hours long and it looks like a Super Nintendo game with a tremendous soundtrack. But it’s a really, really heart-warming feels kind of story that’s just a terrific little game. And it’s made by a little Indi group called Freebird Games. CHUCK:  Alright, cool. Well, we’ll get links to those in the Skype chat and we’ll put them in the show notes. And thanks for coming on the show. It was really good. JUSTIN:   Thank you, guys. I had a lot of fun. CHUCK:  Alright. Well, we’ll wrap this up. We will be around next week and thank you all for listening.

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.