AzureDevOps CI to Build and Test Node.js app with Gulp and Mocha

Build Report

In this post, we will see how to configure Azure DevOps (formerly, Visual Studio Team Services (VSTS)) Continuous Integration (CI) Build for Node.js application. This post is extension of my previous post, where I’ve covered Setting up node application with TypeScript in VS Code  —  using mocha, chai, mochawesome, gulp, travis 

If you are looking for setting up node project with TypeScript, Gulp and Mocha, first refer previous post and then continue below for configuring VSTS CI build for Node.js app with Gulp and Mocha tests. In below post, we’ll import existing project from Github to VSTS and then configure VSTS CI build using web only steps.

If you are already using VSTS for your team project, directly start from step 3 below.

Note: The entire VS Code project used in this post is available at GitHub.

Prerequisites

Let’s get started!

1. Create new project in VSTS

  • Start with creating new Project.
VSTS Create New Project

2. Import Github project to VSTS

  • Select import existing project from Github. (since I have existing project in Github I’m importing existing project, otherwise we can start with creating empty project and add necessary project files.)
Import Git Repo
  • Now go to Code tab, see all project code is now imported to our newly created VSTS team project.
Imported Project

3. Configure CI build for project

3.1 Create New Build Definition for project

  • Go to Build and Release >> Build tab and create new build definition. (Click +New)
  • I have already created one, hence you can see one definition already exist in below screen. If you are creating for the first time, there won’t be any build definition present.
Create Build Definition

3.2. Select NodeJS with Gulp template

  • Upon clicking +New on the page, you can either choose to start with an empty process or select an template. VSTS gives us varieties of templates. For node application, VSTS gives two templates: NodeJS with Grunt and NodeJS with Gulp. Let’s select NodeJS with Gulp.
Nodejs task in CI

3.3. Start with build process

  • Name the build definition. (Keep remaining things as default)
Build Definition Name

3.4. Select project repository and branch for which configuring build

  • Since we have already imported project from Github to VSTS, we’ll choose This project. And also choose repository and branch for which we are configuring CI.
Select Source for CI

3.5. npm install

  • Now that we have selected which resources to be built (project, repo, branch etc), we’ll have to configure steps for build the project. We can have multiple phases in build and each phases can have multiple tasks. For simplicity let’s have single Phase i.e. Phase 1 which will have all the tasks to get the build and tests run.
  • Since we have used VSTS template NodeJS with Gulp, we can see npm install and Gulp are already added under Phase 1. Remaining tasks can be added simply by + icon next to Phase 1.
  • Let’s configure npm install. As shown in below screen configure display name, command and working folder with package.json. (Remember: Don’t pick path of package.json, but pick a path to package.json’s parent folder. If package.json is at root folder, just use current directory: .)
npm install task

3.6. Run gulp task

  • Second step in build would be gulp task configuration. Pick path to gulpfile.js and mention the task name to be run as part of build. Leave blank in task name if you want to run gulp default task.
gulp task

3.7. npm test

  • npm test should run all mocha tests as part of the build. Also to see mocha tests report in VSTS build report, you need to use mocha-junit-reporter. (Yes, we are not talking about Java. It’s javascript/typescript tests in mocha.)
  • Configure mocha tests to run as part of npm test as shown below. Refer complete file: package-vsts.json
  • Add mocha-junit-reporter dependency in package.json
"mocha-junit-reporter": "^1.17.0"
  • Add test script to run mocha tests with mocha-junit-reporter in package.json
  • Below will run all mocha tests under lib/test/ directory and test report will be saved in file: ./TestResults/TEST-RESULT.xml in junit report format.
"scripts": {
     "test": "mocha lib/test/**/*.js --reporter mocha-junit-reporter --reporter-options     mochaFile=./TestResults/TEST-RESULT.xml"
}
npm test task

3.8. Publish Mocha Test Results

  • Now that npm test will run mocha tests and get the reports in JUnit format in file ./TestResults/TEST-RESULT.xml, let’s add a task to publish Mocha Test Results. (Click on + next to phase 1 and search for Publish Mocha Test Results)
  • Configure Publish Mocha Test Results task as shown below, and save the build definition.
    • Test result format should be: JUnit
    • Test results files should match the pattern/fileName given in mocha test run command, for our example: **\TEST-RESULT.xml
Publish Test Results Task

4. Trigger a build

  • Click on Queue new build after saving build definition.
Queue Build

5. See Build summary

  • Once build has ran successfully, we can see below screen as build summary report. (Click on each step for detailed logs etc)
Build Report
  • Click on Tests tab to see details about test report. (By default only Failed tests will be displayed. To see all tests, click on Outcome:ALL)
Test Report
  • Build runs summary for given build definition – shows builds history summary at glance (Go to Build and Release >> Builds >> Select build definition)
Build History

6. Summary

  • This post covered VSTS CI configuration for Node.js app with Gulp and Mocha. Refer Microsoft’s documentation at link for this topic.
  • VSTS can also be used as Continuous Delivery or Continuous Deployment which is not covered in this post. Refer this link for Continuous Deployment (CD) using Release Definitions.

Please share your thoughts using comments on this post. Also let me know if there are particular things that you would enjoy reading further. Please feel free to connect me @nilaydshah.

Setting up node application with TypeScript in VS Code  —  using mocha, chai, mochawesome, gulp, travis

VSCode DebugAddTest

In this post we are going to learn how to configure a TypeScript + VS Code development environment. Perform unit testing with Mocha and Chai. Configure VS Code to perform build task using gulp and then launch mocha tests. Configure Travis CI to enable continuous integration build/test on your github repo. We are going to use the following tools and technologies:

  • TypeScript
  • VS Code
  • Mocha
  • Chai
  • Mochawesome
  • Gulp
  • Travis CI

Let’s get started!

Note: The entire VS Code project used in this post is available at GitHub.

1. Download and install VS Code and some extensions

  • Install VS Code from: https://code.visualstudio.com/
  • Install these VS Code extensions: 1) npm 2) npm intellisense 3) mocha sidebar
  • Create project root folder and open that from VS Code
> code . // This opens VS code from current folder

2. Creating node application

> npm init // This will generate default package.json file
  • Add necessary dependencies in package.json and do npm install
 "dependencies": {
"typescript": "^2.6.1"
},
"devDependencies": {
"@types/chai": "^4.0.5",
"@types/mocha": "^2.2.44",
"chai": "^4.1.2",
"del": "^3.0.0",
"gulp": "^3.9.1",
"gulp-typescript": "^3.2.3",
"mocha": "^4.0.1",
"mochawesome": "^2.3.1"
}

3. Add Typescript source and test files

  • First install typescript globally, so that tsc cli would be available
> npm install -g typescript // This will install typescript globally
> tsc --init // This will generate default tsconfig.json
tsconfig.json {
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./lib"
}
}
  • Now let’s add HelloWorld.ts and HelloWorld.test.ts
  • Notice that, we are not using node basic assertion framework, instead we are using Chai for assertion. You can use either ‘should’ or ‘expect’ module from ‘chai’ for assertion. I used ‘should’ as that just aligns with natural language!
HelloWorld And HelloWorldTest
HelloWorld And HelloWorldTest

HelloWorld.ts 
export class HelloWorld {
public helloWorld() : string {
return 'Hello World'
}
}
export default HelloWorld;
HelloWorld.test.ts 
import { should } from 'chai';
import { HelloWorld } from '../src/HelloWorld';
should();
describe('Hello World test suite', function() {
it('Can say Hello World', function() {
const result = new HelloWorld().helloWorld();
result.should.equals('Hello World', `Should return: Hello World, but returned: ${result}`);
});
});
Calc And CalcTest
Calc And CalcTest
Calc.ts 
export class Calc {
public add(num1: number, num2: number) : number {
return num1 + num2;
}
public subtract(num1: number, num2: number) : number {
return num1 - num2;
}
}

export default Calc;
Calc.test.ts
import { should } from 'chai';
import { Calc } from '../src/Calc';
should();

describe('Calc test suite', function() {
let calc = new Calc();
it('Can add', function() {
let result = calc.add(5,5);
result.should.equals(10, `Should return: 10, but returned: ${result}`);
});
it('Can subtract', function() {
let result = calc.subtract(20,10);
result.should.equals(10, `Should return: 10, but returned: ${result}`);
});
});

4. Build and run base project which includes TypeScript + Mocha + Chai + Mochawesome

  • Build TypeScript project with tsc from project root folder
> tsc // This will compile typescripts based on tsconfig.json
  • Alternatively, you can use VS Code: Ctrl + Shift + B and pick tsc:build
VSCode tsc
VSCode tsc
  • Optionally, install mocha globally so that we can run mocha cli
> npm install -g mocha // This will install mocha globally
  • Run mocha tests with mocha or npm test supply mochawesome as reporter argument.
    • Running tests with mocha
      • mocha lib/test/**/*.js –reporter mochawesome –reporter-options reportDir=TestResults
    • Running tests with npm test, (Make sure your package.json contains above as test script)
      • npm test
    • Running tests with mocha sidebar VS Code extension
      • Add below workspace settings.json to enable discovery of our test path by mocha sidebar
      • “mocha.files.glob”: “lib/test/**/*.js” // Use Ctrl + , to edit settings
      • Now we can see our tests under Mocha in side bar. We can debug / run our tests right from there. We can choose selectively single test or run all tests.
VSCode DebugAddTest
VSCode DebugAddTest
  • Running tests with VS Code launch.json
    • We can configure VS Code tasks.json and launch.json and run the same tests with just F5. Will cover that later in the same post after adding gulp support.
  • Let’s see how Mochawesome test report looks like,
Mochawesome ReportDetails
Mochawesome ReportDetails

5. Add Gulp tasks to clean and build project

  • First install gulp-cli globally
> npm install -g gulp-cli // This will add gulp cli globally
  • Add gulpfile.js and add necessary tasks. For example,  task to clean lib folder and TypeScript compile. We can also add more relevant tasks in gulp such as tslint, copy source to remote, uglify.minify and so on.
gulpfile.js 
"use strict";
var gulp = require('gulp');
var ts = require('gulp-typescript');
var del = require('del');
var tsProject = ts.createProject("tsconfig.json");

// task to clean all files in lib (which is out folder for containing all javascripts)
gulp.task("clean:lib", function() {
return del(['lib/**/*']); }); // task to build(transpile) all typescripts into javascripts in lib folder
gulp.task("tsc", function () {
return tsProject.src()
.pipe(tsProject())
.js.pipe(gulp.dest("lib"));
});

// adding default tasks as clean and build
gulp.task('default', ['clean:lib','tsc'], function () {
});
  • Now let’s run this task from VS Code by Ctrl + Shift + B. This will run both ‘clean:lib’ and ‘tsc’ tasks.
GulpFile And GulpRun
GulpFile And GulpRun
  • Now, let’s see how to enable F5 run for the same in VS Code.

6. Configure tasks.json and launch.json to enable F5 run in VS Code

  • We need two things to run mocha tests from VS Code launch
    1. preLaunchTask
    2. program to launch mocha tests
  • Let’s configure preLaunchTask as gulp default task in tasks.json
tasks.json 
{
"version": "2.0.0",
"tasks": [
{
"label": "gulp",
"type": "gulp",
"task": "default",
"problemMatcher": []
}
]
}
  • Let’s configure mocha (with necessary arguments) as launch program in launch.json
  • We can add multiple configurations as we need. For example, one configuration to launch all mocha tests, whereas another configuration to launch specific tests with mocha grep argument.
launch.json 
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch All Mocha Tests",
"preLaunchTask": "gulp",
"cwd": "${workspaceRoot}",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u", "tdd",
"--no-timeouts",
"--colors",
"--reporter", "mochawesome",
"--reporter-options", "reportDir=TestResults",
"${workspaceFolder}/lib/test" //you can specify paths to specific tests here
],
"internalConsoleOptions": "openOnSessionStart"
}
]
  • We are ready to launch. Hit F5.
CalcTest And HelloWorldTest
CalcTest And HelloWorldTest
  • By this time we should have following global and local node dependencies. Below are the commands to list global and local node dependencies.
> npm list -g --depth=0 // This lists global installed node dependencies 
> npm list --depth=0 // This lists local (project-specific) node dependencies
NpmGlobal And Local Dependencies
NpmGlobal And Local Dependencies
  • Now let’s configure CI for our repo. So every time there’s new check-in or PR to master branch, we can trigger build and tests automatically.

7. Configure continuous integration with Travis CI

  • To configure continuous integration for your github.com repository, you need to add Travis CI service from your Repo > Integrations & Services tab.
Github Travis Configuration
Github Travis Configuration
  • Once you add Travis CI as your service, you will need to define what language of application are you building and what are the steps to build the application. So accordingly, Travis will provide the RunTime environment. For our example, it is node application and our build sequence consist of 3 steps: 1) npm install 2) gulp task 3) npm test.
  • To configure these, add .travis.yml file in the project.
.travis.yml 
language: node_js
node_js:
- "4"
before_script:
- npm install -g gulp-cli
script:
- gulp
- npm test
  • Now we are ready to request build. (At every check-in for particular branch Travis will trigger automated build.) We can see the build status at Travis CI Build URL
TravisCI Current Build Pass
TravisCI Current Build Pass
  • From the Travis job logs we can see what’s passed (and what’s failed too)
TravisCI Test Pass ConsoleLog
TravisCI Test Pass ConsoleLog
  • Check your repo build history
TravisCI Build Pass2
TravisCI Build Pass2

8. Summary

  • In this post we have covered multiple topics at breadth level. At each topic there is a lot to cover. After following all above steps, we will be getting following project/files structure in VS Code.
VSCode Project Structure
VSCode Project Structure

As already mentioned, The entire VS Code project used in this post is available at GitHub.

It’s been a long post, but I hope you found it useful. Let me know your feedback and suggestion on this post.

Did this work for you?

Could I have done something better?

Have I missed something?

Any queries regarding topics covered in the post?

Please share your thoughts using comments on this post. Also let me know if there are particular things that you would enjoy reading further. Please feel free to connect me @nilaydshah.