Getting started with testing
When making a change of this nature, it’s a good practice to write an automated test to verify that the feature is implemented correctly.
Our first test
The trainjs generate controller
command automatically generated an end-to-end test file to get us started
~/sample_app $ ls public/test/e2e_test/controllers/
static_pages_controller_test.js
The default tests for the staticPages controller
public/test/e2e_test/controllers/static_pages_controller_test.js
describe('staticPagesControllerTest', function() {
it('should get home', function() {
var current_url = 'http://localhost:1337/#/static_pages/home';
browser.get(current_url);
expect(browser.getCurrentUrl()).toContain('#/static_pages/home');
expect( element(by.css('body')).getText() ).not.toEqual('');
});
it('should get help', function() {
var current_url = 'http://localhost:1337/#/static_pages/help';
browser.get(current_url);
expect(browser.getCurrentUrl()).toContain('#/static_pages/help');
expect( element(by.css('body')).getText() ).not.toEqual('');
});
});
To begin our testing cycle, we need to run our test suite to verify that the tests currently pass. We can do this with the protractor, an end-to-end test framework for AngularJS
~/sample_app $ protractor protractor.conf.js
Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
Started
..
2 specs, 0 failures
As required, initially our test suite is passing.
Failing test
Our first step is to write a failing test for the About page.
public/test/e2e_test/controllers/static_pages_controller_test.js
describe('staticPagesControllerTest', function() {
it('should get home', function() {
var current_url = 'http://localhost:1337/#/static_pages/home';
browser.get(current_url);
expect(browser.getCurrentUrl()).toContain('#/static_pages/home');
expect( element(by.css('body')).getText() ).not.toEqual('');
});
it('should get help', function() {
var current_url = 'http://localhost:1337/#/static_pages/help';
browser.get(current_url);
expect(browser.getCurrentUrl()).toContain('#/static_pages/help');
expect( element(by.css('body')).getText() ).not.toEqual('');
});
it('should get about', function() {
var current_url = 'http://localhost:1337/#/static_pages/about';
browser.get(current_url);
expect(browser.getCurrentUrl()).toContain('#/static_pages/about');
expect( element(by.css('body')).getText() ).not.toEqual('');
});
});
As required, the test initially fails
~/sample_app $ protractor protractor.conf.js
Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
Started
..F
Failures:
1) staticPagesControllerTest should get about
Message:
Expected 'http://localhost:1337/#/' to contain '#/static_pages/about'.
3 specs, 1 failure
Passing test
Now that we have a failing test, we’ll use the failing test’s error messages to guide us to a passing test, thereby implementing a working About page.
We can get started by examining the error message output by the failing test:
~/sample_app $ protractor protractor.conf.js
Message:
Expected 'http://localhost:1337/#/' to contain '#/static_pages/about'.
The error message here says that no route matches the desired action/controller combination, which is a hint that we need to add the state to the public/app.js
file.
.state('static_pages_help', {
url: '/static_pages/help',
templateUrl: 'partials/static_pages/help.html',
controller: 'StaticPagesHelpCtrl'
})
.state('static_pages_home', {
url: '/static_pages/home',
templateUrl: 'partials/static_pages/home.html',
controller: 'StaticPagesHomeCtrl'
})
.state('static_pages_about', {
url: '/static_pages/about',
templateUrl: 'partials/static_pages/about.html',
controller: 'StaticPagesAboutCtrl'
})
Define StaticPagesAboutCtrl
in the public/controllers/static_pages_controller.js
file.
'use strict';
var staticPagesController = angular.module('staticPagesController', []);
staticPagesController.controller(
'StaticPagesHomeCtrl',
['$scope', function ($scope) {
}]
);
staticPagesController.controller(
'StaticPagesHelpCtrl',
['$scope', function ($scope) {
}]
);
staticPagesController.controller(
'StaticPagesAboutCtrl',
['$scope', function ($scope) {
}]
);
As before, our test suite is still failing, but the error message has changed again:
~/sample_app $ protractor protractor.conf.js
Message:
Expected '' not to equal ''.
This indicates a missing template. We need to create a new file called about.html in the partials/static_pages/
directory.
The generated view for the Home page.
<h1>About</h1>
<p>
The <a href="http://www.nodeontrain.xyz/"><em>Node On Train
Tutorial</em></a> is a
<a href="http://www.nodeontrain.xyz">book</a>
to teach web development with
<a href="http://nodeontrain.xyz/">Node On Train</a>.
This is the sample application for the tutorial.
</p>
At this point, our test suite is passing
~/sample_app $ protractor protractor.conf.js
Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
Started
...
3 specs, 0 failures