Our code base has grown significantly and we noticed that our build and deployment process took too long to complete. We even encountered memory exhausted errors before but we managed to split the tests to fix the issue. This time, we tweaked the Jenkins-X pipeline so that our tests are run in parallel.
npm tests
We already split our large tests by module so the npm run scripts look like this:
{
"scripts": {
// ... other scripts
"test:spec-module-1": "jest --config ./src/module-1/jest.json --runInBand",
"test:spec-module-2": "jest --config ./src/module-2/jest.json --runInBand",
"test:spec-module-3": "jest --config ./src/module-3/jest.json --runInBand",
"test:spec-module-4": "jest --config ./src/module-4/jest.json --runInBand",
// ... and more tests here
"test:spec-all": "<run all module tests here>"
"test": "npm run test:spec-all && npm run test:e2e",
}
}
The entry command for all the tests is this: npm test
based on this pipeline:
https://github.com/jenkins-x-buildpacks/jenkins-x-classic/blob/master/packs/javascript/pipeline.yaml
Our current setup runs for around more than 39 minutes due to this test running sequentially. Other jest
options end up with memory running out so we run our tests sequentially. We experimented on splitting it into few steps.
Grouping Tests
Since some modules are smaller than the others, we decided to just group the tests into bigger tests since we have around 20 modules. We end of with 7 test groups.
{
"scripts": {
// ... other scripts
"test:spec-group-1": "<run test for the group here>",
"test:spec-group-2": "<run test for the group here>",
"test:spec-group-3": "<run test for the group here>",
// ... and more tests here
"test:spec-all": "<run all group tests here>"
"test": "npm run test:spec-e2e",
}
}
Now that we have 7 test groups, we only run the e2e tests for the main entry script then override Jenkins-X pipeline to run the other tests in parallel.
Jenkins-X Pipeline Override
We added a pipeline override for our application using this template:
https://github.com/jenkins-x-buildpacks/jenkins-x-classic/blob/master/packs/javascript/pipeline.yaml
Reference: https://jenkins-x.io/docs/reference/pipeline-syntax-reference/
Key points:
- We need to override both
pullRequest
and therelease
pipeline - Both have the
npm-test
build steps - We need to add some steps after the
npm-test
to run all of our grouped tests
# jenkins-x.yaml
buildPack: typescript
pipelineConfig:
pipelines:
overrides:
- pipeline: pullRequest
stage: build
name: npm-test
steps:
- sh: CI=true DISPLAY=:99 npm run test:spec-group-1
name: npm-test-spec-group-1
- sh: CI=true DISPLAY=:99 npm run test:spec-group-2
name: npm-test-spec-group-2
- sh: CI=true DISPLAY=:99 npm run test:spec-group-3
name: npm-test-spec-group-3
- sh: CI=true DISPLAY=:99 npm run test:spec-group-4
name: npm-test-spec-group-4
- sh: CI=true DISPLAY=:99 npm run test:spec-group-5
name: npm-test-spec-group-5
- sh: CI=true DISPLAY=:99 npm run test:spec-group-6
name: npm-test-spec-group-6
- sh: CI=true DISPLAY=:99 npm run test:spec-group-7
name: npm-test-spec-group-7
type: after
- pipeline: release
stage: build
name: npm-test
steps:
- sh: CI=true DISPLAY=:99 npm run test:spec-group-1
name: npm-test-spec-group-1
- sh: CI=true DISPLAY=:99 npm run test:spec-group-2
name: npm-test-spec-group-2
- sh: CI=true DISPLAY=:99 npm run test:spec-group-3
name: npm-test-spec-group-3
- sh: CI=true DISPLAY=:99 npm run test:spec-group-4
name: npm-test-spec-group-4
- sh: CI=true DISPLAY=:99 npm run test:spec-group-5
name: npm-test-spec-group-5
- sh: CI=true DISPLAY=:99 npm run test:spec-group-6
name: npm-test-spec-group-6
- sh: CI=true DISPLAY=:99 npm run test:spec-group-7
name: npm-test-spec-group-7
type: after
After the update, we noticed a significant improvement in our deployment time. The downside is that it consumes more resources because it need to create more containers to run the tests in parallel.
It’s totally worth it!
Featured image by Pixabay: https://www.pexels.com/photo/action-asphalt-blur-cars-315934/