BM-Bloggers

The blogs of Black Marble staff

Debugging Typescript in Visual Studio Code

This is one of those posts I do as a reminder to myself. I have struggled to get debugging working in VSCode for Typescript files. If I set breakpoints in the underlying generated JavaScript they worked, but did not work if they were set in the Typescript source file. There are loads of walkthroughs and answers on Stackoverflow, but all with that vital little bit (for me) missing. So this is what I needed to do for my usage scenario…

Whilst developing a Node based VSTS extension I have the following structure

Git repo root (folder)

--- .vscode (folder)

------ launch.json

--- mystuff.src   (the source .TS files)

------ script.ts

------ tsconfig.json

--- mystuff    (the target folder for the .JS files)

I develop my Typescript in the .src folder and use the TSC compiler to generate the .JS file into the target folder, running the ‘tsc –p .’ command whilst sitting in the .src folder.

Note: I actually run this Tsc command using Gulp, but this post does not need to go into detail of that.

The key thing is to make sure the two .json files have the correct options

The tsconfig.json is

{

"compilerOptions": {

"target": "ES6",

"module": "commonjs",

"watch": false,

"outDir": "../mystuff/",

"sourceMap": true

},

"exclude": [

"node_modules"

]

}

The important lines are highlighted

  • The path to generate to .JS to – for me it was important to generate to a different folder as this made it easier to create the VSTS extension packages without shipping the .TS files by accident.This was part of my debugging problem as if the .ts and .js files are in the folder the should be no issues
  • Creating the source map which enables debugging, the .JS.MAP files

The launch.json is

{

"version": "0.2.0",

"configurations":

[

{

"type": "node",

"request": "launch",

"name": "Node – my stuff",

"program": "${workspaceRoot}/mystuff.src/script.ts",

"outFiles": ["${workspaceRoot}/mystuff/*.js"]

}

]

}

The critical lines, and the ones I messed up are

  • Program must point at the .TS file
  • Outfiles must point to the location of the .JS and .JS.Map files in the target folder and those square brackets [] are vital

Once I had all this in place I could set breakpoints the .TS file and they worked

Running nUnit and Jasmine.JS unit tests in TFS/VSO vNext build

This article was first published on the Microsoft’s UK Developers site as Running nUnit and Jasmine.JS unit tests in TFS/VSO vNext build

With the advent of vNext build in TFS 2015 and Visual Studio Online running unit tests that are not MSTest based within your build process is far more straightforward than it used to be. No longer do you have to use custom XAML build activities or tell all your TFS build controllers where the test runner assemblies are. The ‘out the box’ vNext build Visual Studio Test task will automatically load any test adaptors it finds in the path specified for test runners in its advanced properties, a path that can be populated via NuGet.

Running nUnit tests

All this means that to find and run MSTest and nUnit tests as part of your build all you have to do is as follows

  1. Create a solution that contains a project with MStest and nUnit tests, in my sample this is a MVC web application project with its automatically created MSTest unit tests project.
  2. In the test project add some nUnit tests. Use NuGet to add the references to nUnit to the test project so it compiles.
  3. Historically in your local Visual Studio instance you needed to install the nUnit Test Runner VSIX package from Visual Studio Gallery – this allows Visual Studio to discover your nUnit tests, as well as any MSTest ones, and run them via the built in Test Explorer

    image

    IMPORTANT Change –
    However installing this VSIX package is no longer required. If you use Nuget to add the nUnit Test Runner to the solution, as well as the nUnit package itself, then Visual Studio can find the nUnit tests without the VSIX package. This is useful but not world changing on your development PC, but when on the build box it means the NuGet restore will make sure the nUnit test adapter assemblies are pulled down onto the local build boxes file system and used to find tests with no extra work.

    Note
    : If you still want to install the VSIX package on your local Visual Studio instance you can, it is just you don’t have to.
  4. Check in your solution into TFS/VSO source control. It does not matter if it is TFVC or Git based
  5. Create a new vNext build using the Visual Studio template
  6. You can leave most of the parameters on default setting. But you do need to edit the Visual Studio Test task’s advanced settings to point at the NuGet packages folder for your solution (which will be populated via NuGet restore) so the custom nUnit test adaptor can be found i.e. usually setting it to  $(Build.SourcesDirectory)\packages

    image
  7. The build should run and find your tests, the MStest ones because they are built in and the nUnit ones because it found the custom test adaptor due to the NuGet restore being done prior to the build. The test results can be found on the build summary page

    image

 

But what if you want run Jasmine.JS test?

If you want to run Jasmine JavaScript unit tests the process is basically the same. The only major difference is that you do still need to install the Chutzpah Test runner on your local Visual Studio as a VSIX package to run the tests locally. There is a NuGet package for the Chutzpah test runner so you can avoid having to manually unpack the VSIX and get it into source control to deploy it to the build host (unless you really want to follow this process), but this package does not currently enable Visual Studio to find the Jasmine tests without the VSIX extension being installed, or at least it didn’t for me.

Using the solution I used before

  1. Use NuGet to add Jasmine.JS to the test project
  2. Add a test file to the test project e.g. mycode.tests.js (adding any JavaScript references needed to find any script code under test in the main WebApp project)
  3. Install the Chutzpah Test runner in your local Visual Studio as a VSIX extension, restart Visual Studio
  4. You should now be able to see and run the Jasmine test run in the test runner as well as the MSTest and nUnit tests.

    image
  5. Add the NuGet package for the Chutzpah test runner to your solution, this is a solution level package, so does not need to be associated with any project.
  6. Check the revised code into source control
  7. In your vNext build add another Visual Studio Test task, set the test assembly to match your javascript test naming convention e.g. **\*.tests.js and the path to the custom test adaptor to $(Build.SourcesDirectory)\packages (as before)

    image
  8. Run the revised build.

    image
  9. You should see the two test tasks run and a pair of test results in the summary for the build.

So now hopefully you should find this a more straight forward way to added testing to your vNext builds. Allowing easy use of both your own build boxes and the hosted build service for VSO with testing frameworks they do not support ‘out the box’

Stupid mistake over Javascript parameters

I have been using the Google Maps JavaScript API today. I lost too much time over a really stupid error. I was trying to set the zoom level on a map using the call

map.setZoom(<number>);

I had set my initial zoom level to 5 (the scale is 1-17 I think) in the map load, when I called setZoom to 11 all was fine, but if I set it to any other number is reverted to 5. This different effect for different numbers was a real red herring. The problem was down to how I was handling the variable containing the zoom level prior to passing it to setZoom method. When it was set to 11 it was set explicitly e.g.

var zoomNumber = 11;

However when it was any other value it was being pulled from the value property of a combo box, so was actually a string. My problem was that setZoom does not return an error if if pass something in it does not understand, it just reverts to it’s initial value.

The solution was simple, cast the value to a string and it works as expected

map.setZoom(parseInt(ZoomNumber));