This is the first blog in a series of two blogs about Karma testing (with code coverage) for Oracle JET. This first blog will help you with setting up the files in the project to get karma up and running. The second blog can be found here and will show you how to actually test your code in the viewModels.
Start a new project.
First we start our new Oracle JET project following the example on the Oracle JET website.
npm install -g bower grunt grunt-cli yo npm install generator-oraclejet yo oraclejet ojet-karma-test --template=navdrawer
Now check if your project is working by running:
grunt build grunt serve
Next step is to add all the npm modules for karma, jasmine and supporting coverage reports.
npm install -g karma karma-cli npm install karma karma-jasmine jasmine-core karma-coverage --save-dev
Add a directory named test, this is where the testfiles will be. Add a file named test-main.js in the directory and leave it empty for now.
Karma Configuration.
Go back to the main directory of your project. Next step is to make the configurations for karma, I do this using
karma init
The framework we are using is Jasmine, we do need the Require.js plugin so answer yes for that question. I use Chrome as a browser but you can pick whatever browser you like. All the other questions I left empty or answered with “no”.
Open the karma.conf.js and add the libraries, viewModel, testfiles and the test-main file to files.
files: [ {pattern: 'js/libs/**/*.js', included: false}, {pattern: 'src/js/viewModels/*.js', included: false}, {pattern: 'test/*Spec.js', included: false}, 'test/test-main.js' ],
Exclude the main.js file
exclude: [ 'src/js/main.js', ],
To have karma coverage replace the preprocessor with:
preprocessors: { 'src/js/viewModels/*.js':['coverage'] },
Add a coverage reporter.
coverageReporter:{ type:'html', dir:'reports/coverage' },
And add coverage to the reporter:
reporters: ['progress','coverage'],
Your karma config will now look like this:
module.exports = function(config) { config.set({ basePath: '', frameworks: ['jasmine', 'requirejs'], files: [ {pattern: 'src/js/libs/**/*.js', included: false}, {pattern: 'src/js/viewModels/*.js', included: false}, {pattern: 'test/*Spec.js', included: false}, 'test/test-main.js' ], exclude: [ 'src/js/main.js', ], preprocessors: { 'src/js/viewModels/*.js':['coverage'] }, reporters: ['progress','coverage'], coverageReporter:{ type:'html', dir:'reports/coverage' }, port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: false, browsers: ['Chrome'], singleRun: true, concurrency: Infinity }) }
Setting up test-main.js
Let’s head back to our test-main.js, this is where the Karma Require.JS magic happens, this is where we load the modules needed for testing.
var tests = []; var modules = []; var SPEC_REGEXP = /Spec\.js$/; var VIEWMODEL_REGEXP = /viewModels\//; var JS_REGEXP = /\.js$/; var jsToModule = function (path) { return path.replace(/^\/base\/src\/js\//, '').replace(/\.js$/, ''); }; for (var file in window.__karma__.files) { if (window.__karma__.files.hasOwnProperty(file)) { if (SPEC_REGEXP.test(file)) { tests.push(file); } else if (VIEWMODEL_REGEXP.test(file) && JS_REGEXP.test(file)) { modules.push(jsToModule(file)); } } } var startTest= function(){ //Load the modules before calling karma start. require(modules, function () { window.__karma__.start() }) } requirejs.config({ baseUrl: '/base/src/js', paths: { 'knockout': 'libs/knockout/knockout-3.4.0.debug', 'jquery': 'libs/jquery/jquery-3.1.0', 'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.12.0', 'promise': 'libs/es6-promise/es6-promise', 'hammerjs': 'libs/hammer/hammer-2.0.8', 'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0', 'ojs': 'libs/oj/v2.1.0/debug', 'ojL10n': 'libs/oj/v2.1.0/ojL10n', 'ojtranslations': 'libs/oj/v2.1.0/resources', 'text': 'libs/require/text', 'signals': 'libs/js-signals/signals' }, shim: { 'jquery': { exports: ['jQuery', '$'] } }, deps: tests, callback: startTest });
This is a bit more elaborate than the standard test-main file used for Require.JS and Karma. The modules that we are testing will be loaded by Require.JS in the testfiles. We use the StartTest function to load the modules where we want test coverage on (everything in the viewmodel folder in this case) with Require.JS before the testing start. If we do not do this, we will not get coverage on files that do not have a test file.
Run karma.
Time to see if karma is running!
Run the following in the terminal / console:
karma start
When the tests are done there should be a folder called reports in your project. Open de index.html to view the code coverage of your viewModels folder. Click on the links to see more detailed information about which code is covered and which is not.
The code mentioned in this blog can also be found on my Github Account, with a bit more comments in the code to clear things up.
Part two is available as well: Part two
Resources:
http://www.bradoncode.com/blog/2015/02/27/karma-tutorial/
https://karma-runner.github.io/0.8/plus/RequireJS.html
http://stackoverflow.com/questions/26850684/karma-coverage-requirejs-misleading-coverage-reports
Hi,
I am getting 404 error for this pattern:
‘src/js/libs/**/*.js’
This makes sense since there is no libs folder under /src/js/ directory.
Am I missing something?
Thanks