DEV Community

Bosco Domingo
Bosco Domingo

Posted on

The ultimate Node Test Runner + TypeScript + ENV variables guide

This also works in a monorepo ;)

First install dotenv-cli, tsx and glob:

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

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

# For the global package.json in a monorepo
# pnpm add -wD dotenv-cli 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 dotenv-cli doesn't throw an error if they don't exist).

Add this to your app's package.json:

"scripts": {
    "test": "dotenv -e .env -e env.test -- glob -c \"tsx --test --test-reporter spec \" \"./test/**/*.test.ts\"",
    "build": "tsc -p",
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, both in the root folder of the app):

// 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

    "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
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

Top comments (0)