Escolasoft
Published in

Escolasoft

Strapi Jest Testing with Gitlab CI.

Edit. After publishing this article I was contacted by Strapi team which ended with this official tutorial as part of Strapi 3 documentation. Thank you Strapi team for that.
More examples are covered in the next article.

Recently I started working with amazing Strapi Headless CMS. After reading all the documentation I was quite shocked that there is not even one sentence about any kind of testing (unit, e2e, whatsoever) with that software. Also after reading comments in Github issues, Slack channel, Stack Overflow and similar resources I realised that this topic is very much neglected. This is really a shame and should be fix as soon as possible by Strapi team if they want this framework to be consider mature and professional.

Yet, I haven’t gave up on Strapi, still finding it as a great tool for rapid programming, one of the most promising in node.js world in terms of Headless CMSes. So I’ve decided to do a research on my own and write done straight forward tutorial on how to achieve easy testing. In this article I will cover topic of creating a simplest API endpoint — a heartbeat check and it’s unit test.

Installing new Strapi instance and dependencies.

I’m creating a new default settings Strapi instance by running command

yarn create strapi-app my-project --quickstart

which creates a default Strapi instance in my-project folder. Once this is done we need some additional npm packages, for jest testing purpose

yarn add --dev jest jest-junit junit supertest
  • jest is our testing framework
  • junit is required by Gitlab CI to display each test in Merge Request view
  • supertest will be used to test our heartbeat endpoint

Jest when called is switching NODE_ENV to test which requires additional Strapi environment configuration.

Copy contents of my-project/config/environments/production into my-project/config/environments/test and put some changes. Edit my-project/config/environments/test/database.json and add value "filename": ".tmp/test.db" — reason of that is that we want to have a separate sqlite database for tests, so our test will not touch real data. The whole file will look like this:

Strapi my-project/config/environments/test/database.json settings.

Getting Strapi instance for tests.

This part is one that people have most problem with, and it is the main reason this article is written.

I’ll create a folder tests where all the tests will be put and inside it, I’ll create another folder helpers where I’ll add main Strapi helper in file strapi.js. File my-project/tests/helpers/strapi.js contents is as follows.

Strapi instance helper for Jest tests.

This is all we need for writing a simple API endpoint unit test.

Heartbeat endpoint

Now let’s create a simple endpoint we’re going to test. Endpoint will serve simple purpose will expose /heartbeat GET request that will return Hello World . You can create this easily with Strapi CLI and the result will be as follows:

You can launch the app with npm run start and under http://localhost:1337/heartbeat you should see “Hello World”. This is an endpoint we’re going to unit test.

Jest unit endpoint test

I’ll write as simple Jest unit test that will test if the /heartbeat GET request is returning Hello World. Here is a test. Descriptions are in the comments.

my-project/tests/app.test.js

Have a look on beforeAll jest method where I call the helper mentioned in section above.

Thats the whole test, save it in file my-project/tests/app.test.js and run it with the command:

./node_modules/.bin/jest --detectOpenHandles

which should return an output similar to

Result of jest testing

and that’s it — you’ve just created a first unit test for Strapi.

Appendix. Continuous Integration

Those test are best used within the Continuous Integration environment. Here I’ll explain how to append this to Gitlab CI, yet it would be easy to implement into any CI framework.

First of all lets add our testing commands into package.json scripts sections:

"scripts": {
"develop": "strapi develop",
"start": "strapi start",
"build": "strapi build",
"strapi": "strapi",
"test": "./node_modules/.bin/jest --detectOpenHandles",
"test-ci": "./node_modules/.bin/jest --detectOpenHandles --forceExit --watchAll=false --reporters='jest-junit'"
}

which will allows us to run client test with npm run test and run CI test with npm run test-ci , please note a custom jest reporter jest-junit.

The JUnit testing framework has introduced a XML file format to report about the test suite execution. These XML files can be processed by programs like Jenkins to display results of the tests.

My intention is that each push of code will launch a Gitlab runner, that calls all of the tests and displays result of the tests in Merge Request view:

Results of tests in Gitlab Merge Request.

Only when all of the tests pass user can merge code. To achieve this you need to have Gitlab with working runner(s). Here is an example gitlab.yml configuration. You need to put this file in the main folder.

Strapi gitlab yaml configuration file for testing

After that code is pushed each next push will trigger a pipeline that will

  • Attach node:alpine docker with our files
  • Install dependencies npm install
  • Run test with npm run test-ci
  • Tests will generate junit.xml file
  • Junit file will be uploaded to gitlab and displayed as a test report
  • In case any test will fail, Merge Request report will give you exact details of which test failed and why
Example of success pipeline
Example of failure pipeline

What’s next

  • Here is mine github repository with some other straight forward example regarding more samples of unit testing in Strapi.
  • I’ve covered the simplest possible example, yet with more sophisticated cases you would need to write some more complex helpers. In my opinion this should be delivered as a part of Strapi out of the box.
  • Most components of Strapi are based on koa, web framework for node.js When there are no decent articles about testing for Strapi there are many on testing for koa — this is when you start if you want to write test for your controllers.
  • Code coverage is note covered in this article yet it is an essential part of Continuous Integration which is both supported by JUnit and Gitlab.

--

--

--

Stories from creative software house based in Poland, with a love for all web technology

Recommended from Medium

JSDoc in React, Express application

Code Reusability via CordaService— Engineering Principles on Corda

Learn GatsbyJS by creating a tourism site -4

Alibaba Clone Backend

Building Expense Tracker using D3 (Part-2)…

VueJS and Laravel API — Part 2

ES6 in action

Displaying notifications on a React app form

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mateusz Wojczal

Mateusz Wojczal

founder of Qunabu Interactive from Gdańsk, Poland. Full-stack web developer with over a dozen years of experience.

More from Medium

Implementing User Authentication with Auth0 in React

Host a NodeJS app with Firebase

Push Strapi to Heroku Using Github Repository

Add EJS to Nest.js Application