The ultimate Node Test Runner + TypeScript + ENV variables guide

Bosco Domingo - Apr 25 - - Dev Community

This also works in a monorepo ;)

First install tsx and glob:

# Use whatever package manager you prefer
pnpm add -D tsx glob

# For a single app in a monorepo
# pnpm add -F your-app -D tsx glob

# For the global package.json in a monorepo
# pnpm add -wD tsx glob
Enter fullscreen mode Exit fullscreen mode

Assuming you want environment variable control, create a .env and a .env.test at the root of the app you want to configure (optional, since Node throws an error if they don't exist, although I'm working on it).

Add this to your app's package.json:

"scripts": {
    //...
    "test": "glob -c \"tsx --env-file .env --env-file .env.test --test --test-reporter spec \" \"./test/**/*.test.ts\"",
    "build": "tsc -p tsconfig.build.json",
    //...
}
Enter fullscreen mode Exit fullscreen mode

What that test script does is load your .env and .env.test files (the latter overwrites the first in case of conflict), then asks glob to process the "./test/**/*.test.ts\" (which will load all Typescript files in the ./test folder ending in .test.ts) and runs the tests via tsx and with a more human-readable output (--test-reporter spec). This last step is equivalent to node --import tsx --test.

Finally, adapt your tsconfig.json to include your tests if you want decent imports, linting and others (in my case I had to split my tsconfig into 2: tsconfig.json and tsconfig.build.json, both in the root folder of the app):

Note: Having the baseUrl and paths set up in your tsconfig.json will also affect imports in the source code, which can mess up when executing Node. I have come up with a better way, find it in the Gist that goes with this article

// tsconfig.json
{
    "extends": "../../tsconfig.json", // Since I work in a monorepo, this one contains all generic compiler options. You can write them in this file if you prefer
    "compilerOptions": { // These are for shorter, non-relative imports in tests. Completely optional
        "baseUrl": "./",
        "paths": {
            "@src/*": ["./src/*"], 
        },
        "noEmit": true, // Avoid compiling by mistake
    },
    "include": ["./src/**/*", "./test/**/*"], // Important so tests also benefit from TS support
}

// tsconfig.build.json
{
    "extends": "./tsconfig.json", // The file above. You can also just extend the base `tsconfig.json` (in the root of the monorepo) instead, adding `include: [ "./src/**/*"]`, or write the `compilerOptions` here
    "compilerOptions": {
        "noEmit": false,
        "outDir": "./dist",
    },
    "exclude": [ // This way we avoid compiling tests into JS
        "**/*.spec.ts",
        "**/*.test.ts"
    ]
}
Enter fullscreen mode Exit fullscreen mode

And that should be it, really. Hope it is of help when setting up your TypeScript testing environment!

For more information, check this GitHub issue.

I also made a GitHub Gist to go along with this guide which will probably be more up-to-date than this article

. . . . . . . . .