00:00:19.760
Okay, let's get started. I'm talking about testing JavaScript with Jasmine. My name is Tim Tyrrell, and I work at PeopleAdmin as a Rails developer in Austin, Texas. I'm originally from Chicago, but I'm living here now.
00:00:26.800
I will talk about PeopleAdmin a little bit later, but we have a talent management application for about 600 to 700 universities where we handle internal and external job management.
00:00:39.120
I want to get going by giving you the agenda to see if this is what you want to see. I appreciate you coming here, and I want to make good use of your time. I know you had a choice, and you chose this session, so I want to set your expectations correctly.
00:00:50.960
This is basically an intro to Jasmine, specifically on how to test JavaScript using the Jasmine Behavior-Driven Development (BDD) testing framework. If you have any experience with Jasmine, you might already know this stuff, so feel free to exit now if you wish to. However, perhaps you’ll pick something up.
00:01:07.920
The focus will be on how easy it is to use a JavaScript testing framework, which is something that is really cool. I also know that I'm standing between you and what I believe is chicken fried chicken today for lunch, complete with gravy and mashed potatoes, so I am pretty excited about that as well.
00:01:27.280
As you can see, I will talk about unit testing and what Jasmine is. I will show syntax comparisons with RSpec and various scenarios where Jasmine can come into play, including testing JavaScript, jQuery, Ruby without Rails, Rails itself, and using Evergreen, which is a really cool gem that packages it all up for you.
00:01:58.560
We will also cover how to run tests headlessly and how to integrate with CoffeeScript and some helper libraries. We will briefly cover a lot of topics; I have many slides and a lot of coding configuration setup, but we will move quickly, giving you a broad overview of everything you can do with this framework.
00:02:15.520
Now, you might be wondering why I'm talking about JavaScript at a Ruby conference. It seems a bit ironic since this is the third talk in a row about JavaScript. Well, a lot of us use Ruby, obviously, whether it’s with Rails or Sinatra, so we have views where we incorporate JavaScript. This is an area where many applications fall short; many do not have tested JavaScript, let alone unit-tested JavaScript.
00:02:45.519
While we often rely on integration frameworks to cover these aspects, they don't always suffice. I'll elaborate on that later, but it's a crucial part of your application that often gets overlooked, particularly if it’s embedded in the view. Not testing it properly is just crazy; I’ll show you how straightforward it can be to implement effective testing.
00:03:09.599
So, why should we unit test JavaScript? Well, it is code. We test our code because it can become very complex, especially with everything that involves client-side operations and server-side functionalities like APIs. There’s a lot of processing happening on the client side which can lead to challenging complexity. Anytime you have code—especially complex code—you need coverage to feel confident and to ensure it works well.
00:03:57.200
The mentality around JavaScript is changing as well, especially with the explosion of various JavaScript frameworks. JavaScript is no longer seen as a 'toy' language; it now has the respect it deserves, and thus we should test it just like any other part of our production code.
00:04:25.520
There are perceived barriers to testing JavaScript, with some thinking it's hard to get started. I am here to show you that this is simply not true. Getting going with Jasmine is incredibly easy, especially considering all the familiar methods you use with your backend code. JavaScript is becoming a more critical component of applications, and unit testing for it is something that we must begin considering and implementing.
00:04:54.000
During Glenn’s talk yesterday, he mentioned that external tests do not aid our internal design. This is an important point; the advent of tools like Cucumber and Capybara has improved our ability to execute integration tests through the full stack, which is great, but if you are not performing unit tests, you might be missing out on improving your design beforehand.
00:05:22.160
Additionally, I have another quote from Twitter: there is only one way to truly go fast: do the best job you can, because anything less is slower. People often claim that unit testing slows them down, but I argue that what really slows you down is your deployment blowing up. When you try to refactor some code and it breaks your application, that's when you truly feel the pain.
00:05:55.040
With good unit test coverage, you’ll have a better design and internal code structure, along with the confidence that your application won’t break down. I understand that there were discussions about not having to test everything; you can spike and protect areas you feel confident in. Still, production code needs testing around it to ensure consistent and reliable operation.
00:06:20.320
It’s worth mentioning that testing isn’t easy. I’m still improving my skills daily since I actively work on it. For those of you who are new to testing, it can be quite intimidating and complex. It took time for me to understand how to call methods and see what they return. Testing is challenging work that gets better with practice over the years, resulting in improved code quality.
00:06:51.200
As the obligatory meme suggests, it is not brain surgery or rocket science, but if you deploy something that blows up, you might find yourself in a panic. Good unit test coverage provides you with confidence that you will not receive calls in the middle of the night due to breaks in your application.
00:07:10.760
So, what is Jasmine? It is a JavaScript testing framework created by Pivotal Labs, which is a known Rails consultancy. You’ve likely heard of Pivotal Tracker, a common tool that many of us use. Mentioning other frameworks, there’s QUnit, the framework used by the jQuery project, but QUnit is primarily an assertion framework, while Jasmine utilizes a BDD style syntax.
00:07:30.960
Jasmine is super easy to use, and I'll demonstrate this shortly. The syntax closely resembles that of RSpec, which provides various advantages, especially when you’re transitioning contexts frequently between unit tests in JavaScript and RSpec. Staying consistent in syntax means you won’t have to switch mindsets as much. Jasmine supports Ruby gems for Ruby, Rails, Node.js, and has a wealth of available plugins; everything you need to test is readily accessible. It's easy to plug into a CI server and doesn't require downloading any other JavaScript frameworks such as jQuery or Prototype.
00:08:17.680
There’s a vibrant community around Jasmine that continuously develops plugins, making it a safe framework to adopt without worry of it disappearing anytime soon. To clarify again, Jasmine is not an integration testing framework; it is meant for unit testing and testing code in isolation. This is different from tools like Cucumber or Capybara, which focus on full stack integration testing.
00:08:54.160
Now I’ll start showing some syntax by comparing RSpec and Jasmine. The RSpec code appears at the top, while Jasmine appears at the bottom. Just look at how similar they are. The primary difference is the use of 'it()' in Jasmine compared to 'describe()' in RSpec. With RSpec, you can easily shift your context and use various aliases, while Jasmine keeps it straightforward. Jasmine uses 'expect()' as the central function for assertions, enhancing its fluidity in syntax and testing. Jasmine simplifies setup with built-in before and after hooks.
00:09:39.920
Jasmine has several simple matchers. Unlike RSpec, where you can say 'should' to convey expectations, Jasmine relies on the 'expect()' format, where you can chain additional conditions after it. This requires a little adjustment, but it becomes intuitive.
00:10:02.560
What I want to show is an example of a simple calculator. Assuming you have a method called 'add' that returns the result of adding two numbers, we'd execute a test to ensure that calling 'add(1, 1)' correctly results in 2. There's ongoing debate about whether there should be a single expectation per it block, which is subjective. Breaking assertions into separate statements can lead to better readability.
00:10:27.760
There are many matchers in Jasmine, allowing straightforward tests. You execute the method, and the resulting output can be checked against expected values. This process keeps testing simple.
00:10:35.760
Custom matchers in Jasmine allow for enhanced testing capabilities, similar to RSpec. You can define your custom functionality within the Jasmine namespace, enabling wider utility across tests. This way, you can establish consistent methods that can be reused throughout your assertions.
00:11:07.760
To effectively manage custom matchers, you can create a helper file for specifications. This file allows you to define various utility functions and expectations centralized for easy accessibility throughout your other spec files.
00:11:30.560
When discussing spies in Jasmine, there may be times when you'd like to control how methods behave during tests. Utilizing spies allows you to intercept calls and retrieve tracking metrics about them, making testing behavior-oriented. Consequently, this adds a layer of monitoring to your functions.
00:12:07.360
With Jasmine, it's easy to validate component functionality in various ways. I won't go too extensive into Test-Driven Development (TDD), but it's vital to write tests before the corresponding code exists. This drives unit tests to focus directly on components and methods, confirming correctness right from the beginning.
00:12:47.360
Why do I like TDD? It helps maintain focus. Writing a failing test helps you identify what you are working on. You know exactly what needs fixing. This approach keeps you on track and reduces distractions.
00:13:16.160
TDD also assists in designing your API structure. You are effectively shaping components as you test them, resulting in a well-structured API. Finally, TDD alleviates stress regarding deployments. When you have unit tests in place, the anxiety associated with changes decreases significantly.
00:13:46.560
Now I will demonstrate how to work with Jasmine using vanilla JavaScript. To do this, you'll visit a GitHub repository, download the latest version, and set it up in your folder.
00:14:07.680
After extracting the zip file, you’ll see a spec runner HTML file with various scripts and tests. This provides an example framework to understand how to test JavaScript applications.
00:14:31.679
I encourage you to delete the example files and write your own testing files to get familiar with the setup. The simplicity of creating your spec files is integral to the Jasmine framework.
00:15:05.920
Moving forward, let's set up a simple calculator test in JavaScript. By creating a calculator instance and verifying its methods, like understanding if adding two numbers returns the expected sum, demonstrates the straightforward nature of Jasmine.
00:15:35.520
By running the tests in the browser and making changes to the JavaScript code, you can observe how the specs reflect outcomes that result in either passing or failing tests, allowing for immediate feedback and rapid iterations on your code.
00:16:03.520
Now I'd like to show you how to implement Jasmine within Ruby without Rails. This involves setting up a gem specifically designed for Jasmine testing, which can take a Blink folder structure.
00:16:39.520
You will also gain insights into using Jasmine with jQuery, which has various additional matchers you can work with to facilitate manipulation and testing within the DOM.
00:17:15.520
You might also explore how to use the Jasmine framework in conjunction with CoffeeScript. By modifying file extensions and adjusting the setup slightly, you can test your CoffeeScript alongside the JavaScript tests seamlessly.
00:17:41.320
Switching over to cover testing structures under Rails can provide more structure. It's essential to leverage gems that streamline the process of testing JavaScript in your environment.
00:18:02.720
Further, when you utilize evergreen, a gem designed to facilitate Jasmine within Rails, usage becomes simple and integrates with your existing workflow, ensuring you can run tests both in development and continuous integration environments.
00:18:38.480
It’s vital that you remain aware of how to structure your test files and declarations, particularly when incorporating jQuery and its plugins into your tests.
00:19:10.720
Finally, we should consider how to do headless testing with Jasmine in a CI context. Tools like Capybara Webkit allow you to run tests without opening a browser window, enhancing efficiency.
00:19:44.640
Additionally, using plugins for Node.js helps to further broaden the testing capabilities available, ensuring extensive testing coverage.
00:20:22.880
In summary, I want to emphasize the importance of unit testing JavaScript. It’s code that requires testing just like any other section of your application.
00:20:55.520
Jasmine makes this process smooth and approachable. Its familiar syntax and powerful features can enhance confidence and reliability in your application’s front-end code.
00:21:29.640
Lastly, I work for PeopleAdmin, and we are actively hiring. Working with me would provide an exciting opportunity to grow and innovate within a professional context.
00:22:00.080
I invite questions or discussions around any plugins or approaches I may have missed. My slides are posted online, and I hope to receive feedback on my presentation.
00:22:39.440
As time is short, I look forward to discussing any inquiries you may have. Thank you all for attending, and enjoy the rest of the conference!
00:23:02.160
Let's go eat some chicken fried chicken!