Build & test stages

Compile, test, and fail fast.

Beginner12 min · lesson 9 of 15

The heart of any CI pipeline is two stages: build the code, then test it. The build stage compiles or packages the application; the test stage runs the suite. The golden rule is fail fast — order stages so the cheapest, most-likely-to-fail checks run first, and stop the pipeline the moment something breaks, so a developer gets a red signal in a minute rather than waiting ten for a slow end-to-end suite that a compile error already doomed.

Jenkinsfile
stages {
stage('Build') {
steps { sh 'npm ci && npm run build' } // any non-zero exit fails the stage
}
stage('Test') {
steps { sh 'npm test -- --ci' }
}
}

How Jenkins decides pass or fail

A sh step succeeds if its command exits 0 and fails on any non-zero exit code — that is the entire contract. So the way to make a test failure fail the build is simply to have the test command exit non-zero on failure, which every test runner does by default. Chaining commands with && ensures a step stops at the first failure rather than marching on and reporting green.

Publish results, do not just print them

Raw log output is hard to read; structured test reports are not. Have your test runner emit JUnit XML and publish it in a post block, and Jenkins renders a proper test-results view — counts, trends, and the exact failures — instead of making people scroll logs. The same goes for coverage and other reports: emit a machine format, publish it, get a UI for free.

Jenkinsfile
stage('Test') {
steps { sh 'npm test -- --reporters=jest-junit' }
post {
always { junit 'junit.xml' } // Jenkins shows pass/fail counts + trends
}
}
A test suite that cannot fail the build is theatre
The classic mistake is a test step that always exits 0 (a trailing "|| true", or a runner in a mode that swallows failures) — the pipeline stays green while tests are broken. Make sure a real test failure produces a non-zero exit and a red build; a green light that never means anything is worse than no CI at all.