Chutzpah 3.1 – Smarter test running and Jasmine 2.0

Chutzpah 3.1 has a few improvements that were originally targeted for the 3.0 release. As always  you can get the new bits from CodePlex, NuGet or go to the Visual Studio Gallery to get the updated Visual Studio Context Menu Extension  and Unit Test Explorer adapter.

Changes

Tests Setting

In the 3.0 release Chutzpah added a references section that let you declare which files to include as references. In this release a similar section named Tests is added that lets you specify what tests you want to run.

Example

{
    "Tests": [
        { "Include": "*test1*" },
        { "Path": "Dir3/test.js"},
        { "Path": "Dir1", "Include": "*.js", "Exclude": "*test4.js" },
        { "Path": "Dir2" }
    ]
}
  • Line #3 – Includes all tests that contain test1 in its path. This is in glob format.
  • Line #4 – Includes the file Dir3/test.js (relative to the chtuzpah.json path).
  • Line #5 – Includes all *.js files in the folder Dir1 except test4.js.  (Include/Exclude in glob format)
  • Line #6 – Includes all files in Dir2

These settings are evaluated on a first match wins policy. This means that if line #2 matches a file then #3 and #4 will not be checked for that file. Therefore, if an earlier line matches a file a later line cannot exclude that same file.

Usage

The tests setting section can be used in two ways: discovery or filtering.

Discovery

You can tell chutzpah.console.exe to execute a chutzpah.json file! Chutzpah will evaluate the tests settings and use it to find all files it describes.  For example:

chutzpah.console.exe path/to/chutzpah.json

This feature provides a nice way to simplify describing  all tests you want to run without needing to explicitly list multiple /path arguments on the command line.

 

Filtering

The second way the new tests setting can be used is to filter which test files are executed. When Chutzpah is running test files it will skip ones which don’t match the tests setting. This is a *much* needed feature for the Visual Studio integration. By default the test adapter plugin will look at all *.js files and try to see if they are test files. Often Chutzpah is able to use heuristics to quickly tell if a file is a test file. If the heuristics fails it then needs to actually execute that file. This can be very slow especially if Chutzpah is doing this with a large JS library. With this tests setting feature you can help Chutzpah out by placing a chutzpah.json at the root of your project and indicate which files are the test files. This can be a big performance boost and is the recommendation for all projects.

Jasmine 2.0

Chutzpah now ships with support for both the 2.0 and 1.0 lines of Jasmine (specifically 1.3.1 and 2.0.0). Both are supported for now since the 2.0 release broke combat with the 1.0 line. By default Chutzpah will assume you want the 2.0 version but there is a new chutpah.json setting to indicate you want the previous version.

To indicate you want the 1.0 line of Jasmine add the following to your chutzpah.json file:

{
    "FrameworkVersion": "1"
}

You can put pretty much any version you want here that starts with 1 since for Jasmine Chutzpah only cares if you either want the 1.0 line or if you don’t. Eventually Chutzpah will deprecate and then remove support for Jasmine 1.0 so please begin the process of upgrading soon.

 

Chutzpah 3.0: Mocha, RequireJS and more…

Chutzpah 3.0 resolves two of the most requested features: Mocha test framework and better RequireJS support.  In addition to those this release contains many bug fixes and a few smaller additions. Below I will describe in detail how to take advantage of these new features. As always  you can get the new bits from CodePlex, NuGet or go to the Visual Studio Gallery to get the updated Visual Studio Context Menu Extension  and Unit Test Explorer adapter.

Changes

Improved RequireJS Support

The most common source of issues for Chutzpah was people trying to get it to work with RequireJS. Although it was possible to make it to work it was very tricky and would crumble if you tried anything complicated. The new support for RequireJS should be much more flexible and allow you to run individual test files however it does require a few specific settings to work. I checked in examples for how to set this up for Mocha, QUnit, Jasmine and TypeScript. I will walk through a simplified version of the  QUnit example in both JavaScript and in TypeScript.

RequireJS with QUnit using JavaScript

In this sample there is a RequireJS module in the base folder and a test file in the tests/base folder. Below I show the file structure of the sample and the source of the test file and the code file tests.

File Structure

chutzpah.json
require-2.1.8.js 

base/
  core.js 

tests/
  base/
    base.qunit.test.js

core.js

define(function () {
    return {
        version: 8
    };
});

base.qunit.test.js

define(['base/core'],
    function (core) {
        module("base/core");
        test("will return correct version from core", function () {
            var version = core.version;
            equal(version, 8);
        });
    });

The key to being able to run the base.qunit.test.js test file is to set up the chutzpah.json file. This sample uses the following chutzah.json file:

{
    "Framework": "qunit",
    "TestHarnessReferenceMode": "AMD",
    "TestHarnessLocationMode": "SettingsFileAdjacent",
    "References" : [
        {"Path" : "require-2.1.8.js" } 
    ]
}

The chutzpah.json file is making use of a few new settings in version 3.0.  Setting TestHarnessReferenceMode to AMD tells Chutzpah that we are running tests that use the AMD style. In this mode Chutzpah will not insert references (discovered from ///<reference comments and the test file into the test harness. Instead it will inject a require statement in the test harness with the right path to the file under test.  I then list explicitly which references I want injected into the test harness (in this case just require.js). The settings file should be place at the root of your AMD project (i.e. where you want all your paths relative to) and you should set the TestHarnessLocationMode to be SettingsFileAdjacent which places the generated harness in the same folder.

With this setup you can run chutzpah as follows:

chutzpah.console.exe tests\base\base.qunit.test.js

RequireJS with QUnit using TypeScript

This is the same example as above expect with everything converted to TypeScript. To be able run this example there are a couple extra settings in the Chutzpah.json file.

File Structure

chutzpah.json
require-2.1.8.js
require.d.ts
qunit.d.ts 

base/
  core.ts 

tests/
  base/
    base.qunit.test.ts

core.ts

export var version = 8;

base.qunit.test.ts

import core = require('base/core');

QUnit.module("base/core");
test("will return correct version from core", function () {
    var version = core.version;
    equal(version, 8);
});

The TypeScript versions of these files make use of TypeScript’s nice import/require syntax which make its cleaner to write code in the AMD style.

The chutzpah.json file needed to run this sample is:

{
   "Framework": "qunit",
   "TestHarnessReferenceMode": "AMD",
   "TestHarnessLocationMode": "SettingsFileAdjacent",
   "TypeScriptModuleKind": "AMD",
   "References" : [
      { "Path": "require-2.1.8.js" },
      { "Path": "require.d.ts", "IncludeInTestHarness": "false" },
      { "Path": "qunit.d.ts", "IncludeInTestHarness": "false" },
      { "Path": "base", "IncludeInTestHarness": "false" }
    ]
}

This chutzpah.json file is a bit more complicated than the one in the previously.It sets TypeScriptModuleKind to AMD, which tells the TypeScript compiler to emit AMD define statements. It also has a few additional References path entries. There are references for the .d.ts files to satisfy type checking. Then we reference the base folder so that Chutzpah will recursively scan that folder and find all files in it. This is important since Chutzpah needs to find all the .ts files in order to convert them to JavaScript. Chutzpah will also use these discovered .ts files to generate a RequireJS map setting that maps from the original file names to the temporary names that Chutzpah creates after conversion. All of these additional path references have IncludeInTestHarness set to false. This tells Chutzpah to not generate a script reference for these files inside of the generated test harness. For the .d.ts files we don’t want script tags and for all the files in the base directory are going to load them using RequireJS so we must not include them a second time using a script tag.

For more complicated examples browse the samples folder in the Chutzpah repository.

Mocha Test Framework Support

One of the most request features was to add the Mocha test framework to the supported frameworks. Mocha presents some challenges since it is a super flexible and open ended test framework. This required several changes in Chutzpah as well as some new chutzpah.json options to make sure it is flexible enough. In the future (based on user feedback) I will try to open up the Mocha integration further to let people do things like use custom interfaces.

Chutzpah supports three of the Mocha interfaces: QUnit, BDD and TDD. It will try to auto detect which one you are using but you can also specify explicitly. For example here is a basic Mocha test using the BDD interface:

/// <reference path="mocha.js" />
/// <reference path="chai.js" />

var expect = chai.expect;

it("A basic test", function() {
    expect(true).to.be.ok;
    var value = "hello";
    expect(value).to.equal("hello");
});

Note that this file includes a ///<reference comment referencing mocha.js. This file doesn’t need to exist since Chutzpah uses its own version but this line is needed to let Chutzpah know you are using Mocha. Since Mocha’s interfaces can look like Jasmine/QUnit Chutzpah won’t auto detect that you are using Mocha. In addition, since Mocha lets you choose your assertion library the test above is referencing chai.js (this does need to exist on disk since Chutzpah does not ship with this). Putting those reference comments in every file can be annoying so you can use the Chutzpah.json file remove the need for them:

{
    "Framework": "mocha",
    "MochaInterface": "bdd",
    "References" : [
      { "Path": "chai.js" }
    ]
}

This Chutzpah.json example shows that you can set the Framework to Mocha, set the interface to BDD and then list the references you want Chutzpah to use. While you don’t always need to explicitly set the Mocha interface it doesn’t hurt to be clear with your intent.

Customizable HTML harness generation

Chutzpah tries its best to work for as many types and configurations of projects. However, there will always be projects where Chutzpah’s assumptions just don’t hold true. To help support these projects Chutzpah now allows you to take complete ownership of the template it uses to generate the html test harness. Be warned this is an advanced feature, by taking ownership of this template you are responsible for keeping it up-to-date with newer additions Chutzpah makes in later releases. Also, by editing this template Chutzpah can no longer make any guarantees that features like Code Coverage will still work.

If that red text did not scare you off continue on :)

To use this functionality you should start by making a copy of existing copy of the Chutzpah test harness template that is checked in (QUnit, Mocha, Jasmine). These templates contain a bunch of JavaScript and HTML embedded with special Chutzpah placeholders. These placeholders are where Chutzpah inserts text and tags it generates when examining your test files. As of version 3.0 the harness contains the following placeholders:

Placeholder Description
@@TestFrameworkDependencies@@ The test framework file references (like QUnit.js) and any references marked as IsTestFrameworkFile.
@@CodeCoverageDependencies@@ The code coverage framework file references (like Blanket.js). This will be empty when not running code coverage.
@@ReferencedCSSFiles@@ The CSS references.
@@TestHtmlTemplateFiles@@ Any test html template files discovered.
@@ReferencedJSFiles@@ Reference for all JS files discovered that your test files are dependent on.
@@TestJSFile@@ The reference for the file under test. This will be empty if in AMD mode.
@@AMDTestPath@@ The AMD path to the file under test.
@@AMDModuleMap@@ A mapping of AMD paths from original test dependencies to ones generated after running TypeScript or CoffeeScript conversion.

You can edit this copy to your liking and then place it somewhere in your project. To get Chutzpah to use this template set the following in your chutzpah.json file:

{
  "CustomTestHarnessPath": "path\\to\\customQUnit.html"
}

Chutzpah will use this template and generate a test harnesses out of it.

Command line failure report flag

When running Chutzpah on a large test suite from the command line it becomes difficult to see everything that failed because the failed test may be several pages up. To alleviate this problem chutzpah.console.exe contains a new flag: /showFailureReport . This flag will print a report showing all test errors and test failures at the ends of the test run.

Chutzpah.json additions

To support some of the new features and to fix existing issues the Chutzpah.json file has several new additions (many of which have been mentioned earlier in this post). Below is a complete list of the additions along with usage examples:

References

Description

The references setting allows you to specify which files/folders to use/scan to find references. This is useful since it replaces the need to the ///<reference comments. This setting is a list of path entries each which can contain the following arguments:

Path The path to either a file or a folder. If given a folder, it will be scanned recursively. This path can be relative to the location of the chutzpah.json file.
Include This is an optional include glob pattern. This is used when the Path is a folder. Only files matching the Include pattern will be added.
Exclude This is an optional exclude glob pattern. This is used when the path is a folder. All files matching the exclude pattern will not be added.
IncludeInTestHarness This determines if the reference should be injected into the test harness. When referencing files like .d.ts or files that you plan to load using require.js you should set this to false. Defaults to true.
IsTestFrameworkFile Indicated that this references should be placed directly after the test framework files (like QUnit.js) in the test harness. This ensures that this file is injected into the test harness before almost all other files. Defaults to false.

Examples

Include files named a.js and b.js

{
    "References": [
        { "Path": "../a.js" },
        { "Path": "b.js"}
    ]
}

Include all .js files in a folder unless their name contains the word Resource

{
    "References": [
        { "Path": "src/Code", "Include": "*.js", "Exclude": "*Resource*" }
    ]
}

TypeScriptModuleKind

Description

The TypeScriptModuleKind setting determines how the TypeScript compiler handles import/export statements. The options are either CommonJS or AMD. The default is CommonJS.

Example

{
   "TypeScriptModuleKind": "AMD"
}

TestHarnessReferenceMode

Description

The TestHarnessReferenceMode setting determines how Chutzpah should treat references to scripts and to the test file. The setting can either be Normal or AMD. Normal is how Chutzpah has always worked where it injects a script reference for your test file as well as all of its references into the HTML test harness. The AMD mode tells Chutzpah that tests using RequireJS are being used. In this case Chutzpah will not inject references or the test script into the test harness. The default value is Normal.

Example

{
   "TestHarnessReferenceMode": "AMD"
}

CustomTestHarnessPath

Description

The CustomTestHarnessPath setting allows you to override the default template Chutzpah uses for the HTML test harness. This is an advanced feature which was explained in detail above.

Example

{
  "CustomTestHarnessPath": "path\\to\\customQUnit.html"
}

EnableCodeCoverage

Description

The EnableCodeCoverage settings provides a way to have Chutzpah always run code coverage. This is important for when running on a build server where you may want Chutzpah to always collect code coverage. The default value is false.

Example

{
  "EnableCodeCoverage": "true"
}

CoffeeScriptBareMode

Description

The CoffeeScriptBareMode indicates if you want CoffeeScript compilation to output scripts in bare mode or not. In bare mode CoffeeScript won’t wrap the generated JavaScript in a function to protect the scope. The default value is true.

Example

{
  "CoffeeScriptBareMode": "false"
}

 

 

Chutzpah and Snippet Designer now support Visual Studio 2013

I released updates for both Chutzpah (2.5.0) and Snippet Designer (1.5.0) which adds support for Visual Studio 2013.

In addition Chutzpah’s command line client now has a /trace argument that will dump detailed trace information into a file named chutzpah.log. This is useful for both debugging and filing bug reports. I plan to add much more information into this log in the upcoming releases.

 

Chutzpah 2.4.3

This release of Chutzpah contains a few bug fixes, upgraded versions of Blanket.js and TypeScript and a new feature for injecting HTML templates.

TypeScript Upgraded

Chutzpah now uses TypeScript 0.9.0.1. This change may require an update for your .ts files. In this version of TypeScript the compiler errors if you do not specify the .d.ts file corresponding to your third party JS library. For example, if you are using QUnit you must reference the QUnit.d.ts file.

Improved Code Coverage

Code coverage has improved with two changes. The version of Blanket.js was upgraded to 1.1.5. In addition, Chutzpah will now prevent files you exclude from code coverage from getting instrumented. This helps improve performance of the coverage runs.

HTML Template Feature

This feature came in as pull request from Matthew Osborn. This allows you to specify an HTML template file from your tests. Chutzpah will inject this templates content into the head section of the generated test harness. For example, lets say you have an HTML template file named template.tmpl.html with the contents:

<script id="testTemplateId" type="text/html">
    <div id="testTemplateDiv">
        Cool!
    </div>
</script>

Then you can reference this file from your test with the syntax:

/// <template path="template.tmpl.html"/>

For example, this is a test case I wrote in Chutzpah to assert this feature works correctly:

/// <reference path="qunit.js" />
/// <template path="template.tmpl.html"/>
/// <reference path="../jquery-1.7.1.min.js" />

module("Html Template Test - QUnit");
test("Will load html template", function () {
    // Grab template text, convert to html, append to body
    $($("#testTemplateId").text()).appendTo("body");

    var templateDiv = $("#testTemplateDiv");

    equal(templateDiv.length, 1);
});

Which results in an HTML test harness which looks something like this:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="qunit.css"/>
  <script type="text/javascript" src="qunit.js"></script>
  <script id="testTemplateId" type="text/html">
      <div id="testTemplateDiv">
          Cool!
      </div>
  </script>
  <script type="text/javascript" src="query-1.7.1.min.js"></script>
  <script type="text/javascript" src="template-qunit.js"></script>
</head>

<body>
    <h1 id="qunit-header">Unit Tests</h1>
    <h2 id="qunit-banner"></h2>
    <h2 id="qunit-userAgent"></h2>
    <ol id="qunit-tests"></ol>
    <div id="qunit-fixture"></div>
</body>
</html>

The content from the template was injected into the head section above. This ability is useful for things like jQuery widgets and JS template renderers.

 

Chutzpah 2.4 – Code Coverage is a go!

With the Chutzpah 2.4 release one of the most asked for features is now available: built-in code coverage. In addition this release contains a bunch of bug fixes and added configurability.

You can get the new bits from CodePlex, NuGet or go to the Visual Studio Gallery to get the updated Visual Studio Context Menu Extension  and Unit Test Explorer adapter for Visual Studio 2012.

Changes and Fixes

  • Added Code Coverage support (item 113)
  • Updated versions of QUnit(v1.11.0), TypeScript(v0.8.3) and CoffeeScript(v1.6.2)
  • jasmin-jQuery toContain tests fail with reason “Passed.” (item 95)
  • FileSearchLimit=300 cancels test run with more than 300 tests (item 89)
  • /failOnScriptError exits with 1 even when there are not errors (item 97)
  • ‘undefined’ is not a function after updating to 2.3 (item 96)
  • No tests found when using QUnit.test instead of test (item 94)
  • Allow including files without building them (item 93)
  • Improve “/openInBrowser” (item 91)
  • Add TestFileTimeout setting to chutzpah.json (item 110)
  • Need a later version of phantom bundled with Chutzpah (item 107)
  • QUnit test runner module gotcha in 2.3 (item 109)
  • Support for unicode (item 111)
  • Improve CoffeeScript parse error reporting (item 80)

 

Code Coverage

Chutzpah’s new code coverage features is built on top of the great open source library Blanket.js. When you run with code coverage enabled it will use Blanket.js to instrument the files under test and gather the coverage results. You can perform code coverage from the command line and both Visual Studio plugins.

Command Line

To get code coverage from the command line you pass the /coverage flag to chutzpah.console.exe.

chutzpah.console.exe /coverage /path test.js

After this command finishes you will have a two files placed in your current directory

_Chutzpah.coverage.html – The rendered html results
_Chutzpah.coverage.json – The raw json results

When you open the results html file you will see something like:

image

 

Visual Studio Context Menu Extension

The Visual Studio Context Menu Extension now contains a Show Code Coverage command which will perform code coverage and open the results in a browser.

image

Visual Studio 2012 Test Adapter Extension

For the Unit Test Explorer adapter for Visual Studio 2012 Chutzpah piggybacks on the existing “Analyze Code Coverage” menu option and uses it to run with code coverage and show the results in a browser. Ideally, Chutzpah would integrate into the code coverage reporting built into VS but I was unable to figure out a good way to plug in to that. The side effect is that when you run this command VS will open their results window first (with nothing in it) and then Chutzpah will launch its results in a browser.

image

NOTE: I have noticed some performance issues when running “Analyze Code Coverage for All Tests” command. I think it might be VS doing extra work for no reason since it is trying to generate its own report.

 

Configuration Code Coverage

Being able to run code coverage is not enough since in many cases the results will not be accurate. For example, if your project uses jQuery you do not expect your test to cover all the lines of jQuery’s source code (that would be one impressive test). Therefore you need to exclude files/directories from participating in code coverage. There are two way you can do that with Chutpah: command line arguments or a chutzpah.json file.

If you are running Chutzpah from the command line there are two additional arguments you can pass coverageIncludes and  coverageExcludes. These are a comma separated list of files/paths you want to include or exclude from coverage. They can use a glob format where * matches zero or more characters and ? matches one character. For example:

Exclude files that ends in matt.js

chutzpah.console.exe /path test.js /coverage /coverageExcludes *matt.js

 

Include only dog.js and any file with a single character extension

chutzpah.console.exe /path test.js /coverage /coverageIncludes "*\dog.js, *.?"

 

Include *query.js but exclude jQuery.js

chutzpah.console.exe /path test.js /coverage /coverageIncludes *query.js /coverageExcludes *\jquery.js

 

The other option for configuring code coverage is the chutzpah.json file. There are two new setting which you can use CodeCoverageExcludes and CodeCoverageIncludes. These settings work in the same way as the their command line counterpart. The main difference is that you must escape backslashes.

{
  "CodeCoverageExcludes": ["*\\jquery.js"],
  "CodeCoverageIncludes": ["*query.js", "*\\dog.js"]
}

Test timeout setting

Chutzpah already has a test timeout setting but you previously could only configure it from the command line or with a setting in VS. This was inflexible especially if you want a different timeout for different tests. To solve this Chutzpah now include a TestFileTimeout setting in the chutzpah.json file. For example if you want a 10 second time out for a certain directory just place a chutpah.json file with the following in it:

{
    "TestFileTimeout": "10000"
}

Chutzpah Specific Reference

With the addition of TypeScript support a few releases ago several people reported issues when using Chutzpah with the TypeScript plugin in VS. The problem occurs since both TypeScript and Chutzpah are using the <reference path…> comments for different purposes. To get around this issue Chutzpah now supports two ways to reference dependent files.

1. The existing general way

/// <reference path="foo.js" />

2. The new Chutzpah specific way

/// <chutzpah_reference path="foo.js" />

Using the latter will let Chutzpah know about your dependency graph and should not confuse the TypeScript compiler.

Excluding References

The reference syntax is also used by VS to give intellisense in JS files. This leads to an issue since sometimes you may reference a version of a file just for intellisense but you do not want Chutzpah to copy it. In this case you now can include the chutzpah-exclude attribute to have it ignored by Chutzpah:

/// <reference path="someDependency.js" chutzpah-exclude="true" />

Running against a remote url

Chutzpah now supports executing a remote test harness. If you have a html test file on a remote server (like http://somesite.com/test.html) you can tell Chutzpah to execute that file directly

chutzpah.console.exe http://somesite.com/test.html

Note: Chutzpah does not support running anything but .html files remotely. If you want to run Chutzpah directly on a .js, .ts or .coffee file they must be local on disk.