How I Use Angular 2 with Webpack: Karma Files

Reading time: 3 minutes

A disclaimer: I’m not claiming to be an expert here and I’m open to any corrections or input from everyone; this is just what’s worked for me so far. Please enjoy!

As I mentioned in the first post of this series, this series looks out how I have been using Angular 2 with Webpack. The topics in the series are:

  1. Directory Structure
  2. Node Modules & NPM Configuration
  3. Typings
  4. Code Linting
  5. TypeScript Configuration
  6. Karma Configuration
  7. Webpack Configuration
  8. Sample Application

In this article we’ll look at the two Karma files needed to effectively run unit tests.

Why Two Karma Files?

Karma requires a configuration through a karma.conf.js file. When using Webpack, however, the environment for performing the unit testing needs additional set up. The second configuration file sets Angular and Jasmine up, while also making the stack trace show full messages. The most important thing it does is grab the unit test files that will be run and in turn (since I’m using TypeScript modules) pull any application files into the mix. This setup file (karma.entry.js) is, in turn, loaded by the standard karma.conf.js.

Both of these files are located in src/test/karma.

To the Files!

First, let’s look at our karma.conf.js and then we’ll look at the karma.entry.js it uses.

Karma Configuration (karma.conf.js)

In the past, with Angular 1.x applications, my karma.conf.js would be huge and unwieldy. A lot of preprocessors and plugins that needed referencing so that it made it difficult for people coming on to a project to understand what was going on–so they never even bothered. The configuration I’ve been using for Angular 2 projects with Webpack is far more manageable. Let’s take a look:

This is pretty standard Karma configuration fare: tell Karma to auto-watch your files for changes and then specify the browsers to run the tests in.

We only care about loading two files at this point. The first is the ES6 Shim which gives us access to the latest and greatest ES6/ES2015 capabilities, regardless of the browser. The second file is that karma.entry.js that we’ll get to in a moment. I love this because in the past I’d have to reference all of my Angular and non-Angular dependencies as well as my code and unit tests. I could probably use path.resolve for referencing the ES6 Shim, which would be safer, but I don’t right now.

This is more standard fare: tell Karma what testing framework is being used and what level of logging to use.

This is less standard fare. Here we’re setting some configuration for the PhantomJS2 launcher. The only option is a just-in-case option. If Karma exits due to a ResourceError it may not shut down PhantomJS2. This option tells it to do so.

Back to the standard stuff. This time defining the preprocessors and reporters to use and setting the singleRun property. Again, in the past the preprocessors section could be a bit more complicated, but by using Webpack, it seems to get more manageable. All we’re doing is telling Karma to run the karma.entry.js through Webpack and then through the sourcemap preprocessors. The only reporter I’m using is the dots which condenses the output to one “.” per unit test. Lastly, I tell Karma that it’s going to run the unit tests over-and-over again so that I can see my tests run as I develop.

Finally, we define the Webpack configuration file to use (which we’ll discuss in the next post) and tell the Webpack server to limit its output so it doesn’t trounce our console as files update.

My final file is (note: the 'use strict' is necessary to get fat-arrows working):

Karma Entry (karma.entry.js)

As described above, the entry file sets up the environment, discovers any unit test files and pulls them in for testing. Like karma.conf.js this is a very small file.

First, we pull in any polyfills for Angular 2, the Angular 2 test-aware browser library, and the Angular 2 testing library. The browser & testing imports allow us to set base providers for performing our unit tests.

Webpack adds a method to require that allows us to pull in files by a pattern. This method is context. We create a context that looks for any .spec.ts files in the test/spec directory; the second parameter being set to true tells context to look in sub-directories of test/spec. The created context can be used as a function to pull the file in, so that context('this/was/discovered') is equivalent to the regular require('this/was/discovered'). Additionally, the context uses a key-value relationship to reference the discovered files, where the key is the name of the file. Using that information, we can just loop over the keys of the context and load the files.

The last two things in this file are setup steps to show full error stack traces and set Jasmine’s timeout for asynchronous operations to 2 seconds.

My final file looks like this:

And That’s It!

Using these two files, we can the unit tests rockin’ and rollin’. But there’s still one missing component: the Webpack configurations. And we’ll talk about that in the next post.

1 Comment

  1. Hi Matt,
    Great article. Why are you using the fat arrow in your karma.conf.js file? Karma documentation states to use the fat arrow in karma.conf.ts file and declare the function(config) in the .js file. I am only curious.
    Thank you for your time!

Leave a Comment

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