Residential Proxies Web Scraping API Turn Sites Into AI Data Automate 3000+ Apps Learn Python Automation Pay As You Go Proxies
Residential Proxies Web Scraping API
Pay As You Go Proxies 10 Free Proxies Antidetect Browser No Code Browser Bots Web Data For AI Agents Hire Scraper Builders

How to Automate Tests with Jenkins

Updated September 2026
Jenkins is the most widely deployed CI/CD server, used by organizations from startups to Fortune 500 companies for automated testing. Its self-hosted architecture gives teams complete control over hardware, security, and configuration, while its 1,800+ plugin ecosystem integrates with nearly every test framework, notification system, and deployment target. This guide shows you how to build a production-grade Jenkins pipeline that runs unit tests, integration tests, and browser tests on every commit.

Jenkins pipelines are defined in a Jenkinsfile, a text file committed to your repository alongside the code it builds and tests. Using a declarative syntax, the Jenkinsfile specifies which agents run the pipeline, what stages execute in what order, how test results are reported, and what happens when stages fail. This "pipeline as code" approach means your CI configuration is version-controlled, reviewable, and reproducible.

Create a Jenkinsfile

Add a file named Jenkinsfile (no extension) to your repository root. The declarative syntax starts with a pipeline block containing agent, stages, and post-build sections:

pipeline {
  agent any

  environment {
    NODE_ENV = 'test'
  }

  stages {
    stage('Install') {
      steps {
        sh 'npm ci'
      }
    }

    stage('Lint') {
      steps {
        sh 'npx eslint . --max-warnings=0'
      }
    }

    stage('Unit Tests') {
      steps {
        sh 'npx jest --ci --reporters=default --reporters=jest-junit'
      }
      post {
        always {
          junit 'junit.xml'
        }
      }
    }
  }

  post {
    failure {
      echo 'Pipeline failed. Check test results.'
    }
  }
}

The agent any directive tells Jenkins to run the pipeline on any available agent. The environment block sets environment variables for all stages. Each stage block defines a named step in the pipeline, and the post block after Unit Tests publishes JUnit XML results to Jenkins's built-in test reporting UI.

In Jenkins, create a new Pipeline job, set the pipeline definition to "Pipeline script from SCM," point it at your repository, and Jenkins will automatically find and execute the Jenkinsfile on every build trigger.

Configure Stages for Test Types

A complete testing pipeline has multiple stages that progressively increase in depth and execution time. Structure them as quality gates: each stage must pass before the next one runs.

pipeline {
  agent any

  stages {
    stage('Install') {
      steps {
        sh 'npm ci'
      }
    }

    stage('Static Analysis') {
      steps {
        sh 'npx eslint . --max-warnings=0'
        sh 'npx tsc --noEmit'
      }
    }

    stage('Unit Tests') {
      steps {
        sh 'npx jest --ci --coverage --reporters=default --reporters=jest-junit'
      }
      post {
        always {
          junit 'junit.xml'
          publishHTML(target: [
            reportDir: 'coverage/lcov-report',
            reportFiles: 'index.html',
            reportName: 'Coverage Report'
          ])
        }
      }
    }

    stage('Integration Tests') {
      steps {
        sh 'npx jest --ci --config jest.integration.config.js --reporters=default --reporters=jest-junit'
      }
      post {
        always {
          junit 'junit-integration.xml'
        }
      }
    }

    stage('E2E Tests') {
      steps {
        sh 'npm run build'
        sh 'npm start &'
        sh 'npx wait-on http://localhost:3000 --timeout 30000'
        sh 'npx playwright test'
      }
      post {
        always {
          publishHTML(target: [
            reportDir: 'playwright-report',
            reportFiles: 'index.html',
            reportName: 'Playwright Report'
          ])
        }
      }
    }
  }
}

Separate Jest configurations for unit and integration tests let you run different test directories with different settings (timeouts, environment variables, setup files). Integration tests might need longer timeouts and database connection strings. E2E tests need the application running, so the stage builds it, starts it as a background process, waits for it to be healthy, then runs Playwright tests.

Add Parallel Execution

Jenkins supports parallel stages within a parallel block. Use this when stages are independent and can run simultaneously:

stage('Test') {
  parallel {
    stage('Unit Tests') {
      agent { docker { image 'node:20' } }
      steps {
        sh 'npm ci'
        sh 'npx jest --ci --shard=1/2'
      }
      post {
        always { junit 'junit.xml' }
      }
    }
    stage('Unit Tests Shard 2') {
      agent { docker { image 'node:20' } }
      steps {
        sh 'npm ci'
        sh 'npx jest --ci --shard=2/2'
      }
      post {
        always { junit 'junit.xml' }
      }
    }
    stage('Security Scan') {
      agent { docker { image 'node:20' } }
      steps {
        sh 'npm ci'
        sh 'npm audit --audit-level=high'
      }
    }
  }
}

Each parallel stage runs on its own agent (Docker container in this example), executing independently. Jenkins waits for all parallel stages to complete before moving to the next sequential stage. If any parallel stage fails, the overall pipeline fails, but all parallel stages still complete so you see the full results.

For E2E test parallelism, shard Playwright tests across parallel stages the same way:

stage('E2E Tests') {
  parallel {
    stage('E2E Shard 1') {
      agent { docker { image 'mcr.microsoft.com/playwright:v1.47.0-noble' } }
      steps {
        sh 'npm ci'
        sh 'npx playwright test --shard=1/3'
      }
    }
    stage('E2E Shard 2') {
      agent { docker { image 'mcr.microsoft.com/playwright:v1.47.0-noble' } }
      steps {
        sh 'npm ci'
        sh 'npx playwright test --shard=2/3'
      }
    }
    stage('E2E Shard 3') {
      agent { docker { image 'mcr.microsoft.com/playwright:v1.47.0-noble' } }
      steps {
        sh 'npm ci'
        sh 'npx playwright test --shard=3/3'
      }
    }
  }
}

Set Up Docker Agents

Docker agents run each pipeline stage in a fresh container, ensuring consistent environments regardless of what is installed on the Jenkins server. The Docker Pipeline plugin lets you specify container images per stage:

pipeline {
  agent none  // No global agent, each stage specifies its own

  stages {
    stage('Backend Tests') {
      agent {
        docker {
          image 'python:3.12'
          args '-v $HOME/.cache/pip:/root/.cache/pip'
        }
      }
      steps {
        sh 'pip install -r requirements.txt'
        sh 'pytest --junitxml=results.xml'
      }
      post {
        always { junit 'results.xml' }
      }
    }

    stage('Frontend Tests') {
      agent {
        docker {
          image 'node:20'
          args '-v $HOME/.npm:/root/.npm'
        }
      }
      steps {
        sh 'npm ci'
        sh 'npx jest --ci'
      }
    }

    stage('E2E Tests') {
      agent {
        docker {
          image 'mcr.microsoft.com/playwright:v1.47.0-noble'
        }
      }
      steps {
        sh 'npm ci'
        sh 'npx playwright test'
      }
    }
  }
}

The args parameter mounts cache volumes into the container so pip and npm caches persist between builds. Microsoft's official Playwright Docker image includes all browser binaries and system dependencies, eliminating the need to install them during the build.

For integration tests that need databases, combine Docker agents with Testcontainers or use Docker Compose to start service dependencies. Mount the host's Docker socket (-v /var/run/docker.sock:/var/run/docker.sock) into the build container so Testcontainers can create sibling containers.

Configure Test Reporting

Jenkins has built-in support for JUnit XML test reports. The junit step parses XML report files and displays results in the Jenkins UI: pass/fail counts, individual test details, failure messages, duration trends, and flaky test detection.

Configure your test frameworks to output JUnit XML:

  • Jest: Install jest-junit (npm install --save-dev jest-junit) and add --reporters=jest-junit to the test command. Set JEST_JUNIT_OUTPUT_DIR=./reports to control the output location.
  • pytest: Use the built-in --junitxml=reports/results.xml flag.
  • Playwright: Add the junit reporter to playwright.config.ts: reporter: [['junit', { outputFile: 'results.xml' }]]
  • JUnit 5 / Maven: Maven Surefire automatically generates JUnit XML reports in target/surefire-reports/.

The HTML Publisher plugin adds rich HTML report hosting. Upload Playwright's HTML report, Jest's coverage report, or Allure reports as publishable artifacts that team members can browse directly from the Jenkins build page.

For teams managing Jenkins at scale, the Test Results Analyzer plugin provides cross-build test trends: which tests are failing most frequently, which have become flaky, and which consistently take the longest to run. These insights guide test suite maintenance and pipeline optimization.

Build Triggers

Jenkins supports multiple triggers for starting pipeline builds. The most common for continuous testing:

Webhook triggers: GitHub, GitLab, and Bitbucket can send webhooks to Jenkins when code is pushed or a pull request is opened. Install the GitHub Branch Source plugin (or equivalent for your platform) to automatically create pipeline jobs for each branch and PR. This is the standard approach for continuous testing because it reacts to every code change instantly.

Poll SCM: Jenkins checks the repository for changes on a schedule (for example, every minute). This is a fallback when webhooks are not available, but it adds up to a minute of delay and generates unnecessary load on both Jenkins and the repository server.

Scheduled builds: Use cron syntax to run pipelines on a schedule, for example nightly builds that run slower test suites, weekly security scans, or monthly performance benchmark runs that are too expensive for every commit.

Pipeline Best Practices

Keep Jenkinsfiles in the repository. Never configure pipeline logic through the Jenkins web UI. Pipeline-as-code in the repository is version-controlled, reviewable, and portable between Jenkins instances.

Use shared libraries for common logic. If multiple repositories have similar pipeline structures, extract shared steps into a Jenkins shared library. This centralizes pipeline logic and makes it easier to update across all projects.

Limit agent scope. Use agent none at the pipeline level and specify agents per stage. This prevents a single agent from being blocked for the entire pipeline duration and allows different stages to use different environments (Docker images, node labels).

Clean up workspaces. Jenkins workspaces grow over time with build artifacts, test reports, and cached files. Use cleanWs() in the post-build section to clean up, or configure workspace cleanup policies at the Jenkins level.

Set timeouts. Prevent hung builds from consuming agents indefinitely by setting stage-level timeouts:

stage('E2E Tests') {
  options {
    timeout(time: 15, unit: 'MINUTES')
  }
  steps {
    sh 'npx playwright test'
  }
}
Key Takeaway

A production Jenkins pipeline uses a declarative Jenkinsfile with sequential quality gates (lint, unit tests, integration tests, E2E tests), parallel execution for independent stages, Docker agents for reproducible environments, and JUnit XML reporting for test result visibility. Trigger builds via webhooks for instant feedback on every code change.