Setting Up a JavaScript Testing Environment in Visual Studio

by | Development | 4 comments

I’m going to walk you through setting up your JavaScript testing environment in Visual Studio, but I’m not going to be explaining how to write Jasmine tests in this article. For that, I recommend going to the Jasmine documentation site for some good examples, or watching one of the several Pluralsight courses that discuss JavaScript testing using Jasmine.

We’re going to set up the testing framework, Jasmine, the test autorunner, Karma, and supporting Visual Studio tools for testing JavaScript. I highly recommend AngularJS for structuring your code in a very testable manner. It’s like the Best. Thing. Ever. But that’s another topic altogether. But without such a framework, JavaScript testing can be a nightmare, even with these testing tools.

Karma

In this first set of steps, we’ll be setting up Karma to run all of our Jasmine tests:

  1. For everything that follows, you’ll need Jasmine, so install it to your project containing your tests via NuGet. You can find it by searching jasmine.js.
  2. You’ll need Node.js in order to run the Karma test autorunner, so go to the Node.js site and click the big, green, shiny Install button. You can’t miss it. You’ll probably end up using Node.js for more than just Karma, so I recommend doing this whether or not you’re ready to use Karma.
  3. Installing Node.js also adds its runtime location to your system path, so even if you already have a command prompt open, you now need to open a new one to ensure the path exists inside the prompt.
  4. Now that Node.js is installed, and you have a new command prompt open, you can now run its version of NuGet, which is called npm, to install Karma.
  5. Run the following from the command prompt, which installs the Karma engine:
    npm install -g karma
  6. Run the following from the command prompt, which installs the command line interface for it:
    npm install -g karma-cli
  7. Although I did not have to do this, others had to. I am not sure why I did not need to, since I never explicitly install this before. For some reason, this was treated as a Karma dependency when I ran the above two commands, but it does not work for everyone. It installs the Jasmine support for Karma:
    npm install -g karma-jasmine

    Jasmine is the JavaScript testing framework that Karma will autorun for us.

  8. Similarly, I also did not need to install the Karma Chrome launcher separately, but others did need to. So run this command:
    npm install -g karma-chrome-launcher

    If you want Karma to use a different browser to execute the automated testing, you can install that instead. For example:

    npm install -g karma-safari-launcher

    Either way, a browser launcher is needed for Jasmine to run, so Karma needs to launch one during its automated testing process.

  9. Karma needs a configuration file (which happens to be a JavaScript file mainly consisting of an object for setting configuration options). Since this configuration file needs to be in the same folder where references to your JavaScript files are relative, you need to change to that folder before running the next command.
  10. To create the initial configuration file, run this from the command line:
    karma init

    (you may notice that karma is a DOS batch file that was installed in the above steps). It will prompt you for some values, but for now, press Enter at each question to accept the defaults. We’ll be editing the config file manually, afterwards. This will create a file called karma.conf.js.

  11. Edit the karma.conf.js file. This next step may take some trial and error. You need to specify an array of paths or file names (relative to the folder containing this config file) of all the JavaScript dependencies required for your tests. You can use wildcard characters as well. A single asterisk represents any set of characters (ex: app/*.js), where a double asterisk means to recurse through all subdirectories (ex: app/**/*.js means look for all JavaScript files within all subdirectories under app).
  12. Assuming you will be using Chrome and Jasmine, the config file should look something like this:
    // Karma configuration
    // Generated on Thu May 08 2014 13:19:36 GMT-0400 (Eastern Daylight Time)
    
    module.exports = function(config) {
      config.set({
    
        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',
    
        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['jasmine'],
    
        // list of files / patterns to load in the browser
        files: [
          'Scripts/**/*.js',
          'app/*.js',
          'app/**/*.js',
          'Tests/*.js'
        ],
    
        // list of files to exclude
        exclude: [
    
        ],
    
        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
    
        },
    
        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['progress'],
    
        // web server port
        port: 9876,
    
        // enable / disable colors in the output (reporters and logs)
        colors: true,
    
        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,
    
        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,
    
        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['Chrome'],
    
        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false
      });
    };
    
  13. After saving these changes, you can now run all your tests via Karma by using this command from within the same folder as the config file. By the way, you could specify the config file and path (check out the Karma documentation), but for our purposes, we’ll be using the defaults:
    karma start
  14. As long as the command prompt is open, every change you make to the scripts under test will automagically trigger a re-test, thanks to the autoWatch: true setting in the config file.

Chutzpah

If you’re like me, and want the flexibility of running tests on demand via the IDE, you have at least a couple of choices. Follow these steps to install the Chutzpah Visual Studio extensions (it takes some chutzpah to name an extension “Chutzpah” and expect everyone to understand what that means 🙂 ), that will add the ability to right-click on a test folder or test script to run a quick test:

  1. Create a reference for all of your dependent JavaScript files at the top of each JavaScript file under test (similar to what you would do to get JavaScript Intellisense work correctly within Visual Studio). As James of Code for Coffee suggests, it’s recommended you create a _references.js file, and place it with your main JavaScript files, and al references within that file would be relative to where it’s located. Then all you’ll need to do is include _references.js at the top of each of your JavaScript files under test.
  2. Install the Chutzpah test adapter and the Chutzpah context menu.
  3. Create a chutzpah.json file (which is Chutzpah’s configuration file) in the same folder where references to your JavaScript files are relative. It should look like this:
    {
        "Framework": "jasmine",
        "RootReferencePathMode":"SettingsFileDirectory"
    }
    

    This ensures that Chutzpah can find all JavaScript files under test relative to the config file’s location.

That’s basically it. Just right click a folder containing your JavaScript tests, or on one of the files if you want to just run its tests, and click Run JS Tests. Chutzpah also installs an option for showing code coverage, but I have not experimented with that yet.

ReSharper Unit Testing

If, like me, your Visual Studio extension tool of choice is ReSharper (R#), you may want to run its test runner instead. It should work fine, with one potential pitfall. If you try running your tests, but they all seem hung up, make sure you remove any references to jasmine.js from your _references.js file or from the top of any JavaScript files under test. I know that hurts, because now your editor won’t recognize the reference from within any of your Jasmine test files, leaving you with a bunch of blue squigglies. But for some reason, the R# test runner gets confused. I’m going to contact JetBrains about that.