Skip to content


Unit and E2E Tests with AngularJS in a Browser

I was playing with the great JavaScript Framework AngulaJS.org which gains some momentum (from AngularJS – some initial thoughts) in the last weeks. AngularJS is very easy and enjoying to get into it to write one page web pages. The tutorial videos from egghead.io from John Lindquist helped a lot and clarified some behavior and tricks of Angular.

The documentation of Angular is very good in general and has always a block how to test a specific function of Angular. The standard way for testing is to use Karma (previous Testacular) and runs server side with node.js. If you like to run tests on the client side within a browser the unit testing doc has some missing sections. This blog describes who to setup AngularJS unit tests and end-to-end test within the browser.

AngularJS Unit Tests with Jasmine

Jasmine is de facto standard for unit tests in javascript. Jasmine can executed in the browser or server side. You have to download Jasmine and extract jasmine.js with jasmine-html.js to lib/jasmine-x.x.x folder below your test folder. angular-mocks-1.1.0.js comes from the AngularJS zip and should be alsoe located in your lib folder. The index.html of unit tests could look like:

<!DOCTYPE html>
<html>
  <head>
    <title>AngularJS Unit Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
    <!-- include jasmine -->
    <link rel="stylesheet" type="text/css" href="lib/jasmine-1.3.1/jasmine.css" />
    <script type="text/javascript" src="lib/jasmine-1.3.1/jasmine.js"></script>
    <script type="text/javascript" src="lib/jasmine-1.3.1/jasmine-html.js" ></script>
 
    <!-- import angular specific files -->
    <script type="text/javascript" src="../js/angular-1.0.5.js" ></script>
    <script type="text/javascript" src="lib/angular-1.1.0/angular-mocks.js" ></script>
 
    <!-- project dependencies -->
    <script type="text/javascript" src="../js/angular-ui.min.js" ></script>
 
    <!-- application files -->
    <script type="text/javascript" src="../js/app.js" ></script>
    <script type="text/javascript" src="../js/app-controllers.js" ></script>
    <script type="text/javascript" src="../js/app-filters.js" ></script>
    <script type="text/javascript" src="../js/app-routes.js" ></script>
    <script type="text/javascript" src="../js/app-services.js" ></script>
 
    <!-- include test files -->
    <script type="text/javascript" src="js/test-runner.js" ></script>
    <script type="text/javascript" src="js/spec.js" ></script>
  </head>
  <body>
    <!-- will be filled by test-runner -->
  </body>
</html>

While the test-runner.js is

(function() {
  var jasmineEnv = jasmine.getEnv();
  jasmineEnv.updateInterval = 1000;
 
  var trivialReporter = new jasmine.TrivialReporter();
 
  jasmineEnv.addReporter(trivialReporter);
 
  jasmineEnv.specFilter = function(spec) {
    return trivialReporter.specFilter(spec);
  };
 
  var currentWindowOnload = window.onload;
 
  window.onload = function() {
    if (currentWindowOnload) {
      currentWindowOnload();
    }
    execJasmine();
  };
 
  function execJasmine() {
    jasmineEnv.execute();
  }
 
})();

The spec.js contains the unit test like in angular doc

describe("App Test", function() {
  // Global import of application to make all app's modules available
  beforeEach(function() {
      module('myApp');
  });
 
  describe("DataProvider Service Test", function() {
    var dataProvider;
 
    beforeEach(function() {
      // assign service for service test
      inject(function($injector) {
        dataProvider = $injector.get('DataProvider');
      });
    });
 
    it('should have 551 entries', function() {
      expect(dataProvider.findAll().length).toBe(551);
    });
 
    it('should find entry with id \'id4711\'', function() {
      expect(dataProvider.findById('id4711')).not.toBe(null);
    });
 
    it('should find 5 matches', function() {
      expect(dataProvider.findAllByExpression('wind strength').length).toBe(5);
    });
  });
 
});

AngularJS with Jasmine

End-To-End Test with AngularJS Scenarios

AngularJS provides a simple e2e javascript to tests user actions on the real page. These tests are written in scenarios. ng:autotest="true" starts the test automatically.

<!DOCTYPE html>
<html>
  <head>
    <title>Angular E2E Tests</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
    <!-- use angular e2e scenario test runner with enabled autorun -->
    <script type="text/javascript" src="lib/angular-1.1.0/angular-scenario.js" ng:autotest="true"></script>
 
    <!-- include e2e tests of app -->
    <script type="text/javascript" src="js/scenarios.js" ></script>
  </head>
  <body>
    <!-- will be filled by angular scenario -->
  </body>
</html>

Within the scenarios.js you describe user actions which are than executed in an iframe.

describe('My App', function() {
  describe('Query List', function() {
    beforeEach(function() {
      // point relative to your apps index.html
      browser().navigateTo('../index.html');
    });
 
    it('Query Filter', function() {
      expect(element('.questionList li').count()).toBeGreaterThan(3);
      input('listFilter.input').enter('wind strength');
      expect(element('.questionList li').count()).toBe(5);
    });
  });
});

AngularJS Scenario Runner

Posted in linux.

Tagged with , , , .