For those who are new to Strapi
Strapi is an open-source headless Content Management System (CMS) built with Node.js, designed to make it easy for developers to manage and deliver content across any device. It provides a flexible and customizable API out of the box—supporting REST and GraphQL—allowing teams to decouple the backend from the frontend. With an intuitive admin panel and support for custom plugins, Strapi is ideal for building scalable, content-driven applications quickly and efficiently.
How to add tests ?
Its easy , you can add jest and write Test the way you want. As Strapi clearly gives API . We can write our assertions clearly on API responses. You can follow the documentation here – as we are just focusing on API tests alone. we are doing a much simpler approach with Jests. you can read more about this here
The sample package.json file changes looks like this
"devDependencies": {
"@strapi/plugin-documentation": "^5.13.0",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"jest": "^29.7.0",
"typescript": "^5"
},
First part is you adding jest to the dev dependencies as you will not need this package on production
"scripts": {
"build": "strapi build",
"deploy": "strapi deploy",
"develop": "strapi develop",
"start": "strapi start",
"test": "jest --runInBand --testPathPattern=tests/",
"strapi": "strapi"
},
next is adding the tests to the scripts section , with following options
runInBand – --runInBand
option tells Jest to run all tests serially in the same process, rather than spawning multiple worker processes to run tests in parallel (which is the default behavior).We are doing this as we saw the retry behavous was triggering multiple API calls.
-testPathPattern=tests/” – this is where you specify your tests folder. You can change the folder to where you store. your test – may be you named it api-test ? this is where you change it
# now you can run the following command
npm run test
and as you expect it will run the tests, we made use of axios to trigger apis using async await .
The problem
Whenever we are editing test, strapi is continuously reloading. this is annoying and a serious waste of time.
The GPT Failure
We checked with Chat GPT – and we got the following response, which is not working and
Of course we tried the GPT approach and it didn’t work.

Teach a man how to fish
Then we resolved to good old code reading and debugging as you would do with any open source projects.
So we saw the logs –
[2025-05-18 05:44:44.620] info: Strapi started successfully
[2025-05-18 06:07:19.083] info: File changed: XXXXXX file path
✔ Cleaning dist dir (35ms)
[2025-05-18 06:07:29.116] info: Shutting down Strapi
[2025-05-18 06:07:29.133] info: Strapi has been shut down
whenever the test file was changing the message will popup. so we grep -ed for the “File changed” in the @strapi folder on node_moduels
ceegees@CGS-LT-M-039 node_modules % cd @strapi
ceegees@CGS-LT-M-039 @strapi % grep -inr 'File changed' .
./strapi/dist/node/develop.mjs:227: strapiInstance.log.info(`File changed: ${path2}`);
./strapi/dist/node/develop.js.map:1:{"version":3,"file":"develop.js","sources":["../../src/node/develop.ts"],"sourcesContent":["import * as tsUtils from '@strapi/typescript-utils';\nimpo
now you know that the reloading is happening from develop.mjs
now we look at the file develop.mjs
const watcher = chokidar.watch(cwd, {
ignoreInitial: true,
usePolling: polling,
ignored: [
/(^|[/\\])\../,
// dot files
/tmp/,
"**/src/admin/**",
"**/src/plugins/**/admin/**",
"**/dist/src/plugins/test/admin/**",
"**/documentation",
"**/documentation/**",
"**/node_modules",
"**/node_modules/**",
"**/plugins.json",
"**/build",
"**/build/**",
"**/log",
"**/log/**",
"**/logs",
"**/logs/**",
"**/*.log",
"**/index.html",
"**/public",
"**/public/**",
strapiInstance.dirs.static.public,
strings.joinBy("/", strapiInstance.dirs.static.public, "**"),
"**/*.db*",
"**/exports/**",
"**/dist/**",
"**/*.d.ts",
"**/.yalc/**",
"**/yalc.lock",
// TODO v6: watch only src folder by default, and flip this to watchIncludeFiles
...strapiInstance.config.get("admin.watchIgnoreFiles", [])
]
}).on("add", (path2) => {
strapiInstance.log.info(`File created: ${path2}`);
restart();
}).on("change", (path2) => {
strapiInstance.log.info(`File changed: ${path2}`);
restart();
}).on("unlink", (path2) => {
strapiInstance.log.info(`File deleted: ${path2}`);
restart();
});
here we can see that , along with the list of ignored file passed to chowkidar there is an extra option
…strapiInstance.config.get(“admin.watchIgnoreFiles”, []) – be careful with the todo on V6 —
So now its clear that we have to add to the admin config an extra option and pass the folders you want to exclude there –
//config/admin.ts
export default ({ env }) => ({
auth: {
secret: env('ADMIN_JWT_SECRET'),
},
apiToken: {
salt: env('API_TOKEN_SALT'),
},
transfer: {
token: {
salt: env('TRANSFER_TOKEN_SALT'),
},
},
watchIgnoreFiles:[
"**/tests/**",
],
flags: {
nps: env.bool('FLAG_NPS', true),
promoteEE: env.bool('FLAG_PROMOTE_EE', true),
},
});
Voila – this solved the problem for us. happy coding.
Co-Founder , Ceegees Software Solutions Pvt Ltd.
Problem Solver, Engineer