Writing Test Solutions with JavaScript: Starting Out

As many of my readers my know, or have figured out, I’ve been a fan of the Ruby language for quite some time and I’ve used it to construct some of my own open source testing solutions. I’m now actively pursuing JavaScript as my potential test ecosystem of choice. In a few upcoming posts, I’ll talk about this journey with practical examples. This first post starts things off by getting you up and running with a few possible JavaScript technologies.

To set expectations, in this post I’ll cover a bit about using Node as the means by which to host your JavaScript execution. I’ll talk about using NPM to get the required dependencies. I’ll very briefly cover one very popular test library, Mocha, and I’ll show you how to use a build management tool to fire things off. I’ll also provide a very brief foray into using a JavaScript alternative, called CoffeeScript.

By necessity I’m going to be giving you a bit of a whirlwind tour here. As a test developer myself, I often have enough knowledge of how to utilize different languages and different tools. That’s not the problem. The problem is simply knowing where to start and then actually getting started with some very minimal examples so that I can play around further on my own. So I need you to come in to this with at least some pre-existing knowledge or, at minimum, a comfort level with getting into a particular language’s ecosystem.

To do all this, you need Node.js and NPM. I have my Setting Up WebDev page to help you get started with all that. If you’re curious and/or a glutton for punishment, I also do have a series of Node.js tutorials, but they are much more involved than what you need for these test-specific discussions.

Create the Project

This part is simple. Just pick some spot on your filesystem where you want to create a project. Do note that I do just about everything via the command line, but if you want to use an editor and/or IDE, feel free. As with most such tutorials, a $ is meant to indicate a generic prompt and not something you should type in.

$ mkdir project-dir
$ cd project-dir

Set up the Project

One of the test runners that is extremely popular for writing tests with JavaScript is called Mocha.js, usually shortened to just Mocha. Let’s first install this as a local project dependency.

$ npm install mocha

Some tutorials will have you install Mocha globally, by adding a “-g” flag to the above command. That’s certainly fine as it allows you to run the mocha command from anywhere. As it is, with my current instructions you would have to run Mocha like this:

$ node_modules/mocha/bin/mocha

However, I tend not to install anything globally unless I absolutely have to. I’m going to show you how you don’t have to use that full command path. If you are creating a Node project specifically, you will usually have a package.json file which serves as a means of identifying a particular module. Normally people will initialize their project at the start — and that’s fine — but here I’m showing you can do it later. So let’s initialize our project:

$ npm init

You’ll be asked a series of questions about your project. You can pretty much just accept the defaults for now. One thing to note in particular is the “test command” prompt you are given. You’ll notice that it defaults to “(mocha)” and this is because NPM was smart enough to see that you already had a node_modules directory and it looked within there to see that you also had a mocha directory. Since NPM is aware that Mocha is a test runner, it makes the likely assumption that you want to use it for running tests.

What this means is that you can now run your test runner of choice by doing the following:

$ npm test

Obviously you don’t have any tests yet so if you run that now you’ll get something like Error: cannot resolve path (or pattern) 'test'. We’ll come back to that in a bit but for now you can probably see that the nice thing about this approach is that you can switch out your test runner but still run the same command. You can also use multiple test runners in your project and simply add more sections to the package.json file.

Speaking of that file, if you look at its contents you’ll notice that “mocha” is now a “devDependency”, which is generally what you would want for your test projects. Although do note that deployment of a test solution can be a bit different than deployment of an application solution. I won’t go into that too much right now since this post isn’t about deploying test solutions, but rather just getting started with them.

You can probably see that there’s a lot of supporting material that I could be covering here but I’m not. I do talk a little about NPM and initializing projects in my third post on learning Node.js. For an exhaustive explanation of all the information that package. json can contain, just issue the npm help json command or, even better, go to https://www.npmjs.org/doc/files/package.json.html. For an exhaustive list of all the commands of NPM, go to https://www.npmjs.org/doc/cli/npm.html. Regarding those version numbers you see in the package.json file, you can define any kind of version range; see https://www.npmjs.org/doc/misc/semver.html for more details.

Create a Test

So remember that horrendous looking error you got when running npm test? What that was basically telling you is that Mocha was looking for a test directory but couldn’t find it. Mocha will be able to run tests from anywhere but, by convention, it will look in a test directory. So let’s set one up.

$ mkdir test

In that directory, create a file called first-test.js and put the following in it:

If, like me, you’re coming from Ruby, you’ll notice this format is very much like RSpec. Both of these test solutions are conceptually similar to NSpec in the .NET testing world or GSpec in the Java testing world. I’m going go into more specifics about Mocha in a future post, so for now just take note of the structure.

You might notice that I’m using the built in assertion library of Node.js. This is really nice and simple. You can see the full documentation for the assert library. For some people that simplicity is enough for what they want. For others, however, they prefer more expressive ways to assert aspects about tests. I’ll talk about alternatives in that same future post where I’ll cover Mocha in greater detail.

Make sure you run this with:

$ npm test

You should see some nice output showing a passing test.

Syntactic Sugar for Tests

I’m adding this part mainly for the Rubyists in the crowd who tend to like their test structure to be as syntactically clean as possible. One thing you’ll note with JavaScript is you always have callback functions being passed around. It can add to the boilerplate of using JavaScript, to be sure. One neat “trick” is to use an alternative called CoffeeScript.

First, let’s install a local copy of CoffeeScript:

$ npm install --save-dev coffee-script

This will install the coffee-script module and, since I used the “–save-dev” flag, it will add it to the “devDependencies” of package.json. Incidentally, you may wonder why I didn’t use this same flag with Mocha earlier. That’s because I didn’t have a package.json file yet. Had I ran npm init first and then installed Mocha I would have used the command npm install --save-dev mocha to do so.

Now create a file called second-test.coffee in your test directory. Put the following in that file:

As you can see, it’s the same test as before but with a lot less boilerplate. This is one of the reasons many JavaScript developers prefer CoffeeScript. As a tester focused on writing test solutions, I’m still on the fence about CoffeeScript. I don’t dislike it, by any means, but it’s one more layer I sometimes have to worry about.

In any event, if you run npm test now you’ll find that your previous test still passes but the new one isn’t being run. The reason for this is that Mocha is looking for JavaScript (*.js) files but this is a CoffeeScript (*.coffee) file. CoffeeScript is basically a language that has be compiled into JavaScript in order for it to run. Without going into all the details of what this means, for now you can create a file called mocha.opts in your test directory and put the following in it:

You can now run the test command again:

$ npm test

You should see that you have two passing tests.

Using a Build Manager

Earlier I had talked about Grunt as a build tool to use for JavaScript, but a tool called Gulp definitely seems to be gaining momentum and I personally find Gulp’s stream approach to be a much more logical approach to specifying build tasks.

First, you have to install Gulp. In this case, I’m going to install Gulp globally, since it is a build tool that can be used for any project, as well as locally so that it serves as a dependency for my project.

$ npm install gulp -g
$ npm install --save-dev gulp

You can check if you have a global Gulp by doing this:

$ gulp -v

Since I’m using Mocha as my test runner and I’m going to want Gulp to utilize it, I’m going to also locally install the gulp-mocha plugin.

$ npm install --save-dev gulp-mocha

Now, create a gulpfile.js file in the root of project-dir. And then put the following in that file:

This isn’t the post to cover Gulp in detail but essentially what I’m doing there is setting up a build task called ‘mocha’ that reads in all of the *.js files in my test directory. I’m then using the Gulp stream approach, via the .pipe call, to send those files to Mocha. I’ve also said that the default task is to run my ‘mocha’ task. To run the build, just do this:

$ gulp

Hmm. Notice something interesting there? Only one test ran and that’s the JavaScript test. The CoffeeScript test did not run. This has to do with some oddities regarding how the mocha.opts file is processed. What you can do is change your task as follows:

Now you should find that both tests are running.

And there you have it! A brief foray into the world of writing test solutions in JavaScript. Even though I’ve barely scratched the surface here, consider what you’ve done. You’ve used Node.js, NPM, Mocha, CoffeeScript, and Gulp all in one shot.


This article was written by Jeff Nyman

Anything I put here is an approximation of the truth. You're getting a particular view of myself ... and it's the view I'm choosing to present to you. If you've never met me before in person, please realize I'm not the same in person as I am in writing. That's because I can only put part of myself down into words. If you have met me before in person then I'd ask you to consider that the view you've formed that way and the view you come to by reading what I say here may, in fact, both be true. I'd advise that you not automatically discard either viewpoint when they conflict or accept either as truth when they agree.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.