Testing setup with Webpack and Karma

There are two runners to execute tests:

  • HTML runner from the Jasmine's standalone distribution (https://github.com/jasmine/jasmine/releases): Download the ZIP file, unzip it, and open the SpecRunner.html file in any text editor. This HTML file includes some base code that loads the test framework. You need to add regular Angular dependencies, an Angular testing library, and a SystemJS loader, which loads the .spec files. After that, you can open the HTML file in your web browser to see the test results.
  • Command-line runner Karma: Karma can run tests in different browsers and report possible errors with various reporters. The runner can be integrated into the build process so that the unit tests get executed automatically as a part of the build.

In this book, we will only concentrate on the Karma runner. The Webpack-based project setup needs the following Karma dependencies:

"devDependencies": {
...
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-matchers": "~3.7.0",
"karma-mocha-reporter": "~2.2.3",
"karma-phantomjs-launcher": "~1.0.4",
"karma-sourcemap-loader": "~0.3.7",
"karma-webpack": "~2.0.3",
"phantomjs-prebuilt": "~2.1.14"
}

Attentive readers will notice that we want to run tests against Google Chrome and PhantomJS (http://phantomjs.org)--a headless browser, which is perfect for testing web applications.

The complete project with instructions is available on GitHub at
https://github.com/ova2/angular-development-with-primeng/tree/master/chapter10/unit-testing.

The testing setup with Webpack and Karma requires three configuration files. First of all, we need a Karma configuration file: karma.config.js. This file will tell Karma where the tests are located, which browser(s) to use to execute the tests, which reporting mechanism to use, and so on. In the project on GitHub, this file has the following content:

let webpackConfig = require('./webpack.test.js');

module.exports = config => {
config.set({
autoWatch: false,
singleRun: true,
browsers: ['Chrome', 'PhantomJS'],
basePath: '.',
files: ['spec-bundle.js'],
exclude: [],
frameworks: ['jasmine', 'jasmine-matchers'],
logLevel: config.LOG_INFO,
phantomJsLauncher: {exitOnResourceError: true},
port: 9876,
colors: true,
preprocessors: {
'spec-bundle.js': ['webpack', 'sourcemap']
},
reporters: ['mocha'],
webpack: webpackConfig,
webpackServer: {noInfo: true}
});
};

Two important points should be mentioned here. There is a special Webpack configuration for tests, which is located in the webpack.test.js file. Its content is simple:

var ContextReplacementPlugin = require("webpack/lib/ContextReplacementPlugin");

module.exports = {
devtool: 'inline-source-map',
resolve: {extensions: ['.ts', '.js', '.json']},
module: {
rules: [
{test: /.ts$/, loaders: ['awesome-typescript-loader',
'angular2-template-loader']},
{test: /.json$/, loader: 'json-loader'},
{test: /.(css|html)$/, loader: 'raw-loader'}
]
},
plugins: [
new ContextReplacementPlugin(
/angular(\|/)core(\|/)@angular/,
path.resolve(__dirname, '../src')
)
]
};

The webpack.test.js doesn't specify entry points for files to be tested. The location and file extension for test files are defined in spec-bundle.js. This is another important file processed by Webpack. It loads Angular modules required for testing and initializes the test environment. At the end, all the test files are getting loaded in the browser. The content of the spec-bundle.js file is listed here:

require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('rxjs/Rx');

const coreTesting = require('@angular/core/testing');
const browserTesting = require('@angular/platform-browser-dynamic/testing');

// Initialize the test environment
coreTesting.TestBed.resetTestEnvironment();
coreTesting.TestBed.initTestEnvironment(
browserTesting.BrowserDynamicTestingModule,
browserTesting.platformBrowserDynamicTesting()
);

// Let the browser show a full stack trace when an error happens
Error.stackTraceLimit = Infinity;
// Let's set the timeout for the async function calls to 3 sec.
// (default is 5 sec.)
jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;

// Find all files with .spec.ts extensions
const context = require.context('../src/', true, /.spec.ts$/);

// For each file, call the context function that will require
//the file and load it up here.
context.keys().forEach(context);
The convention is to name your test file the same as the file it is testing, but with the suffix .spec before the file extension. For example, header.component.spec.ts and language.service.spec.ts. It is also the best practice to keep each test file in the same directory as the corresponding file under test.

In package.json, we can configure three convenient commands.

"scripts": {
...
"test": "karma start ./config/karma.conf.js",
"test:headless": "karma start ./config/karma.conf.js
--browsers PhantomJS",
"test:chrome": "karma start ./config/karma.conf.js
--browsers Chrome"
}

Now, we are ready to run our tests using one of the three commands. When we execute npm run test, Karma will open and close each configured browser and print the test results.

When using the Angular CLI, it handles the configuration for us. You don't need to write any configuration files and can quickly run all tests by typing ng test in our project root. This command watches for changes and reruns the tests automatically.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.159.223