Tests are written in vitest and served via npm run vitest
Test initialization goes like this:
-
api/vitest.config.mts
loads the tsconfig.json and finds the appropriate setup functions. -
Before running the tests, it runs the file found in the
globalSetup
config option. i.e.api/tests/global-setup.ts
. This does things like setting up the database and running migrations and base seeds. -
Next it loads a pre-test files using config option
setupFiles
files, currently onlyapi/tests/setup.ts
. These setup files add callbacks that will run before/after each test file runs, so they should be performant. Mostly cleanup functions such as wiping the database. -
It runs the actual tests in the loaded file.
-
Runs the next test file, and repeats from step 3.
-
Tests should map to a specific file in the api/src folder.
e.g.
api/src/models/user.ts
maps toapi/tests/models/user.test.ts
api/src/services/users/create-service.ts
maps toapi/tests/services/users/create-service.test.ts
-
Tests should follow the naming convention
{filename}.test.{extension}
. -
Test file location should be moved if a given file is moved, and deleted if the file under test is deleted.
-
A good general pattern for a test is
describe("api/src/services/users/create-service.ts", () => { // references file under test describe("CreateService", () => { // references class or model under test describe(".perform", () => { // references a specific method on the class or model test("creates a new user in the database", async () => { // descriptive message about the specific behaviour under test }) }) })
-
I'm using a plugin that lets me switch between the test and non-test file, and creates the test file if it does not exist. It's not great, but it mostly works. See https://marketplace.visualstudio.com/items?itemName=klondikemarlen.create-test-file
It requires this config (in your workspace or
.vscode/settings.json
).Note that if this is in your workspace config must be inside the "settings" entry. i.e.
{ "settings": { // these settings } }
.{ "createTestFile.nameTemplate": "{filename}.test.{extension}", "createTestFile.languages": { "[vue]": { "createTestFile.nameTemplate": "{filename}.test.{extension}.ts" } }, "createTestFile.pathMaps": [ { // Other examples // "pathPattern": "/?(.*)", // "testFilePathPattern": "spec/$1" "pathPattern": "(api)/src/?(.*)", "testFilePathPattern": "$1/tests/$2" }, { "pathPattern": "(web)/src/?(.*)", "testFilePathPattern": "$1/tests/$2" } ], "createTestFile.isTestFileMatchers": [ "^(?:test|spec)s?/", "/(?:test|spec)s?/", "/?(?:test|spec)s?_", "/?_(?:test|spec)s?", "/?\\.(?:test|spec)s?", "/?(?:test|spec)s?\\." ] }