Run and debug unit tests in Typescript

Jean Tadebois
3 min readApr 12, 2021

In a previous article, I weighted the pros and cons of writing our unit tests in Typescript (TS) when working on a TS project. In this article, I want to explain how to overcome the challenges of debugging TS unit tests, i.e. hitting a breakpoint in our TS code while executing a test.

The issue here is that TS does not execute per se. Instead, it gets transpiled to JavaScript, which can then run in a browser or Node.js.

The problem statement therefore is: How do we hit a breakpoint in a TS unit test while debugging our code?

The answer is quite simple; we use the npm package ts-node.

npm install ts-node --save-dev

This package allows TS to execute without going through the transpiling stage to JavaScript (JS)

ts-node is to TS what node is to JS.

Hossam Barakat, in his article Running Mocha with TypeScript. provides a concise but complete tutorial on how to achieve a debuggable unit test in TS. However, I want to share my own take on the concept.

I will begin by exposing some code via Gist, and provide a complete repository of the solution by the end of this article.

Let us begin with a non-trivial TS class:

The file Field.ts defines a class with a print method that needs to be brought under test.

Notice the export default preceding the Field class declaration. This is important for TS as it uses the import <class> from <file> syntax.

For our unit tests, we create a FieldTest.ts file.

Here notice how Field does not use require() but instead uses import, i.e. import Field from ‘../src/Field’;

The Project’s Structure

The source files in TS are placed in ./src and the unit tests in ./test respectively. We need to examine two configuration files to understand the interplay between the files in those folders.

tsconfig.json

The include section only mentions the source folder, i.e. ./src/. That’s because we do not want our unit tests written in TS to be transpiled to JS in the build folder.

Notice that compilerOptions.outDir points to ./built. After executing npm start, the source code in ./src will be transpiled from TS to JS, allowing node to execute the code.

package.json

Of importance to our unit testing solution lies within the “script” section. “prestart” executes each time npm start is executed. It is responsible for transpiling TS code from ./src to JS code in ./built.

Afterwards, “start”, via npm start, uses node to execute the JS file passed in as parameter, in this case ./built/index.js.

The “test” section instructs mocha to use ts-node as execution environment. From then on, each time we run npm test, it is our TS unit tests that executes, allowing us to place breakpoints both in the unit test and within the class under test.

Hitting a breakpoint in a TS unit test.
Hitting a breakpoint in our TS Class from one of its unit tests.

Voila! We now have an elegant solution to exercising our TS production code with unit tests written with the same nomenclature.

I encourage you to fork the complete repository and play around with it a little to gain a deeper understanding of how to achieve writing and debugging your TS unit tests.

--

--