 This is specifically intended for Rubyists to use and integrate into your Ruby and or Rails apps. So I'm Chris Powers, I'm a software consultant for Optivo. We are currently hiring, so if you're looking for a gig in Chicago or Denver, let me know. But that aside, so I think the first question that we kind of have to tackle before we get into, you know, why do we want to try out the Jasmine library itself? First of all, why do we want to test JavaScript in the first place? And I think it probably goes a little deeper to ask the question, well, why are we testing the code? Because it's mine, it doesn't work. So the first thing is that JavaScript is important. And frankly, it's getting more important every single day. I've met several guys, I had conversations over the last couple of days here. We don't sound real happy about this. And unfortunately it's not going away. We can try to abstract it away using something like CoffeeScript. We tried to do something really clever called RJS. That went well. But it's important, and the bottom line is that the clients that we work for, the businesses, are going to continue to look for deeper, richer, more interactive experiences through the web. JavaScript is everywhere. Not only is it the language that we're going to be using to build out the client sides of our web apps, but now we've got JavaScript on the server if we're using something like Node or Ringo. And now we're even getting JavaScript in our databases. If you've been using Mongo, if you've been using Couch, you're very familiar with the fact that in the internals it's using JavaScript. And you're writing a lot of your queries or your views in JavaScript. Now one of the biggest problems is that while JavaScript is hard, and that's true. I think that JavaScript has become one of the most misunderstood languages that is still being used all the time. And I think because of that, a lot of times we try to take JavaScript and turn it into something that it's not. Whether it's a library like Prototype making a very ruby-ish or something along those lines. Trying to make it object-oriented when it's not strictly an object-oriented language, things like that. But this is probably the biggest complaint that I hear from people when we start talking about doing testing for JavaScript. And they say, well, it seems like a lot of work just for some lousy regression tests. And if that's the criteria, I would actually agree. Because when it comes down to whatever JavaScript you have in your app, it may not be too hard to just start clicking through and do your testing that way. Do some regression testing just by clicking through. Maybe you have a QA team, maybe you're lucky enough to have some people who can do this as their day job. And having automated tests may not seem like that big of a deal. But the thing is that that's not what TDD is about. Doing test for development is not just about building out a regression test suite. It's about guiding your development. So the first thing that it does is it drives good design in your code. Specifically, in your JavaScript code, you're going to find that it's going to become a little more object-oriented urr. Because it's not an object-oriented thing. There's objects and I think it gets oriented urr. What I mean by that is simply the fact that you're going to end up with code that is more modular and is more namespaced. Which is more important in JavaScript than a lot of other languages. Because our JavaScript deals with global variables and things. Modules, namespaces are very important. You're going to end up with code that is much more flexible. It's going to be easier to update, easier to modify and extend over time. And you're going to end up with code that is reusable. Both within the same project and then across projects. And those are all benefits of using modular design. Now why is it that writing tests and specifically test driving your development, why? How does that get you here? Well, the bottom line is that you can't test something without a name. You can't test something that you can't make a reference to in your tests. You know, when you're doing your jQuery code and you've got nested function inside of a nested function, they're all anonymous and it's all slick looking jQuery. Well, the problem is you can't test that. And that's one of the big problems that people have is they're like, well, I can't test this so I'm not going to. Test driving your JavaScript demands that you take a new fresh look at how you're writing your JavaScript. Focus and process. These are some of the benefits of using test driven development as well. The code that you write is going to be driven by the business requirements. It's not just going to be code that you're writing on a whim or you know, there's going to be a very strict set of business requirements that you get from your users or from your client. And you're going to iteratively work through those writing tests, writing implementation and following that red green refactor pattern. You're not familiar with that. The pattern is basically that red means that you've written a test that is failing. That's always where you start. You have taken a business expectation and you have written code that expresses that requirement and that expectation. And you see it fail because it's not done yet. It's not implemented. You then go in and you write as little code as possible to get that test to change. You pass and that's green. And now refactoring is just that continual set of iterative changes that you're making to the internals of your code. Making improvements, simplifying your code that doesn't actually affect the exterior behavior or the API of the code. And when we get into that red green refactor, red green refactor, iterative development cycle, we start to get focused and we see process. You also know when you're done. You know a lot of times when you're working on a feature and there's really kind of vague requirements, you don't really know when you're done. There ends up being a lot of round trips between you and the client or you and your business partners. Nobody's exactly sure what it's done. But using TDD, we do know because once you're done with those business requirements, once you've written that last test, it's time to move on to something else. You also get some what I call free documentation. And for those of you who are using R-spec, and I hope that most of you or all of you are, you're already familiar with some of the benefits of this free documentation. So our specs that we write, assuming that they're good specs, they're going to be expressing the object behavior of the objects that we're writing. And when we run our test suite, we're going to have legible output that is going to be very descriptive and is going to kind of read like documentation and tell us what these objects and what these systems do. And these can be very helpful tools for when you have new developers who need to get up to speed on a project. They're able to go straight to the tests, to your specs. They're able to see how you are using these objects and what requirements you are putting on these objects. And it becomes a very expressive way of getting up to speed. Oh, yeah. Plus you get a regression test suite. And I guess the way that I've been looking at it recently is that this is almost just a side effect of all of the other benefits that we get when we go about our Ruby code, our JavaScript code, or whatever other languages we're using, taking a test-driven development approach to that. So why is it that we actually want to use Jasmine? Because there are a lot of JavaScript frameworks out there. And they're good ones, too. You know, you've got funk units, crew units. We've got Blue Ridge, and there's a series of them. So why isn't it about Jasmine specifically that I decided would be the thing to share today? Well, one of the biggest things is that if you are already familiar with RSpec, you're already familiar with Jasmine because they flat out ripped off RSpec. And it's a great thing that they did because it's to all of our benefit. They both have a very similar syntax. They both take that BDD approach, that behavior-driven development approach, to describing behavior of objects. And they also end up with very similar output, just like I mentioned before. Doubles is this kind of documentation. So the RSpec integration is very tight. First of all, if you're already using RSpec and you have a spec directory, it's going to drop a JavaScript directory into your spec directory. And that's where all your Jasmine specs are going to go. And if you're hopefully using something like Hudson or cruise control, using some continuous integration on your team to make sure that you always have a good build, Jasmine is out of the box ready to plug into that as well, along with your Cucumber tests, your RSpec tests, whatever else you're using. One other cool feature that has been added recently to RSpec is that when we're working with Jasmine and really any JavaScript tests, one of the things that you oftentimes have to do is you need to load in some fixture data. Now, not like RSpec where you're loading and stuff from the database, but rather some fixture markup that you pull into your code, you then run behavior on this markup and make sure that your expectations are being met. And one of the cool things that RSpec supports now is that if you're using RSpec tests, controller tests that have the view integration turned on so that they are actually running the controller action and generating the view, it will actually take the output from the view and it will write it to disk. It'll save it tucked away in your TMP file. And when you run your Jasmine specs later, Jasmine will look in your temp directory, find these saved markup files, and actually use them. And so the great thing about that is that if you make a change to your view, and you forgot to make a similar change to your JavaScript files, you're going to see a test failure because it's going to load in that view. It's going to run the JavaScript and it's going to fail because of this change and you're going to find out immediately that you need to update your JavaScript. Getting up and running with Jasmine is surprisingly easy to do. It's about two steps. You just install the Jasmine gem, and then there's a Rails generator that you can run, and that will create a file like this. It's a Jasmine YAML configuration file. Basically, it just allows you to specify, these are all of the JavaScript files that I want, but my source files that I want to include so that I can run tests against them. Here's even style sheets that I want to include in case that affects the way that the JavaScript works. And then here's where I store all of my spec JavaScript files, and these are the orders I want everything to be pulled in. Now, there's two ways you can actually run your Jasmine specs. One of them, and I think it's the faster and the easier way, is that you can actually run this in the browser, which is pretty sweet. You just run rate Jasmine, and that starts up a spec server on port 8888. And when you go to that browser, this is what you get. And you can see that of all these specs that I had, we had one failure, and the rest of them were passing. And when I make changes, all I have to do is refresh the browser, and I can see the updated tests. And these run very, very fast. I don't know, 10th of a second to run a couple hundred of these things. I mean, when you take the database out, it's pretty blazing. Now, using the browser has some definite problems with it, and one of the big ones is that, well, I want to run it from the command line, right? That's probably what a lot of you are thinking, and I want to integrate this into my CI system. I can't integrate a browser into my CI system. And so Jasmine also gives you rate Jasmine CI, which is going to run them on the command line in a way that you can integrate into your CI system, and it will run the specs from the command line. In the background, it's going to be using Selenium in order to run these things. And so it does take longer to do Jasmine CI than just running them in the browser, but this is going to be a good solution for those times when you need that flexibility. Chris, there's a lot of work going on trying to get other support for headless JavaScript testing. There's like eight different things that are being worked out right now for how to do headless testing of that so that you can get Selenium out of the picture. Yes. Yeah, there's some really cool development. I think I just saw a library called Phantom, I think, here. So there is a lot of active development in this space, which is really exciting to see where that's heading. So now at this point, I want to use RSpec as a point of comparison to show you what does Jasmine code actually look like. So let's get cooking. So first of all, all of our specs and our expectations are going to be grouped into these described blocks. And so on the top, I'm going to be showing RSpec code, and on the bottom, I'm going to be showing the Jasmine code that is essentially equivalent. And at one quick glance, you can see that, yes, these are very similar. So Jasmine gives you a described function where you pass in a string. You can't pass in an object, but you can pass it a string. To describe, I want to describe this cook object and describe the process of baking a pie. And now inside of these described blocks, I'm going to have the actual examples or the expectations in id blocks where it functions to JavaScript. And so what I'm able to do here is I can say it should be tasting, passing in an arbitrary string that describes this expectation. And then inside of this anonymous passing function, I'm able to run code and then set an expectation. So now RSpec, the way that we set our expectations is that we're given the should method on all of our objects. And we can then use matchers or we can use operators in order to actually set that pie.tst.should be true, setting that expectation. So in Jasmine, we have one function, expect, that actually sets up an expectation, as opposed to RSpec, which has a few, should, should not, should receive, things like that. Jasmine always uses expect. And you pass expect some kind of a value. In this case, my value is going to be the tasty attribute of pie. And then I'm going to use a matcher function in order to actually put that expectation on it. Now what exactly is this truthy? Why didn't we just say, expi.tst to be true or to be false? Well, and the reason has to do with how JavaScript as a language actually evaluates certain statements. There's a few quirks that you need to be aware of, and I think this is why they specifically chose to use the words to be truthy and to be falsey. So up top, we have the actual matcher definition of to be truthy. And you'll see what's happening is it's taking, so this side actually is what's passed in, and we're just evaluating that and inverting it twice to get an evaluated value, which is all well and good except for these and all these down here. So expect the string hello to be truthy, you know, that's true, because that string is going to evaluate the true. But in JavaScript, a blank string actually evaluates to false, which is totally different from how it works in Ruby and probably most other languages. Similarly, you know, one, two, three, that's going to evaluate to true, but the number zero actually evaluates to false. And so this is just a reminder of some of those quirks that it's more about evaluating truthiness than strictly whether it evaluates to true or not. So now if you want to do negative expectations using our spec, if we need to say that, you know, my should not be burned, then rather than using should, we simply use the should not method and then use the matcher. In Jasmine, again, we're just sticking with the expect function, but now we're able to chain on the not method in there in order to simply, you know, reverse the value returned by this matcher to be burned. So we've seen a couple of these Jasmine matchers. To be truthy, to be faulty, those are built-in. I'd say there's about a dozen or so built-in matchers for the most common cases, but if you want to be more expressive in your test, you want to do something like, you know, expect it not to be burned, how do we do that? So in both our spec and Jasmine, you're able to create custom matchers. And so in our spec, we get this spec matchers define method. We pass in a symbol for the method name and then we get this match block where we have the actual object and that actual object represents what is actually being tested. And so we can check that, check the color, see if it's black, and return a value based on that. So now in Jasmine, a little different syntax, but it's the same idea. We're going to use the this.addMatchers function and we can actually pass in an object with as many of these matchers as we want. Each key in this object is going to be the name of the matcher and then each value is going to be a function. And inside of that function, you get the this.actual object that we can then run different expectations on. The only thing we have to remember is that we have to explicitly return because it's not going to implicitly return the way it does in Ruby. Now you see in this Jasmine example, we're using before each. So in our spec, we get the before each and the after each blocks. This is nested inside of a described block and basically this allows us to do set up and tear down code before and after every single it block that's inside of that description. And so we have something very similar in Jasmine. We have the before each and the after each methods. The one gotcha that we need to take a look at here is you'll notice that in the R spec, I was able to just create the pie variable inside of that before each and that pie instance variable would be available in the after each in all subscript describes it blocks. Now the way the JavaScript scoping works, we don't get quite as much of that metaprogramming magic to make that happen. And so instead what we need to do is we need to actually declare the variable outside of the scope of the before each and then we can set the value inside before each because if we had actually declared the variable inside of the before each block, it would be stuck in there. We wouldn't see that outside of the scope. Now before all and after all, that's something that is supported in R spec and this is just run once before or after a set of expectations and in Jasmine, we actually don't need a special construct for that. We can literally just run code before a described block and run code after a described block and we get basically the same functionality out. So one of the things that really, I think, makes Jasmine stand out above some of the other libraries is how we are able to stub our values and we're able to do message expectations very similarly to how R spec does it. So in this scenario, we want to make sure that if a pie is 160 degrees, that it considers itself done baking. And so we accomplish this in R spec by creating pie, we're going to stub out the temperature method and then we're going to chain on and return so that we can return 160 degrees and then we can run the done baking method and assert that it should be true because that's our cooking temperature. Now this is where Jasmine and R spec start to branch off one another, I guess. And so Jasmine is able to do this exact same behavior with a little bit of a different style. What it uses are called spy objects and so a spy object is basically an object that when you use spy on, I'm going to spy on an object and then you pass in the name of the method or the attribute that you want to stub out. And what's going to happen is that Jasmine is actually going to take the method that you have that temperature method and it's going to pull it out and it's going to replace it with a spy object and that spy object can then do your bidding. And so when that spy object gets culled, it's not then able to do something like and return 160 and I get that stubbed value. So while it's a little different syntax and it's a little different under the hood, these are equivalently the same, the R spec and the Jasmine. So now in R spec, sometimes stubbing is not enough. We want to make sure that a certain method is culled. And so to do that, we would use the should receive. Say that, okay, so this cook should be going to make dinner, cook should receive the make a pie message. And we set that basically before it happens. We then do cook, make dinner and then basically we check to see if that expectation is met. Now again, we're going to use a spy in Jasmine and the syntax is the same for spying on this, the same as stubbing. We're replacing that bake pie method with our spy object. Now here's, and this makes a little more sense in Jasmine frankly, the fact that we actually run the method that we're interested in which is cook, make, dinner. And then we can put the expectation after as opposed to having to say what should happen in the future the way that we do with R spec. Jasmine allows us to actually look back and see what happened in code receiving which I think can be a little more legible. And so here we can actually place an expectation on cook.bake pie which remember cook.bake pie is now returning a spy object not the original method. And at spy object you can now do expectations on. So the spy knows whether or not it has been called so we're able to use the to have been called matcher in order to make that expectation. So taking that one step further we don't want to just make a pie we want to make a tasty pie. And so in R spec I'm going to say that it should receive the bake pie message and it should receive it with the argument tasty. And I'm able to just chain on the with method there to specify that expectation. And we have something very similar in Jasmine. All we need to change is that we can change the to have been called matcher. We can then use the to have been called with and pass in any number of arguments that we're expecting. So the real Jasmine only feature that R spec as far as I understand doesn't support is actually being able to haul through to the original method. So let's say that we want to make sure that something has been called and it has been called with a certain argument but we also still want it to run. Maybe it makes the test easier to use or maybe there's a significant original value that we still need to get out of that method. What we're able to do is when we spy on this cook bake pie method we can then use the and call through method and that's actually going to retain a reference to the original function. The spy is going to be hit with the message. The spy is then going to delegate it on to the original function and return whatever the actual response is. So I think that's actually, that is a really neat Jasmine only feature functionality that would be neat to see in R spec. I'm just not sure if it's possible to base on how the languages differ. You can do it with double R. Double R allows that kind of test doubling. Okay, using that as opposed to built in R spec. Yeah. Okay, thank you. You might want to repeat. Yes, so apparently the double R is a mocking library, right? Yeah, so double R actually does support the functionality I was just talking about which you can use inside of R spec rather than the built in R spec mock library. So the next thing that we want to do is we want to not only check to see that we received a message but that we received a number of times. And so R spec gives you the nice sugary syntax where we can say that the cook should receive the check the pie message twice because checking at once is not enough. We can do something similarly in Jasmine. At this time, inside of our expect function we're using cooked out check the pie which returns our spy. But now the spy actually has some attributes on it and one of those attributes is the call count. So you're actually able to ask the spy well how many times were you called? And we can then assert that it's going to equal two in order to get the same functionality. So now expectations on errors when you throw errors. So let's say that we have a cranky cook and when we tell him to make pie to raise the error, make your own damn pie. So if we want to test that, in our spec we actually kind of have to jump through a little bit of hoop here, right? Because we can't just raise an error inside of our it block. It's going to blow up our whole test week. And so what we're able to do is we're able to use a lambda to create a scope where we can run the volatile code. And we can then actually put an expectation on that lambda. And we can say that that lambda should raise the error, make your own damn pie. And with Jasmine, I think it's actually it's cleaner the way that we can do it here in JavaScript is that we can set this up. It's going to be a message make your own damn pie. And we can say that we expect this method the cook.bakePie to throw a given error message or given error object or whatever you're using in JavaScript to represent your error. And so what to throw does is it will actually execute the cook.bakePie method and then it will put the expectation on whether or not that through an error that matches the message or object that you passed in it. Finally, simulating errors. So getting a little more complex now let's say that we want to do some errors we want to read pie with pseudo. And so if our cook tells us to make our own damn pie we will then use the pseudo makePie. And so we're able to stub out makePie method and we're able to use the and raise Jane method in order to purposefully raise that when it's called. And in the error handling then that pseudo.bakePie method would get called. And this too we can do in Jasmine. When we spy on the bakePie method we're then able to chain and throw on to this and we pass in the string or the object that's representing our error. And then what we're able to do is we can just expect that the pseudo.bakePie method will be called. And so this again is going to be functionally equivalent to how our spec does it. And so I want to point you in the direction of some resources if this is something that sounds interesting I would say give it a shot jump in there and start playing around with it. So there's actually some really great documentation it's up on github it's pivotal.github.com and this is a full set of documentation and examples that shows you how to write your Jasmine tests. And again if you're familiar with our spec and you're using that already this is going to be a really smooth transition for you. You can check out my homepage chrisjapowers.com I have a lot of links and notes and things about Jasmine and other JavaScript TV topics so you can take a look at that. Also a project that I'm working on is not quite ready to go yet but it's going to be a set of resources for JavaScript specific you're going to be doing screencast tutorials etc. And so if you go to jobscriptmaster.com just give us your email and use the sign up code roa2011 and we'll make sure that we send some free stuff your way a free tutorial that goes more in depth than I did here tonight about how you can start using Jasmine. So if you have questions we've got some time now and you can obviously send me up on Twitter I'd be more than happy to talk shop. And also if you have any feedback let me know. I'd like to hear what you thought about the talk on thespeakerrate.com I'll tweet that one as well. Yes? Yes. Sure, yeah. So the the idea is that I'm technically speaking in the implementation code oh, thank you So to repeat the question he was just asking in this test we're making reference to the pseudo big pie method how would that actually be called that I'd be expecting it to be called and I guess the idea was that if I put in some error handling code to catch this error or make your own damn pie and then in that handling code rather than clean the program I'm actually then going to run the pseudo big pie in order to try to get you know Oh, you know what you are absolutely right. Sorry about that. I'm missing the last line should actually do something like I think I was using cook.make.dinner Oh, okay. Sorry, you're right. I was missing a line of code here. Imagine cook.make.dinner is at the bottom there and that would be the method that we're actually running in the test. Yeah, the maker pointed out anyone else have any questions about background? Yes. Have you seen evergreen at all for integrating jasmine with rails? The question was have I seen evergreen and unfortunately no, I'm not familiar with that. What is that? It's just another way to integrate jasmine with rails instead of depending on our spec. Does it give you a like a different kind of runner? It uses selenium by default but it uses capybara under the hood as well. Okay. Tell us about capybara also. Okay. So it sounds like evergreen is also another framework to fund your radars. Sounds like a cool project using capybara. Yes. Your JavaScript code includes references to things like buttons and links and we've got new trigger events on those objects in the context of your capybara testing. Yeah, so the question was assuming that your JavaScript code is going to have a lot of references to DOM elements, buttons, links things that you're going to be clicking and that you're going to be clicking on event handlers on. How does that work and how do we have access to these objects? So there's a few things. First of all if you're using jQuery a jQuery jasmine library that you can kind of mix into your current test code and it gives you a lot of helper methods that allow you to do stuff like this. And so a common usage pattern I would say there's probably two common usage patterns. The first one is that you would create elements in the DOM using jQuery like before each block for example. And so let's say that you have a described block where you're describing a form of functionality and you have some kind of an Ajax call or some kind of a click handler on the button. So what I would do is I would basically figure out which of the keynotes well I need a form with a certain ID I need a button in there with a certain ID and using some of the methods of jQuery I would actually create those those DOM elements and you can attach them to the document or you don't have to when possible I like to just keep my DOM elements you know they exist but they're not actually on the page test one faster you don't have conflicts of things bumping into each other the other thing that you can do that is the fixtures so if you have you know markup that is either generated from your RSpec code or it's just markup that you you know it's your fixture markup you can create an HTML file and then the jQuery the jQuery Jasmine library gives you helpers to very easily load that in put it in the DOM and now you can start simulating clicks and doing all that stuff so that you can fully test all of your interactive behavior Yes? Test AJAX calls using the spy function or is there some other approach that you use? I would say that usually I treat it the same way I treat like RSpec kind of hitting external resources or you know like I'll stuff out the basically use a spy to make sure that the call is being made and then in another test I'll be calling the callbacks the error callback or the success callback with simulated responses so that you're not actually hitting any external resources in the test game and I know that there's some I've seen some different helper libraries that I don't have much experience with but there is built in support for testing asynchronous coded in Jasmine and there is more extensions that I've seen on GitHub for people to allow them to better more easily spec out AJAX calls and other asynchronous behavior Yes? I was curious if that was important That I'm aware of No, it's pretty much all just kind of in the before blocks and like I said anytime that you create a variable that you're going to be using inside your tests inside more than one test those all kind of get declared at your highest scope usually have like a bar statement at the top of the page with all the variables you're going to be using just so that they're all declared at the top of the scope but yeah in terms of some of the semantics of using Subject and Lead I haven't seen an equivalent to that in the Jasmine Yes? I know it's a whole nother talk but endless JavaScript testing with CI and it does it uses some kind of a headless Firefox something or other in the background you know I actually I really do like using the Jasmine tests in the browser just because I find that it suits my workflow pretty well they tend to be very fast and I've had I just generally say I've had more longer than that in server and that always works well but I'm very excited to see some more mature implementations of doing the headless browser testing for sure alright well thank you very much