Last Updated: February 25, 2016
· newtriks

Testing an AngularJS Directive

Project tools

sudo npm install -g yo grunt-cli bower karma

Yeoman generators:

sudo npm install -g generator-angular generator-karma

(thanks to @amscotti for the heads up on these).

Create the project

mkdir directive-example && cd $_
yo angular

Configure Karma

Open the karma.conf.js file and make the following changes (any changes to this file require you to restart Karma):

Base path

To enable Karma to use the correct template path and have the directive load template file you will need to change the basePath:

basePath = 'app';

File patterns

Amend the paths to reflect the newly defined basePath:

files = [

Compiling templates

Templates need to be compiled to javascript otherwise you will get a parse error on running Karma. The html2js preprocessor is the solution and simply requires adding the following to your karma.conf.js (this is based on you storing template files within a directory in views):

preprocessors = {
  'views/**/*.html': 'html2js'

Auto watch

This is a really cool part of Karma where you can enable watching files and then auto executing tests as you develop:

autoWatch = true;


I use PhantomJS to run the Angular tests as opposed to relying on a browser such as Chrome.

Change the browser for running tests to PhantomJS:

browsers = ['PhantomJS'];

Create a directive

yo angular:directive albums

Start Karma

To start Karma which will also auto run the tests when we update the files use:

karma start

You should now see that two tests have been executed successfully:

Executed 2 of 2 SUCCESS (0.284 secs / 0.015 secs)

Create a failing test


(Our list is sourced from the crazy talented Busdriver!)

Let's fix the first error we see:

Error: No module: views/templates/albums.html

Build a simple template

mkdir -p app/views/templates
touch app/views/templates/albums.html

Our test is still failing, let's add the new template to the albums.js directive, change the line of code declaring the template to:

templateUrl: 'views/templates/albums.html',

The test will still fail as we are not creating a list within the template. Let's do that now by adding the following to the albums.html:


And update the albums.js directive as follows:


Word! The test passes. Let's add another test to check the first album in the list has the correct title.

it("should display the correct album title for the first item in the albums list", function() {
    var list = element.find('li');
    expect(list.eq(0).text()).toBe('Memoirs of the Elephant Man');

The test fails. Let's add the title attribute to the directives scope in albums.js:


Sweet, the test's are passing again.

All the source to this project can be found on Github.

Full article can be read here: http://newtriks.com/2013/04/26/how-to-test-an-angularjs-directive/

Say Thanks

1 Response
Add your response


very comprehensive and well written

over 1 year ago ·