From: http://www.cnblogs.com/vipyoumay/p/5331787.html
In this paper, we introduce the unit and E2E testing of the application developed by angular through the framework of karma and jsmine.
- Practice of angular unit testing and integration testing
Precondition
- nodejs
- webstorm
Create project
Create a blank web project in webstorm
Create html, js folders
Create two folders in the project to store the html and js files used in the project.
Installation framework
Install front-end frame
The front-end framework in the project is mainly angular JS related framework. In order to install the framework conveniently, the bower package manager can be installed.
1) Install the bower package manager
Executing scripts in terminal of webstorm
npm install bower -save
2) Initialize bower.json file
Execution scripts generate bower.json files for managing bower dependencies and configurations.
bower init
3) Installation of frameworks such as angular
In addition to the angular framework to be used in the project, the angular-mocks framework needs to be installed.
bower install bootstrap -save
bower install angular -save
bower install angular-mocks -save
Installation of Server-side Framework
The server relies on nodejs and needs to install the package of nodejs. First, create the package.json file in the root directory.
1) Install http-server module
npm install http-server -save
2) Install other modules
- jasmine-core:javascript unit testing framework;
- karma: A tool that simulates javascript scripts in various browsers.
- karma-chrome-launcher: Tool executed in chrome browser;
- karma-jasmine: jasmine-core adapter in karma;
- karma-junit-reporter: Generate JUnit reports;
- protractor:E2E testing framework
Start the server
To start a node server, you need to configure a script node in package.json, define a dependencies package in dependencies, and configure a start node in script to start the server. The contents of the test node will be explained later.
"name": "angularjs-test",
"version": "0.0.1",
"dependencies": {
"bower": "^1.7.7",
"http-server": "^0.9.0",
"jasmine-core": "^2.4.1",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-jasmine": "^0.3.8",
"karma-junit-reporter": "^0.4.1",
"protractor": "^3.2.1"
},
"scripts": {
"postinstall": "bower install",
"prestart": "npm install",
"start": "http-server -a localhost -p 8000 -c-1",
"pretest": "npm install",
"test": "karma start karma.conf.js",
"test-single-run": "karma start karma.conf.js --single-run"
}
Run the command after configuration, start the server, enter http://localhost:8000 on the browser
npm start
Start unit testing
Write functional code
Create a new JS file index. JS in the file js. In index.js, congroller is defined to implement the simple accumulation method add. The code is as follows:
/**
* Created by stephen on 2016/3/24.
*/
(function (angular) {
angular.module('app', []).
controller('indexCtrl', function ($scope) {
$scope.add = function (a, b) {
if(a&&b)
return Number(a) + Number(b)
return 0;
}
});
})(window.angular);
Create a new HTML file index.html in the file html, add two input boxes for users to get input, and bind the add method in the controller to realize calculator function after input. The code is as follows:
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<div ng-controller="indexCtrl">
<input type="text" ng-model="a" value="0">
+
<input type="text" ng-model="b" value="0">
=<span id='result'>{{add(a,b)}}</span>
</div>
</body>
</html>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<script src="/js/index.js"></script>
Start the server and see the following effect
Write test code
Create a new file index-test.js in the test folder to write unit tests for index.js.
'use strict';
describe('app', function () {
beforeEach(module('app'));
describe('indexCtrl', function () {
it('add test', inject(function ($controller) {
var $scope = {};
//spec body
var indexCtrl = $controller('indexCtrl', {$scope: $scope});
expect(indexCtrl).toBeDefined();
expect($scope.add(2, 3)).toEqual(5);
}));
});
});
Unit test configuration
Initialize the karma configuration file to configure karma and execute commands
karma init
In the karma configuration file code, each node has default comments. See
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: './',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'js/index.js',
'test/index-test.js'
],
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-junit-reporter'
],
junitReporter: {
outputFile: '/test_out/unit.xml',
suite: 'unit'
}
})
}
Configure test information in package.json scripts and specify the karma file address
"test": "karma start karma.conf.js",
Running unit tests
Run commands, execute tests
npm test
The results are as follows. You can see that the test has passed.
Debugging Unit Testing
In addition to running tests, debugging tests are often required. Click debug on the karma pop-up page and enter the http://localhost:9876/debug.html page to debug the code with the debugging tool provided by chrome:
Unit test coverage
If you need to make statistics on unit test coverage, you can install karma-coverage and configure karma files. After the unit test is completed, the test coverage report document is generated.
npm install karma-coverage -save
Add nodes to the karma.conf.js file
// Added nodes to configure output folders
coverageReporter: {
type: 'html',
dir: 'coverage'
},
// Added node to configure the file address to be tested (here is the controller address)
preprocessors: {'js/*.js': ['coverage']}
// New element'karma-coverage'
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-junit-reporter',
'karma-coverage',
],
// New element coverage
reporters: ['progress', 'coverage'],
After running the unit test, the coverage folder is generated in the directory, and the test coverage can be viewed by clicking index.html.
E2E test
e2e or end-to-end or UI testing is a test method used to test whether an application's process from beginning to end is the same as the design time. In short, from a user's point of view, it considers that the whole system is a black box, only UI will be exposed to users.
Configuring E2E tests
The new folder e2e-test creates a new protractor.conf.js file to configure the protractor framework. The code is as follows.
exports.config = {
allScriptsTimeout: 11000,
baseUrl: 'http://localhost:8000/app/',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
framework: 'jasmine',
// Spec patterns are relative to the configuration file location passed
// to protractor (in this example conf.js).
// They may include glob patterns.
specs: ['*.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
},
defaultTimeoutInterval: 30000
};
Configure the package.json scripts script node
"preupdate-webdriver": "npm install",
"update-webdriver": "webdriver-manager update",
"preprotractor": "npm run update-webdriver",
"protractor": "protractor e2e-test/protractor.conf.js"
Write e2e test script
Design test cases: value entry 1 for text box a, value entry 2 for text box b, expected result 3
describe('index.html', function() {
beforeEach(function() {
browser.get('http://localhost:8000/html');
});
it('get index html', function() {
var a = element(by.model('a'));
var b = element(by.model('b'));
a.sendKeys(1);
b.sendKeys(2);
var result = element(by.id('result'));
expect(result.getText()).toEqual('3');
});
});
Execute tests to see test results
You need to perform naming to see if you want to update the webdriver. http://sentsin.com/web/658.html),
Manual installation of protractor to global
npm
i -g protractor
Note: FQ is required to install or update webdriver. Please set the proxy address in webstrom.
Switch to the Terminal window in webstrom and set up the agent in the Terminal window in the following way:
set PROXY=http://localhost:1080
set HTTP_PROXY=%PROXY%
set HTTPS_PROXY=%PROXY%
After the proxy setup is successful, run the following commands
npm run update-webdriver
Executing e2e test, which will pop up the browser, automatically click on the browser, enter script input to complete the automated e2e test, its essence is to call selenium test.
npm run protractor
Reference material
[1] Official test demo https://github.com/angular/angular-seed
[2] Official documentation of protractor http://angular.github.io/protractor/#/tutorial
[3] Automated E2E testing http://sentsin.com/web/658.html
[4] karma Official Documents https://karma-runner.github.io/latest/intro/configuration.html
[5] Official documentation for angular unit testing https://docs.angularjs.org/guide/unit-testing
Source address https://github.com/stephen-v/angular-e2etest-showcase
LDAPCtrlDef in the above code introduces ldap.controller.js into the variables by definition, and then $scope,ldapSrv,uiGridUtils and so on are all parameters that need to be injected into the controller.var ldapCtrlInst = $injector.instantiate(LDAPCtrlDef,{ $scope:scope, ldapSrv:ldapSrv, uiGridUtils:{ createGridOptions:function(){return {};}, resetGridSelection:jasmine.createSpy('resetGridSelection') }, modalUtils:{ showDlg:function(){ var deferred = $q.defer(); deferred.resolve(""); return deferred.promise; } } });
var deferred = $q.defer(); deferred.resolve({resultCode:"200",resultObject:[]}); spyOn(ldapSrv,'listLDAP').and.returnValue(deferred.promise);
3) remember to call scope.$digest() in the it method; trigger angular variables to change the binding mechanism