Github: https://github.com/railsstudent/image-gallery-native-js
1) Install gulp, mocha, chai, puppeteer, http-server as dev-dependencies
yarn add gulp mocha chai puppeteer http-server -D
2) Install all karma dependencies as dev-dependencies.
yarn add karma karma-chai karma-mocha karma-chrome-launcher mocha chai -D
3) Create test/bootstrap.karma.js file to share global variables among unit test cases.
'use strict';
const expect = chai.expect;
const assert = chai.assert;
4) Run karma command to generate karma.conf.js to specify Karma configuration.
./node_modules/.bin/karma init
// Karma configuration
// Generated on Sun Aug 26 2018 09:31:46 GMT+0800 (HKT)
process.env.CHROME_BIN = require('puppeteer').executablePath();
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
plugins: [
"karma-chai",
"karma-chrome-launcher",
"karma-mocha",
"karma-coverage"
],
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai'],
// list of files / patterns to load in the browser
files: [
'src/**/*.js',
'test/bootstrap.karma.js',
'test/**.test.js'
],
// list of files / patterns to exclude
exclude: [
'test/gallery.test.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/**/!(gallery).js': 'coverage'
},
// optionally, configure the reporter
coverageReporter: {
type : 'lcov',
dir : 'coverage/',
subdir: '.'
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage'],
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['ChromeHeadless'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
})
}
Explicitly list karma plugins for chai, browser launcher, mocha and code coverage.
plugins: [
"karma-chai",
"karma-chrome-launcher",
"karma-mocha",
"karma-coverage"
]
Include mocha and chai required by the unit test cases.
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai'],
Load src/, test/bootstrap.karma.js and test/**/*.test.js in browser. Exclude test/gallery.test.js since this test file contains automated UI test cases
// list of files / patterns to load in the browser
files: [
'src/**/*.js',
'test/bootstrap.karma.js',
'test/**.test.js'
],
// list of files / patterns to exclude
exclude: [
'test/gallery.test.js'
]
Use Chromium instance of puppeteer to execute headless browser test
process.env.CHROME_BIN = require('puppeteer').executablePath();
browsers: ['ChromeHeadless'],
Add lcov code coverage. Code coverage results are kept in coverage/lcov-report directory
preprocessors: {
'src/**/!(gallery).js': 'coverage'
},
// optionally, configure the reporter
coverageReporter: {
type : 'lcov',
dir : 'coverage/',
subdir: '.'
}
Add reporters for headless browser testing and code coverage
reporters: ['progress', 'coverage']
5) Install gulp-karma to integrate karma with gulp
yarn add gulp-karma -D
Add gulp test task to run karma test runner
/**
* Run test once and exit
*/
gulp.task('test', function (done) {
new KarmaServer({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, done).start();
});
6) Set up npm script commands in package.json.
"scripts": {
"test": "gulp test",
"serve:coverage": "gulp test && http-server coverage/lcov-report/ -p 8001"
}
Test unit test cases in headless browser
yarn test
Serve lcov code coverage results at http://localhost:8001
yarn serve:coverage
7) Write mocha test case in test file.
'use strict';
describe('slideshow test', function() {
let first, middle;
let imageUrls = [];
let slideshow = null;
before(function() {
first = 0;
middle = 1;
});
describe('single image slideshow', () => {
before(function() {
// runs before all tests in this block
imageUrls = [
'image1.jpg'
];
slideshow = new SlideShow(imageUrls);
slideshow.setCurrentIndex(first);
});
it('slideshow has 1 image', function() {
assert.strictEqual(slideshow.totalCount(), imageUrls.length);
});
it('current url should be the first url', function() {
assert.strictEqual(slideshow.currentUrl(), 'image1.jpg');
});
it('initial index is always 0', function() {
assert.strictEqual(slideshow.currentIndex(), first);
});
it('Slide show with 1 image is always the first image', function() {
assert.strictEqual(slideshow.isFirstImage(), true);
});
it('Slide show with 1 image is always last image', function() {
assert.strictEqual(slideshow.isLastImage(), true);
});
it('Show next image does nothing when there is 1 image', function() {
assert.strictEqual(slideshow.showNext(), false);
assert.strictEqual(slideshow.currentIndex(), first);
});
it('Slide prev image with 1 image is always last image', function() {
assert.strictEqual(slideshow.showPrev(), false);
assert.strictEqual(slideshow.currentIndex(), first);
});
});
});
Finally, we are done.