Thanks to visit codestin.com
Credit goes to www.slideshare.net

Continuous Integration
for front-end JavaScript
Lars Thorup
ZeaLake Software Consulting


April, 2013
Who is Lars Thorup?

●   Software developer/architect
     ●   JavaScript, C#
     ●   Test Driven Development
     ●   Continuous Integration

●   Coach: Teaching agile and
    automated testing

●   Advisor: Assesses software
    projects and companies

●   Founder of ZeaLake
Continuous Integration
 Code                       CI-server                     Results
 function createBoard() {
   ...
 }                                      static analysis
                                                              errors

                                         test runner
 Tests
 test('createBoard', {
    ...                                                      coverage
                                   coverage analysis
 });


                                         minification      distributables
GruntJS
●   Command line             ●   Good support for
     ●   NodeJS                   ●   RequireJS
                                  ●   CoffeeScript
●   Static analysis
     ●   JSHint              ●   Lots of other plugins

●   Run tests in PhantomJS   ●   Popular and actively
     ●   QUnit                   developed
     ●   Jasmine
     ●   and others

●   Code Coverage
     ●   Istanbul
     ●   Blanket
src/test/code.test.js
 describe('durationInEnglish', function () {

       it('should return "now" when duration is 0', function () {
           expect(durationInEnglish(0)).toBe('now');
       });

       it('should return "x seconds ago" when ...', function () {
           var now = new Date(2013, 04, 19, 11, 00, 17);
           var then = new Date(2013, 04, 19, 11, 00, 00);
           expect(durationInEnglish(now - then)).toBe('17 seconds ago');
       })

 });
src/js/code.js

 function durationInEnglish(milliseconds) {
     var seconds = milliseconds / 1000;
     if(seconds === 0) {
         return 'now';
     } else if(seconds < 60) {
         return seconds + ' seconds ago';
     } else {
         return 'whenever';
     }
 }
package.json

 {
     "name": "gruntdemo",
     "version": "0.1.1-1",
     "devDependencies": {
         "grunt-cli": "0.1.6",
         "grunt": "0.4.1",
         "grunt-contrib-jshint": "~0.1.1",
         "grunt-contrib-jasmine": "0.4.1",
         "grunt-template-jasmine-istanbul": "0.2.0"
     }
 }



                              >npm install
Gruntfile.js

 module.exports = function (grunt) {
     var gruntConfig = {};

      // task definitions
      ...

      // grunt
      grunt.initConfig(gruntConfig);
 };
Gruntfile.js - jshint
 grunt.loadNpmTasks('grunt-contrib-jshint');
 gruntConfig.jshint = {
     all: [
         '*.js',
         'src/**/*.js'
     ]
 };




                                 >grunt jshint
                                 Running "jshint:all" (jshint) task
                                 >> 3 files lint free.
Gruntfile.js - jasmine
 grunt.loadNpmTasks('grunt-contrib-jasmine');
 gruntConfig.jasmine = {
     src: {
         src: [
             'src/js/**/*.js'
         ],
         options: {
             specs: 'src/test/**/*.test.js',
             junit: {
                 path: 'output/testresults'
             }
         }
     }                            >grunt jasmine:src
 };                               Running "jasmine:src" (jasmine) task
                                  Testing jasmine specs via phantom
                                  ..
                                  2 specs in 0.109s.
                                  >> 0 failures
Gruntfile.js - istanbul
gruntConfig.jasmine.istanbul = {
    src: gruntConfig.jasmine.src.src,
    options: {
        specs: gruntConfig.jasmine.src.options.specs,
        template: require('grunt-template-jasmine-istanbul'),
        templateOptions: {
            coverage: 'output/coverage/coverage.json',
            report: [
                {type: 'html', options: {dir: 'output/coverage'}},
                {type: 'text-summary'}
            ]
        }                 >grunt jasmine:istanbul
                          Running "jasmine:istanbul" (jasmine) task
    }
                          Testing jasmine specs via phantom
};
                          ..
                          ========== Coverage summary ===========
                          Statements    : 85.71% ( 6/7 )
                          Branches      : 75% ( 3/4 )
                          Functions     : 100% ( 1/1 )
                          Lines         : 85.71% ( 6/7 )
                          =======================================
Coverage report
Coverage details
Jenkins job
Jenkins report

Continuous Integration for front-end JavaScript

  • 1.
    Continuous Integration for front-endJavaScript Lars Thorup ZeaLake Software Consulting April, 2013
  • 2.
    Who is LarsThorup? ● Software developer/architect ● JavaScript, C# ● Test Driven Development ● Continuous Integration ● Coach: Teaching agile and automated testing ● Advisor: Assesses software projects and companies ● Founder of ZeaLake
  • 3.
    Continuous Integration Code CI-server Results function createBoard() { ... } static analysis errors test runner Tests test('createBoard', { ... coverage coverage analysis }); minification distributables
  • 4.
    GruntJS ● Command line ● Good support for ● NodeJS ● RequireJS ● CoffeeScript ● Static analysis ● JSHint ● Lots of other plugins ● Run tests in PhantomJS ● Popular and actively ● QUnit developed ● Jasmine ● and others ● Code Coverage ● Istanbul ● Blanket
  • 5.
    src/test/code.test.js describe('durationInEnglish', function() { it('should return "now" when duration is 0', function () { expect(durationInEnglish(0)).toBe('now'); }); it('should return "x seconds ago" when ...', function () { var now = new Date(2013, 04, 19, 11, 00, 17); var then = new Date(2013, 04, 19, 11, 00, 00); expect(durationInEnglish(now - then)).toBe('17 seconds ago'); }) });
  • 6.
    src/js/code.js function durationInEnglish(milliseconds){ var seconds = milliseconds / 1000; if(seconds === 0) { return 'now'; } else if(seconds < 60) { return seconds + ' seconds ago'; } else { return 'whenever'; } }
  • 7.
    package.json { "name": "gruntdemo", "version": "0.1.1-1", "devDependencies": { "grunt-cli": "0.1.6", "grunt": "0.4.1", "grunt-contrib-jshint": "~0.1.1", "grunt-contrib-jasmine": "0.4.1", "grunt-template-jasmine-istanbul": "0.2.0" } } >npm install
  • 8.
    Gruntfile.js module.exports =function (grunt) { var gruntConfig = {}; // task definitions ... // grunt grunt.initConfig(gruntConfig); };
  • 9.
    Gruntfile.js - jshint grunt.loadNpmTasks('grunt-contrib-jshint'); gruntConfig.jshint = { all: [ '*.js', 'src/**/*.js' ] }; >grunt jshint Running "jshint:all" (jshint) task >> 3 files lint free.
  • 10.
    Gruntfile.js - jasmine grunt.loadNpmTasks('grunt-contrib-jasmine'); gruntConfig.jasmine = { src: { src: [ 'src/js/**/*.js' ], options: { specs: 'src/test/**/*.test.js', junit: { path: 'output/testresults' } } } >grunt jasmine:src }; Running "jasmine:src" (jasmine) task Testing jasmine specs via phantom .. 2 specs in 0.109s. >> 0 failures
  • 11.
    Gruntfile.js - istanbul gruntConfig.jasmine.istanbul= { src: gruntConfig.jasmine.src.src, options: { specs: gruntConfig.jasmine.src.options.specs, template: require('grunt-template-jasmine-istanbul'), templateOptions: { coverage: 'output/coverage/coverage.json', report: [ {type: 'html', options: {dir: 'output/coverage'}}, {type: 'text-summary'} ] } >grunt jasmine:istanbul Running "jasmine:istanbul" (jasmine) task } Testing jasmine specs via phantom }; .. ========== Coverage summary =========== Statements : 85.71% ( 6/7 ) Branches : 75% ( 3/4 ) Functions : 100% ( 1/1 ) Lines : 85.71% ( 6/7 ) =======================================
  • 12.
  • 13.
  • 14.
  • 15.