Test
Unit tests
In this project, a unit test is expected to be a test without a database/network connection
The unit test file should suffix with
.test
The jest config file is
jest.config.js
run all unit test
yarn test
E2E tests
In this project, the e2e test is expected to be a test with a database/network connection.
The e2e test file should suffix with
.e2e-spec
The jest config file is
jest.e2e.config.js
run all e2e test
yarn test:e2e
Strapi Environment
StrapiEnvironment
presets for each e2e test. A strapi instance and a database will start automatically. You do not need to handle the lifecycle of strapi in each test file like this exampleBut be careful, the strapi instance and database are reuse in each test.
You could use the
strapi
andrequest
instance directly in the e2e test filestrapi.query('products').find();
strapi.services.product.creates({});
// instead of request(strapi.server).get('/products').send`
request.get('/products').send();For more details, see
strapi/tests/helpers/strapiEnvironment.ts
Test Api
I have created an API instance/utility for the e2e testing. You do not need to care about the HTTP method and the path.
The API instance is strongly typed. It depends on
strapi/tests/helpers/routes.ts
which is a file auto-generated byesbuild/routeMetadata.ts
. If you found the content is not up to date. Just runyarn build
Examples:
// basic usage
api.category.find().send();
// dynamic path '/categories/:id'
api.category.findOne({ id: 'mongoid' }).send();
// add bearer token
api.profile.get().token(token).send();
// multipart, file upload
api.product
.create()
.multipart()
.attach('file', './image.png')
.field({ data: JSON.stringify({}) });The above code same as below
request.get('/categories').send();
request.get(`/categories/${mongoid}`).send();
request.get(`/profile`).set('Authorization', `bearer ${token}`).send();
request
.post(`/products`)
.set('Content-Type', 'multipart/form-data')
.attach('file', './image.png')
.field({ data: JSON.stringify({}) });
Custom Jest matcher
I have defined some custom jest matcher in strapi/tests/matchers
import { HTTPStatus } from '@/tests/helpers/httpStatus';
test('...', async () => {
const response = await request.get('/categories').send();
// expect response status to be 200
expect(response).toHaveStatus(HTTPStatus.OK);
// expect response.error not false
expect(response).toHaveError(HTTPStatus.OK);
// expect response.error is false
expect(response).not.toHaveError(HTTPStatus.OK);
});
step to create custom Jest matcher
Refer to the matchers in
tests/matchers
Remember to extend and export the matcher function
export function theMatcherFunction(
this: jest.MatcherContext,
received: unknwon,
expected: unknwon
): jest.CustomMatcherResult | Promise<jest.CustomMatcherResult> {}
expect.extend({ theMatcherFunction });
- Export the matcher file in
tests/matchers/index.js
Define new global variables for test
- Define the type of variables in
tests/jest-e2e.d.ts
- Set the initial values in
/jest-setup.js
- Update the
globals
field in.eslintrc
Watch
start development using yarn dev
or docker-compose up
. Open another terminal and type
yarn app test --watch
yarn app test:e2e --watch
Specify a test
yarn test app/schema/joi/mongoid.test.js
yarn test:e2e app/tests/category.e2e-spec.ts
No console output
Copy below test as the last test
test('delay', async () => {
const delay = (ms: number) => new Promise(_ => setTimeout(_, ms));
await expect(delay(2000).then(() => 1)).resolves.toBe(1);
});
Test cronjobs
try to add below test at the end ...
import { cron } from '@/tests/helpers/cron';
test('...', async () => {
await cron('*/5 * * * *', {
advanceTimersByTime: 5 * 60 * 1000
});
});