I use Windows so these instructions are for windows developers
-
Install Node
cinst nodejs.install
Node is the tooling that allows you to run javascript code outside the browser. -
Install NPM
cinst npm
For .NET developers, npm can be thought of as the Node-equivalent of nuget. Node javascript libraries are shared using npm.
You may have to restart your console program for these changes to take effect.
-
Install the grunt command-line interface.
npm install -g grunt-cli
Grunt is a task runner (think Ant, Nant, or rake) for Node packages. The -g argument installs grunt globally (as against locally in your project). We're going to use grunt to execute our unit tests. -
Create a default grunt profile.
npm install -g grunt-init $path = [System.IO.Path]::Combine($env:UserProfile, ".grunt-init/gruntfile") git clone https://github.com/gruntjs/grunt-init-gruntfile.git $path
This part is a bit janky. Basically it just installs default configuration for grunt into your user's home directory on Windows.
-
In your solution root
npm init
Just accept the default options. Since we are not publishing a node library none of the this meta-data really matters. We just need npm to recognize the solution as a node application. -
Edit your .gitignore
# Logs logs *.log # Runtime data pids *.pid *.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directory # Deployed apps should consider commenting this line out: # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git node_modules
-
Configure the project for grunt
npm install grunt-init
Is the DOM involved in ANY way? Answer yes.
Answer as you see fit to the rest of the questions.
-
Install karma
npm install karma --save-dev npm install -g karma-cli
Karma is a unit test runner and reporting engine. -
Initialize karma
karma init
Which testing framework do you want to use ? Press tab to list possible options. Enter to move to the next question.
jasmine
Do you want to use Require.js ? This will add Require.js plugin. Press tab to list possible options. Enter to move to the next question.
yes
Do you want to capture any browsers automatically ? Press tab to list possible options. Enter empty string to move to the next quest
Chrome
PhantomJS
What is the location of your source and test files ? You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js". Enter empty string to move to the next question.
Should any of the files included by the previous patterns be excluded ? You can use glob patterns, eg. "**/*.swp". Enter empty string to move to the next question.
Do you wanna generate a bootstrap file for RequireJS? This will generate test-main.js/coffee that configures RequireJS and starts the
yes
Do you want Karma to watch all the files and run the tests on change ? Press tab to list possible options.
yes
-
Edit karma.conf
// list of files / patterns to load in the browser files: [ 'test-main.js', { pattern: 'Demo-LendingTracker.Tests/**/*.js', included: false }, { pattern: 'Demo-LendingTracker/Scripts/app/**/*.js', included: false} ], // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['PhantomJS'],
You can verify that your default karma configuration is correct by running karma start. If you start adding files to the monitored js folders karma should detect the changes.It's important to specify included: false on the js files since we are going to load them using requirejs.
-
Edit test-main.js
var allTestFiles = []; var TEST_REGEXP = /(spec|tests)\.js$/i; var pathToModule = function (path) { return path; return path.replace(/^\/base\//, '').replace(/\.js$/, ''); }; Object.keys(window.__karma__.files).forEach(function (file) { if (TEST_REGEXP.test(file)) { // Normalize paths to RequireJS module names. allTestFiles.push(pathToModule(file)); } }); require.config({ // Karma serves files under /base, which is the basePath from your config file baseUrl: '/base/Demo-LendingTracker/Scripts', // dynamically load all test files deps: allTestFiles, paths: { "bootstrap": 'bootstrap', "tests": "/base/Demo-LendingTracker.Tests", "jquery": "jquery-2.1.1", 'ko': 'knockout-3.2.0', "PubSub": '//cdn.jsdelivr.net/pubsubjs/1.4.2/pubsub.min' }, shim: { bootstrap: ["jquery"], ko: { exports: 'ko' }, PubSub: { exports: 'PubSub' } }, // we have to kickoff jasmine, as it is asynchronous callback: window.__karma__.start });
-
Install grunt-karma
npm install grunt-karma --save-dev
-
Edit the grunt file
watch: { karma: { files: [ 'Demo-LendingTracker/Scripts/app/**/*.js', 'Demo-LendingTracker.Tests/**/*js' ], tasks: ['karma:unit'] }, gruntfile: { files: '<%= jshint.gruntfile.src %>', tasks: ['jshint:gruntfile'] }, jshint: { files: '<%= jshint.lib_test.src %>', tasks: ['jshint:lib_test'] } }
});
// These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-karma');
// Default task. grunt.registerTask('default', ['watch']);
-
Add the karma task to the gruntfile beneath the jshint task
karma: { unit: { configFile: "karma.conf.js", singleRun: true, autoWatch:false, browsers: ['PhantomJS'] }, teamcity: { configFile: "karma.conf.js", singleRun: true, browsers: ['PhantomJS'], reporters: ['progress', 'teamcity'] }, ci: { configFile: "karma.conf.js", autoWatch: true }, debug: { configFile: "karma.conf.js", autoWatch: true, browsers: ['PhantomJS', 'Chrome'] } },
-
Our Grunt watch task has some dependencies, so we need to make sure everything is installed.
npm install
-
At this point you should be able to watch your js files for changes and get real-time feedback via grunt.
grunt