Recently, I wrote a tutorial on how to get started using Typescript, ReactJS, and Webpack because I noticed there weren’t many good online resources highlighting how to integrate them together. In this post, I want to continue where I left off and add a wrinkle many people have asked for: Testing. I won’t explain why we want to write tests for our code because if you’re reading this, I’m going to assume you know how important and life-saving it can be! Instead, my goal with this post is to provide a structure for writing tests in a project that uses Typescript, ReactJS, and Webpack, and explain why we use some of these testing technologies.

For those of you who want to dive in and see the final version of the code, check it out here!

Brief prelude on the different Testing technologies

As we all know, the JavaScript community has tons of different libraries and frameworks for doing just about anything you can imagine. As you can guess, the same is true for testing JavaScript code and there’s a myriad of technologies out there. At a high level though, these technologies fall into 4 major categories:

Test Runner (example: KarmaJS) Testing Framework (example: MochaJS) Assertion Library (example: ChaiJS) Various plugin libraries (example: SinonJS)

Each of the examples I provided are representative of each category. However, I want to point out that it’s not always the case that a framework or library fits neatly into one of these buckets. For example, another popular testing framework JasmineJS is its own testing framework, assertion library, and includes some functionalities found in different plugin libraries.

At this point, you might be asking, “So what exactly is each one of these categories responsible for? Why does it seem so complicated?” Here’s a good way to think about them and how they relate to each other:

The test runner is responsible for actually running the test code that you’ve written. In the case of KarmaJS, you’ll write a configuration file that spins up a web server to execute your test code in different browsers and then displays the test results for you. What’s important to note is that the test runner is useless unless its configured to use a testing framework, assertion library, and other plugin libraries. The testing framework is responsible for structuring your test code. It provides methods that are concerned with structuring your test code so that you’ll have different code blocks for testing each of your source files and code blocks for testing a different functionalities in a source file. The assertion library is responsible for checking / asserting whether the values you expect are actually the values you get. The set of methods bundled with an assertion library typically compare 2 values and determine whether they are equal. Typically, your test code will use methods from your testing framework to structure the tests into code blocks, and then use methods from your assertion library within each code block to assert whether your expectation is correct. I’ve labeled the last group of libraries as a catch-all for various plugin libraries. Essentially, these different libraries enhance and provide additional methods that can be used in combination with the assertion library. For example, SinonJS is a library that allows you to stub out a particular function’s implementation with another dummy function — the reason this is useful is because you can then assert whether that dummy function was called, how many times it was called, what arguments it was called with, etc.

Hopefully, you now have a better understanding of why you need these different technologies and how they’re related. Luckily for us, KarmaJS, MochaJS, ChaiJS, and SinonJS are extremely popular and have become sort of the de-facto JavaScript testing technologies.

Getting Started

I’m going to assume that you’re using my previous post as the starting point. If you want to see the code from the previous post, check out the master branch in this Github repo.

After cloning down the Github repo, change into that directory and run the following:

I’ve named my project “typescript-react-webpack” but you can name it anything you want!

At this point, your package.json should look like this:

Since we’ve already introduced Typings in the previous post, let’s also go ahead and install the typing files for SinonJS, MochaJS, and ChaiJS:

At this point, your typings.json file should look like this:

If you’re keeping track, we’ve installed our testing framework (MochaJS), assertion library (ChaiJS), and one of many plugin libraries out there (SinonJS). We still haven’t installed the test runner yet, but before we do that, let’s first create a test directory in our root and add a test file:

Remember to be in the project’s root directory before running this command!

The test file that we’re going to write will be for the Hello.tsx file. In case you don’t remember, here’s the gist we set up in the previous post for it:

And here’s the corresponding test file:

A couple of things to note:

We’re importing a new library that we haven’t seen before: React-Addons-Test-Utils. This library is specifically for testing React components and provides a suite of methods for doing so (i.e. TestUtils.createRenderer, etc). You can learn more about TestUtils here. We’ll go ahead and install this NPM package next! If you recall the earlier discussion on Testing Frameworks and Assertion Libraries, you’ll see them both at work here. The “describe” and “it” methods are provided by the MochaJS framework, and at a high level, they’re used to organize your test code into logical blocks to test different functionalities. Within each of the “it” methods, you’ll notice that we have “chai.assert.strictEqual(…)” and this is where the ChaiJS assertion library comes into play. Essentially, within each “it” method, you write some code to test your functionality and then assert whether the value you get from running the test code is what you expect.

Let’s go ahead and install React-Addons-Test-Utils so that our test code can import it:

Remember to save as a dev dependency!

And here’s how our package.json looks right now:

Let’s also go ahead the run the following to get the typings for React-Addons-Test-Utils:

node_modules/.bin/typings install --save --ambient react-addons-test-utils

We’re almost at the last step which is to install and set up KarmaJS. Again, remember that KarmaJS is responsible for actually running our test code. While it’s probably possible to configure our application to run the tests without installing and setting up KarmaJS, I haven’t found a way to do this easily when using Typescript, ReactJS, and Webpack together. One of the reasons I’ve needed to use Karma is because it allows me to write my test code in Typescript, preprocess those files through Webpack, and then run the tests in various browsers.

We’re about to install a bunch of KarmaJS related NPM packages — I’ll explain why each of these packages are needed but at a high level, KarmaJS is pretty useless without providing it a testing framework and assertion library to use. These packages are related to integrating KarmaJS with the other technologies that we have already installed: