Unit testing your Browserify code (Part 1)

Browserify Unit Testing

Returning to Javascript is always fun and scary at the same time. Lately I’m working on a web application and I wanted to make the experience less scary so I’ve invested some time to the tools that all the cool kids use, Grunt, NPM etc. Through this process I’ve discovered Browserify and I was so, so, so happy with the way it handles dependencies. At last I was able to divide my code in countless little js files. I had some fun with it until I’ve decided to add unit tests. I’ve already had some minor experience with Jasmine so I started messing around with Grunt to make it run my browserify-based tests. That’s when the hair pulling started.

This tutorial will be separated in two parts. In the first (this one) I will try to demonstrate how you can set up a project that uses Browserify and Grunt to automate the build process and I’ll add some code to play with. In the second one, we will add the unit testing functionality and make them all work together.

What we’re going to use

  1. NPM – The node.js package manager will help us install the tools we need and the various libraries as well. All the following tools will be installed through NPM so if you haven’t installed node yet, go ahead. It’s magic.
  2. Grunt – Grunt will coordinate the build process by running every tool when we need it to do so.
  3. Browserify – The final packaging will be achieved through browserify.
  4. Jasmine – The unit testing library
  5. Karma – The test runner. Karma will start the jasmine tests and include information on what tests we have and how it should run them.
  6. PhantomJS – A headless browser that makes the testing process easier.

package.json

Node.js allows you to “install” javascript libraries for your project and at the same time have a central file that describes all the libraries you use. This file is called package.json and its located in the root directory of your project.

This file acts as your project description but we’ll only use the devDependencies object to define our libraries. If you want to add more info for your project have a look at the official documentation.

The most basic package file you can have is something like this.

Keep in mind that syntax errors in your json declarations will make npm unhappy and it will complain.

Grunt and Gruntfile

Grunt is in the core of what we try to achieve. Let’s install it and see how we can proceed after that.

While you’re in the root directory of your project run the following command.

This will download and install everything you need to work with Grunt from the command line. Next we will add Grunt itself in our project by running the following installation command.

The –save-dev option is crucial if you want npm to add the installed libraries in your package file. Your package.json file should look like this after the installation.

Grunt uses the concept of tasks to organize the build process. Grunt itself and its tasks can be configured inside Gruntfile.js, a file that sits next to your package.json and it’s necessary to have Grunt working. At the moment we have no tasks so lets just add the file and its basic code.

We’ll add more to that as we go on.

Browserify basics

Essentially, Browserify allows you to easily import javascript code from one file to another and not worrying about loading all the files in your HTML. You can use the require() method to load any code that resides in some other file or library and Browserify will check your requirements and build one file that contains the code of your application (including any libraries you use). All you have to do is load the built file in your HTML and you’re good to go.

The great advantage is that you can have only one script element in your html page and the final script file is built the way it should, with dependencies in the right order.

There is a Grunt-compatible version of it and you can have it installed using the following command.

Adding a library and some code

Let’s assume that our project is based on the lodash library. Our first step is to install it through npm just like the other dependencies.

After installing it, its probably a good time to start adding some of our own code. The following example includes a javascript file called methods.js with a very basic method that calculates the age of someone based on the provided parameter, added in the exports object so that it can be required properly by other files/modules. The method is using the isNumber function of the lodash library which can be accessed without a problem because it has been required right above the method.

Browserify will look in your installed node modules to find what you’re trying to use and since we have installed lodash everything will work as expected.

The next file to include in our src directory is the main entry point of the application, let’s call it start.js. All we do here is add the requirement for the methods.js module and call the calculateAge method with a valid parameter.

Browserify as a Grunt task

Time to start modifying the Gruntfile and add tasks to it. The first task to be added will be the browserify command which depends on two files to work.

The first is the file that will be included in your application. Both your code and the libraries you use will be added in this one. The second file is the entry point of your application, in our case the start.js.

The debug option is helpful if you want to debug your application inside a modern browser using source maps.

That’s all the configuration you need to do. After that you simply call the browserify command and your file will be created.

Hopefully no errors have occurred during the process and you can see a final-output.js file in your project’s directory. Including it in your html and testing it will log the result of the method to your console.

End of part 1

That’s it for the first part. We have two files and a library bundled in one file that can be used by our app. We also have a method that is ready for some unit tests and this is coming in the second part.

The full project will be uploaded in Github once the second part is posted.

 

Update : Project is available on Github and part 2 is up as well

  • unrelated to this but
    I saw various utility functions in the code blocks as hiding line nos, opening code in new tab, copying code. is it an external library or do you build it yourself