Unit testing JS in a .NET project using Jasmine and Chutzpah
JavaScript is everywhere, including in your .NET web application.
We already had unit tests in place for the bulk of our ASP.NET MVC project, but we wanted to extend our coverage to include front-end JavaScript code. Preferably, we’d write these tests without leaving Visual Studio, and run them alongside our .NET tests in the same project.
Of course, JavaScript has no shortage of unit testing libraries. However, many of these seem to assume a Node.js stack. Our search led us to Jasmine, a testing framework with zero dependencies on other JS frameworks. Using this together with the Chutzpah test runner allowed us to achieve our goals.
Installing Jasmine
The preferred way to include JavaScript libraries in your .NET project is via NuGet packages. You can add the Jasmine package through the GUI or by running the following terminal command:
dotnet add package jasmine
This will add several JavaScript files to your project’s Scripts directory, most importantly jasmine.js
.
Installing Chutzpah
Next, you’ll want to install the Chutzpah Test Adapter for the Test Explorer extension for Visual Studio. This extension lets your Jasmine unit tests appear alongside your other tests in the Test Explorer.
If you’re using Visual Studio Code, you can install the Chutzpah Runner extension for that editor. Note that this extension needs to be configured to point to the chutzpah.console.exe
binary, which gets downloaded into your project when you include the Chutzpah NuGet package. You will also need this NuGet package if you want to wire up your unit tests to be automatically run on your build server, as we did.
Visual Studio users could also check out the Chutzpah Test Runner Context Menu Extension, which, as its name suggests, allows you to invoke the Chutzpah test runner from the context menu:
Warning: I have found that this extension does not integrate so well with the Test Explorer, so maybe evaluate both approaches and choose the one that works best for you.
Referencing your JS files
Let’s say you wanted to test a JavaScript function called makeCoffee()
, declared in a file named coffee-machine.js
, and you wanted to do this in a separate JS file named coffee-machine-tests.js
. The first question is, how do you reference this file from your test file?
The standard way to deal with these things is to use JavaScript modules (through CommonJS, RequireJS, or native ECMAScript 6 support). The catch here is that your code under test (your production code) is expected to export such modules, which ours doesn’t. But with Chutzpah, you don’t need this. Instead, Chutzpah provides a simple comment markup syntax for referencing other scripts.
For example, you can import a file, coffee-machine.js
, from the same directory as the test file by putting the following comment at the top of your test file:
/// <reference path="coffee-machine.js" />
Note that this uses a relative file path. Suppose coffee-machine.js
was in a different directory from the test file, e.g.
In this case, your reference path will look like this:
/// <reference path="../src/coffee-machine.js" />
Writing the tests
Once you have added references to your production JS code, you are ready to write your tests. I won’t go into a lot of detail here since that is not the focus of this article and there are plenty of tutorials available already.
In short, test suites are declared by calling describe
, passing in a description of the suite as well as a function.
/// <reference path="../src/coffee-machine.js" />
describe("coffee machine tests", function() {
// ...
});
This function declares test cases by itself making calls to it
, each once again passing in a description of the test case as well as a function.
/// <reference path="../src/coffee-machine.js" />
describe("coffee machine tests", function() {
it("pressing power turns on the machine", function() {
// ...
}); it("coffee is delicious", function() {
// ...
});
});
In these inner functions, you can call the code you want to test and use any of the various Jasmine matchers to verify the results, e.g.
/// <reference path="../src/coffee-machine.js" />
describe("coffee machine tests", function() {
it("coffee is delicious", function() {
var coffee = makeCoffee();
expect(coffee.isDelicious()).toBe(true);
});
});
Running the tests
In Visual Studio, if you installed all the Test Adapter extension, your Jasmine unit tests should now be listed in the Test Explorer and can be run like any other test. You should also be able to debug your tests. Additionally, if you installed the Test Runner for Context Menu extension, you can also run your tests via the context menu (as shown earlier in the article).
Using Visual Studio Code, if you installed the Chutzpah Runner extension, you can run your tests by selecting “Run Chutzpah” from the context menu. The results are written to the output window, e.g.
Tests complete: 18
=== 18 total, 0 failed, took 2.08 seconds ===
Used for this article:
- Visual Studio 2015 (14.0.25431.01 Update 3)
- Visual Studio Code 1.45.0
- Jasmine 2.6.4 (NuGet)
- Chutzpah 4.4.10 (NuGet)
- Chutzpah Runner 1.3.0 (VS Code)
- Chutzpah Test Adapter for the Test Explorer 4.4.9 (VS 2015)
- Chutzpah Test Runner for Context Menu Extension 4.4.9 (VS 2015)