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
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",
//...
}
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
andpaths
set up in yourtsconfig.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"
]
}
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