Why Unit Testing?

Throughout my career in the software development industry, unit testing has been a practice that I have known about, somewhat understood the benefits, but never had a real opportunity to practice.  When you are a part of a small development team and you are looking for ways to deliver value to your customers more quickly, skipping unit testing “feels” like you are doing the right thing.  But if your project becomes more successful, more complicated, and your team grows, not having unit tests becomes risky and costly.

Unit testing is a software testing approach by which a unit of work within your source code is tested to determine if it functions properly.  You can think of a unit (unit of work) as the smallest testable part of your code.  A unit test is code a developer creates to test a unit.  It is basically code written to test code.  For example, let’s say some code has a function that accepts an array of numbers and returns the sum of the values.  Several unit tests (code) can be written to test the function by providing arrays of known values as input and comparing the result to the known sum of the of the values in the input array.  If the sum returned by the function matches the known sum, the unit test passes.  So big deal, the function can correctly calculate the sum of the values in an input array.  What’s the value in creating unit tests for that?  

Well let’s expand our thinking for a moment.  You have an idea that might improve the efficiency of the function by 10x and it requires that you refactor how the function sums the values of the input array.  Let’s make this a little more interesting and assume you are not the original author of the function and the output of the function should be the same as before your refactor.  Without unit tests in place, how do you determine if the function is still working correctly after your refactor? In this scenario is where unit testing adds tremendous value.

There are a couple of items in this scenario that contribute to increased risk and cost.  All non-trivial applications/libraries will have code refactored at some point which introduces risk.  Without unit testing, the only way to ensure that code continues to function correctly after refactoring is to perform manual testing and in some scenarios the code that was refactored can only be tested indirectly as a part of a larger operation.  This leads to increased cost because resources (developers/testers) have to be allocated to a manual testing effort and human resources are the most expensive part of any business.  In addition, this manual testing effort requires time which delays the delivery of value to the end users.

Returning to our scenario, let’s assume there were unit tests available and the tests were setup to execute as a part of the build process.  After the refactor, you rebuild the code which kicks off the execution of the unit tests.  Almost instantaneously you will get feedback on your code changes.  Assuming that the unit tests are correctly testing the function (big assumption) and the unit tests are still passing after your refactor, you can be fairly confident that you have not introduced errors.  This does not eliminate the need for all manual testing but it is safe to conclude that the manual testing efforts can be minimized and the unit testing has reduced, not eliminated, risks and cost.

Based on my view of the software development world, I would say that most development shops do not actively use unit testing as a tool to mitigate risk and cost.  To the inexperienced, unit testing is overhead in the software development process that can be eliminated to deliver value to users faster.  But what happens when the “overhead” is eliminated for years, the project has become more complicated, and more software developers have been added or experienced developer have departed.  The result: a huge amount of risk to the project when changes are made, increased cost in time to test, and delayed delivery of value to the end users - a mountain of technical debt.  Unit testing is a tool, if used properly, to help teams of all sizes be more efficient and minimize technical debt.  It should not be viewed as “overhead” or a barrier to delivering value to the end users.

If you are developing software using the .NET (Microsoft) technology stack, there are several unit testing frameworks available.  The most popular are Microsoft Unit Testing Framework for Managed Code (MSTest), NUnit, and xUnit.Net.  All get the job done and warrant evaluation if you are considering adding unit testing to your project.

Unit testing is a tool and with all tools they can cause problems if not used properly.  But when used properly, unit testing is a powerful tool in the tool chest.  If you are starting a new project or supporting a legacy codebase, unit testing should be in your tool belt to help minimize risk and cost while delivering value to your end users.

Keep Right’in Code!
Richard

Using Angular 2 RC5 with Visual Studio 2015 and ASP.NET Core 1.0

Lately, I have been spending time learning Angular 2.  During my study, I have seen many examples of setting up and getting started by using Visual Studio Code, WebStorm, and other excellent IDE’s.  I have also read several articles about setting up and using Angular 2 beta versions with Visual Studio 201x.  Since  I spend most of my time using Visual Studio 2015, this article will show you how to setup Angular 2 RC5 with Visual Studio 2015 and ASP.NET Core 1.0 on .NET Core 1.0.

Before you get stared, make sure you have Update 3 for Visual Studio 2015 installed and Preview 2 tooling for Microsoft .NET Core 1.0.  Once you have confirmed your installation, fire up Visual Studio 2015 and select “New Project” from the Start Page.  You will be presented with the dialog below:

New Project

Make sure you have selected the “ASP.NET Core Web Application (.NET Core)” option. Name the project and the solution, and set the location to whatever you would like.  Click “Ok” to continue.  Next you are presented with selecting what type of project template you would like to begin with.  Select “Empty”.  Authentication should be set to “No Authentication” and the “Host in the cloud” option should not be selected.  See the screenshot below:

Empty Template

Click “Ok” to continue.  After VS (Visual Studio) completes the setup you will be presented with the project readme HTML file in the editor.  If you take a look at Solution Explorer, your solution structure should look like the screenshot below:

Solution Explorer - Start

The next step in setting up ASP.NET Core 1.0 to serve Angular 2 RC5 is to configure your application to serve static files.  First, right-click on your web application in solution explorer and select “Manage NuGet Packages”.  In the NuGet Package Manager, enter “Microsoft.AspNetCore.StaticFiles” in the search window.  You will be presented with the screenshot below:

NuGet Package Manager

Make sure you have the latest stable version selected and click “Install”.  You may be asked permission to update your application as well as accept licensing terms.  Confirm to complete the installation and close the NuGet Package Manager Tab.  Finally edit the Startup.cs file in your solution.  It should look like the code below:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace WebApplication1
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseFileServer();
        }
    }
}

For a more in depth understanding of serving static files with ASP.NET Core 1.0, please visit here.

Now we are ready to begin setting up our environment for Angular 2 RC5.  “Right-click” on your web application project and select “Add” then “New Item”.  You will be presented with the dialog below:

Package-JSON

Navigate to “Client-side” under .NET Core and then select “npm Configuration File” (package.json).  Click Add.  This file is used by NPM (Node Package Manager) to install required modules for our Angular 2 application.  You will be presented with the package.json file loaded in the editor.  Edit the package.json file to look like the code below:

{
  "version": "1.0.0",
  "name": "webapplication1",
  "scripts": {
    "postinstall": "typings install",
    "typings": "typings"
  },
  "dependencies": {
    "@angular/common": "2.0.0-rc.5",
    "@angular/compiler": "2.0.0-rc.5",
    "@angular/core": "2.0.0-rc.5",
    "@angular/forms": "0.3.0",
    "@angular/http": "2.0.0-rc.5",
    "@angular/platform-browser": "2.0.0-rc.5",
    "@angular/platform-browser-dynamic": "2.0.0-rc.5",
    "@angular/router": "3.0.0-rc.1",
    "@angular/router-deprecated": "2.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.5",

    "systemjs": "0.19.27",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12",

    "angular2-in-memory-web-api": "0.0.15",
    "jquery": "^3.1.0",
    "bootstrap": "^3.3.6"
  },
  "devDependencies": {
    "typescript": "^1.8.10",
    "gulp": "^3.9.1",
    "path": "^0.12.7",
    "gulp-clean": "^0.3.2",
    "fs": "^0.0.2",
    "gulp-concat": "^2.6.0",
    "gulp-typescript": "^2.13.1",
    "typings": "^0.8.1",
    "gulp-tsc": "^1.1.5"
  }
}

Immediately after saving the package.json file, Visual Studio will begin downloading all the dependencies listed to a folder named “node_modules” in the directory where your web application is located. (If you would like a detail explanation of these settings, you can go here.)  In addition, you will probably receive an error message stating that npm was not able to resolve Typings dependencies due to a missing “typings.json” file.  Let’s create that file now.

“Right-click” on the web application and select “Add” then “New Item”.  Again select “Client-side” on the far left and then select “JavaScript File”.  Make sure you name the file “typings.json”.  Your screen should look like the screenshot below:

Typings-JSON

Click “Add” and you will be presented with the typings.json file in the editor.  Edit the typings.json file to look like the code below:

{
  "ambientDependencies": {
    "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654",
    "jasmine": "registry:dt/jasmine#2.2.0+20160412134438",
    "node": "registry:dt/node#4.0.0+20160509154515"
  }
}

Save the typings.json file.  If you would like an explanation of these settings, you can go here. Now if you switch to the project.json file and save it again, Visual Studio should complete the installation of the dependent modules without error.

Next we add a TypeScript JSON Configuration File. (tsconfig.json)  “Right-click” on the web application in Solution Explorer and select “Add” and then “New Item”.  Select “Client-side” on the left and “TypeScript JSON Configuration File”.  Your screen should look like the screenshot below:

TypeScript-JSON

Select “Add” and the tsconfig.json file will be loaded into the editor.  Edit the tsconfig.json to look like the code below:

{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noEmitOnError": true,
    "noImplicitAny": false,
    "outDir": "./wwwroot/scripts"
  },
  "exclude": [
    "node_modules",
    "wwwroot",
    "typings/main",
    "typings/main.d.ts"
  ]
}

Save the file.  If you would like an explanation of these settings, you can go here.

We are going to use SystemJS to load our application and library modules.  To do so, we need to create a configuration file for SystemJS so that it can locate the code we need loaded.

Since ASP.NET Core 1.0 serves static files from the “wwwroot” folder, we are going to place the SystemJS configuration file in a folder named “scripts” under this folder.  “Right-click” on the wwwroot folder and select “Add” then “New Folder”.  Name the folder “scripts”.  Solution Explorer should look like the screenshot below:

Solution Explorer - scripts folder

Now add the SystemJS configuration file to the scripts folder by selecting “Right-click” on the script folder and selecting “Add” then “New Item”.  You will be presented with the dialog below:

SystemJS

Select “Client-side” on the left and “JavaScript File”.  Name the file “systemjs.config.js”.  Click “Add” and the “systemjs.config.js” file will be displayed in the editor.  Edit the “systemjs.config.js” file to look like the code below:

(function (global) {
    // map tells the System loader where to look for things
    var map = {
        'app': 'scripts',
        '@angular': 'libs/@angular',
        'angular2-in-memory-web-api': 'libs/angular2-in-memory-web-api',
        'rxjs': 'libs/rxjs'
    };
    // packages tells the System loader how to load when no filename and/or no extension
    var packages = {
        'app': { main: 'main.js', defaultExtension: 'js' },
        'rxjs': { defaultExtension: 'js' },
        'angular2-in-memory-web-api': { defaultExtension: 'js' }
    };
    var ngPackageNames = [
      'common',
      'compiler',
      'core',
      'forms',
      'http',
      'platform-browser',
      'platform-browser-dynamic',
      'router',
      'router-deprecated',
      'upgrade'
    ];
    // Add package entries for angular packages
    ngPackageNames.forEach(function (pkgName) {
        packages['@angular/' + pkgName] = { main: './bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
    });
    var config = {
        map: map,
        packages: packages
    }
    System.config(config);
})(this);

If you are interested in the settings in the “systemjs.config.js” file, you can go here.

There is one final configuration step to complete and then we are ready to code our Angular 2 application.  As stated before, ASP.NET Core 1.0 serves static files from the wwwroot folder by default.  As a result, we need to move required library files from the node_modules folder to a location under the wwwroot folder.  In addition, if we would like to perform any debugging of the TypeScript code in our browser development tools, we need to have the original TypeScript files served from the server.  In order to accomplish this, we are going to use a gulp script to handle copying the files to their needed location.

“Right-click” on the web application and select “Add” then “New Item”.  Select “Gulp Configuration File”.  The dialog should look like the screenshot below:

Gulp

Click “Add” and you will be presented with gulpfile.js in the editor.  Edit the gulpfile.js to look like the code below:

/// <binding AfterBuild='clearLibsDestinationFolder, clearAppDestinationFolder, moveToLibs' />
/*
This file in the main entry point for defining Gulp tasks and using Gulp plugins.
Click here to learn more. http://go.microsoft.com/fwlink/?LinkId=518007
*/

var gulp = require('gulp');
var clean = require('gulp-clean');

var libsDestPath = './wwwroot/libs/';
var appDestPath = './wwwroot/app/';

//clear destination folders
gulp.task('clearLibsDestinationFolder',
    function () {
        return gulp.src(libsDestPath)
            .pipe(clean());
    });

gulp.task('clearAppDestinationFolder',
    function () {
        return gulp.src(appDestPath)
            .pipe(clean());
    });

gulp.task('moveToLibs', function () {
    gulp.src([
      'node_modules/es6-shim/es6-shim.min.js',
      'node_modules/systemjs/dist/system-polyfils.js',
      'node_modules/systemjs/dist/system.src.js',
      'node_modules/reflect-metadata/Reflect.js',
      'node_modules/rxjs/bundles/Rx.js',
      'node_modules/zone.js/dist/zone.js',
      'node_modules/jquery/dist/jquery.*js',
      'node_modules/bootstrap/dist/js/bootstrap*.js',

      'node_modules/core-js/client/shim.min.js'

      //'node_modules/systemjs/dist/*.*',
    ]).pipe(gulp.dest('./wwwroot/libs/'));

    gulp.src(['node_modules/@angular/**/*'], { base: 'node_modules/@angular' })
        .pipe(gulp.dest('./wwwroot/libs/@angular'));
    gulp.src(['node_modules/angular2-in-memory-web-api/**/*'], { base: 'node_modules/angular2-in-memory-web-api' })
        .pipe(gulp.dest('./wwwroot/libs/angular2-in-memory-web-api'));
    gulp.src(['node_modules/rxjs/**/*'], { base: 'node_modules/rxjs' })
        .pipe(gulp.dest('./wwwroot/libs/rxjs'));

    gulp.src([
      'node_modules/bootstrap/dist/css/bootstrap.css'
    ]).pipe(gulp.dest('./wwwroot/libs/css'));

    //copy typescript files for debugging purposes - would not deploy to production environment
    gulp.src(['app/**/*']).pipe(gulp.dest('./wwwroot/app'));
});

The gulp file is configured to execute after a successful build of the solution once the Task Runner Explorer is setup.  From the VS menu, select “View”, “Other Windows”, and then “Task Runner Explorer”.   Click the “Refresh” button (top left, next to the application name) and Task Runner Explorer will read the gulp file.  You should see three(3) task: clearAppDestinationFolder, clearLibsDestinationFolder, and moveToLibs.  You should also see the number three(3) next to the “After Build” Bindings.  Now the gulp script will execute after a successfully build.

Okay, finally let’s code our Angular 2 application.

First step is to add an “index.html” file.  “Right-click” on the wwwroot folder and select “Add” then “New Item” and add an HTML file named “index.html”.  Edit the file to look like the code below:

<!DOCTYPE html>
<html>
<head>
    <title>Angular 2/ASP.NET Core 1.0 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="libs/css/bootstrap.css">

    <!-- 1. Load libraries -->
    <script src="libs/jquery.min.js"></script>
    <script src="libs/bootstrap.min.js"></script>
    <script src="libs/zone.js"></script>
    <script src="libs/Reflect.js"></script>
    <script src="libs/system.src.js"></script>

    <!-- Polyfill(s) for older browsers -->
    <script src="libs/es6-shim.min.js"></script>
    
    <!-- 2. Configure SystemJS -->
    <script src="scripts/systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
</head>
<body>
<h1>Hello world from ASP.NET Core 1.0 on .NET Core 1.0!</h1>
    <br/><br/>
    <my-app>Loading...</my-app>
</body>
</html>

Now let’s add a new folder name “app” that will contain all of our TypeScript code for our Angular application.  “Right-click” on the web application project and select “Add” then “New Folder”.  Name the folder “app”.

The first TypeScript file we will add to the project is “main.ts”.  This is where our Angular 2 application starts up.  “Right-click” on the “app” folder and select “Add” then “New Item”.  Select “Client-side” on the left and in the center select “TypeScript File”.  Name the file “main.ts” and select “Add”.  “main.ts” should now be loaded in the editor and your solution should look similar to the screenshot below:

Main.ts

Edit the main.ts file to look like the code below:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Visual Studio will flag a few errors but that is okay for now.  They will be resolved when we add the remaining files.  Now let’s add a new TypeScript file to the app folder named “app.module.ts” and edit the file to contain the code below:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';

@NgModule({
    imports: [BrowserModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }

Finally, let’s add a third TypeScript file to the app folder named “app.component.ts” and edit the file to contain the code below:

import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: '<h3>Angular 2 RC5 is running here!</h3>'
})

export class AppComponent { }

After adding the third TypeScript file, all of the Visual Studio errors should have been resolved.  Your solution should look similar to the screenshot below:

Final TypeScript

I will publish another blog post with more details about the three(3) TypeScript files we just added.  If you would like more information now, you can go here.

Okay, let’s build the application in Visual Studio.  The application should build successfully.  Now let’s launch the application and you should be greeted with the screenshot below:

AppWelcome

We have an Angular 2 RC5 application served up from ASP.NET Core 1.0 on .NET Core 1.0 and built using Visual Studio 2015!  You can find a Visual Studio solution here.

I hope this post is helpful with getting started with Angular 2 development using Visual Studio 2015 and ASP.NET Core 1.0 on .NET Core 1.0.  Let me know if you have any questions.  Keep Right’in Code!

Richard - @rightincode