View all services
Talk to QA Advisor
Browse the Knowledge Hub211 resources
/Tools Library/Jenkins
Tools Library · We run this

Jenkins review: what it is, alternatives and tutorial

Jenkins is a free, self-hosted automation server under the MIT licence. Pipelines are written as code in a Jenkinsfile, run on agents you provide, and gain almost every capability through plugins, including JUnit result publishing, Docker agents and parallel test splitting. The current long-term support line, 2.580.1, was released on 30 September 2026 and needs Java 21 or 25.

QAble runs this tool on client engagements. The assessment below is from that experience.

last reviewed
13 October 2026
version covered
Jenkins 2.580.1 LTS
licence
Open source

Reviewed by Viral Patel

Co-Founder, QAbleLast reviewed 13 October 2026

At a glance

Jenkins at a glance

Official site
Vendor
CD Foundation
Category
CI/CD
Licence
Open source (MIT)
Platforms
Self-hosted, Docker, Kubernetes
Languages
Groovy
Integrates with
Git, Maven, Docker, Selenium, SonarQube
First released
2011
Version reviewed
Jenkins 2.580.1 LTS

Verdict

Our verdict on Jenkins

Strengths

  • Free under the MIT licence, with no limit on users, jobs, agents or build minutes
  • Runs anywhere you can start Java, including networks that cannot reach any hosted CI service
  • The junit step keeps per-test history and trends for every build, and marks failures UNSTABLE rather than FAILED
  • Declarative matrix and parallel stages fan a suite out across browsers, platforms or shards in one Jenkinsfile
  • More than 2,300 plugins cover almost every tool, test format and notification channel
  • Shared libraries let one team maintain pipeline code that every repository reuses

Weaknesses

  • You run the controller, agents, backups, upgrades and security patches yourself
  • Plugin updates can break each other, so upgrades need testing like any other release
  • Groovy runs on the controller, so complex pipeline logic hurts every build
  • No built-in flaky test detection or test-level retry; both come from build tools or plugins
  • Configuration drifts into the UI unless Configuration as Code is enforced from the start

Best for

Organisations that must keep builds inside their own network, on their own hardware, with no limits on what a job can reach: test environments behind a firewall, licensed devices, mainframe connectors or a lab of physical phones. For QA teams it is also strong where per-test history matters, because the JUnit plugin keeps results for every build and shows trends and failing tests over time without a paid add-on. It suits teams with Java and Maven suites, where the tooling around Jenkins is most mature.

Not for

A team whose code already lives on GitHub or GitLab and that has nobody to own a server. GitHub Actions or GitLab CI/CD give a working pipeline in minutes with no controller to patch, and for most product teams that is the better trade. Jenkins is also a poor fit for teams that want the pipeline file to be the whole story, since plugin versions and global settings live on the controller unless you deliberately move them into code.

Setup cost

Moderate. A container gives you a running Jenkins in minutes, and the setup wizard installs a sensible plugin set. A production setup takes days: agents separate from the controller, credentials, backups of JENKINS_HOME, Configuration as Code, a pinned plugin list and a shared library. For a test suite the first useful Jenkinsfile is short; making it reliable across parallel agents is the real work.

Maintenance burden

The highest of the CI tools we run, and the main argument against it. Each LTS release has to be tested with your plugin set, plugins update on their own schedules, and a controller left alone for a year becomes a security liability. Recent releases add their own work: 2.555.1 dropped Java 17, and 2.580.1 stopped bundling the JUnit plugin with the WAR. Budget a few hours a month for upgrades and treat the plugin list as code.

Honest limitations

Groovy in a Jenkinsfile runs on the controller, so heavy pipeline logic slows every build. Plugin quality varies, and some popular plugins have little maintenance. There is no built-in flaky test detection or automatic retry of failed tests: you add a retry flag in Maven or Gradle, or a plugin. Blue Ocean, the newer UI many tutorials show, has been deprecated since July 2026. And there is no hosted option from the project itself; someone always runs the servers.

How it works

What is Jenkins and how does it work?

One controller, many agents

A Jenkins installation is a controller and a set of agents. The controller serves the web UI, schedules builds, stores configuration and every build record under JENKINS_HOME, and holds credentials. Agents are machines, containers or Kubernetes pods that connect to it and run the actual steps. Out of the box Jenkins runs builds on the built-in node, the controller itself, and the security documentation says builds should run elsewhere, because a build on the controller has the same file system access as Jenkins. For test automation the split matters twice: browsers and devices belong on agents sized for them, and a crashing test run must not take the scheduler down with it.

The Jenkinsfile and where Groovy runs

Pipelines are defined in a Jenkinsfile kept in the repository, in either Declarative syntax, a structured block of stages, steps and post conditions, or Scripted syntax, which is open Groovy. Either way the Groovy itself executes on the controller, and only steps such as sh or bat run on an agent. Jenkins records the pipeline’s progress so a build can survive a controller restart. The consequence is spelled out in the official best practices: use Groovy as glue between steps, not as the place where work happens. Parsing large files or looping over thousands of items in Groovy consumes controller memory and slows every other build.

Everything is a plugin

Core Jenkins knows how to schedule work and store results. Git checkout, Pipeline itself, Docker agents, credentials binding, JUnit reporting and most of the UI arrive as plugins, each versioned and released independently through the update centre, with declared dependencies on each other and on a minimum core version. That model is why Jenkins integrates with almost anything, and also why upgrades need care: a core release can require newer plugins, and a plugin update can require a newer core. Release 2.580.1 stopped bundling the JUnit, Mailer and Matrix Project plugins in the WAR file, so they must be installed explicitly rather than assumed.

Test results become build data

The junit step reads JUnit-format XML, which Maven Surefire, Gradle, TestNG, pytest and most JavaScript runners can produce, and attaches the results to the build. Jenkins then shows a trend chart across builds, a page per failed test with its stack trace and output, and history for each test. A test failure marks the build and the stage UNSTABLE, shown in yellow, rather than FAILURE, so the UI separates a red build that could not run from a yellow build whose tests found problems. Because results live on the controller, retention settings decide how much history you keep and how much disk it uses.

Strengths

What it does well

Matrix builds for browser and platform coverage

A Declarative matrix defines axes such as browser and operating system, and Jenkins runs every combination in parallel as separate cells, each with its own agent, stages and post conditions. An excludes block removes combinations that make no sense. Adding a browser becomes a one-word change instead of a copied stage, and failFast true stops the other cells as soon as one fails when you would rather save agent time.

Timing-based test splitting

The Parallel Test Executor plugin’s splitTests step reads test durations from the last successful build and divides the suite into roughly equal groups, returned as inclusion or exclusion lists. Each group runs in its own parallel branch, and Maven Surefire picks up its list through excludesFile or includesFile. Balancing by measured duration rather than file count keeps the slowest branch close to the average, which is where parallel suites usually lose time.

Retries aimed at infrastructure, not tests

The retry step can take conditions: agent retries when the agent disconnects or is removed mid-build, and nonresumable retries after a controller restart interrupts a step. That lets a pipeline survive a lost cloud agent without also re-running genuinely failing tests. Stage-level retry and timeout options cover the rest, and a timeout on every test stage stops a hung browser from holding an executor all night.

Artefacts beside the results

archiveArtifacts stores screenshots, videos, HTML reports and logs with the build, and allowEmptyArchive keeps a passing run from failing because there was nothing to keep. Stash and unstash move files between stages and agents within one run, such as a built application handed to several test agents. Combined with buildDiscarder, which can keep artefacts for fewer builds than logs, storage stays predictable.

Shared libraries for consistent pipelines

A shared library is a Git repository of pipeline steps and variables that Jenkinsfiles load with @Library. A QA platform team can publish a runUiTests step that sets up the browser container, applies retries, publishes JUnit results and archives screenshots, and every product repository calls it in one line. Fixing reporting once then fixes it everywhere, which is the main way large Jenkins estates stay consistent.

Configuration as Code for the controller

The Configuration as Code plugin rebuilds a controller’s global settings, credentials references, agent clouds and security realm from a YAML file, by default $JENKINS_HOME/jenkins.yaml. Paired with a plugins list baked into a custom image with jenkins-plugin-cli, a controller becomes reproducible: lose it, rebuild it from Git. This is the single most effective defence against configuration that exists only in someone’s memory of the UI.

Pricing

Jenkins pricing and licensing

Jenkins is free and open source under the MIT licence. There are no tiers, no per-user or per-minute charges and no paid edition from the project itself. The cost is entirely operational: the servers or cloud instances for the controller and agents, storage for build history and artefacts, and the engineering time to upgrade, secure and maintain it. Commercial distributions and support exist from third parties, CloudBees CI being the best known, but they are separate products with their own pricing.

  • Licence: MIT, stated in the jenkinsci/jenkins repository. Each plugin carries its own licence, so check any plugin your compliance team cares about.
  • Free tier: everything. Any number of users, pipelines, agents and parallel builds.
  • Infrastructure: you pay for the controller, agents and disk. Browser and mobile suites need larger agents than unit tests, and parallel suites need several at once.
  • Elastic agents through the Kubernetes or cloud plugins keep idle cost down, at the price of more configuration.
  • Maintenance time is the largest hidden cost: LTS upgrades every few months, plugin updates, security advisories and backups.
  • Commercial support is available from third parties such as CloudBees, priced by them rather than by the Jenkins project.

Checked against the vendor’s own pages on 13 October 2026. Pricing changes; confirm on the official site before buying.

Getting started

Jenkins tutorial: getting started

Setup, step by step

  1. Run the LTS container image with a named volume for JENKINS_HOME so data survives restarts.
  2. Open port 8080, sign in with the initial admin password from the container, and install the suggested plugins.
  3. Install the JUnit and Docker Pipeline plugins if they are not already present.
  4. Add an agent with Docker available, and set the built-in node’s executors to 0.
  5. Commit a Jenkinsfile to the repository and create a Pipeline or Multibranch Pipeline job that points at it.
  6. Run the job and check the Tests tab shows results, then break a test on purpose and confirm the build turns UNSTABLE.

Install

docker run -d --name jenkins --restart=on-failure \
  -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts-jdk21
# initial admin password
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

A first example

// Jenkinsfile (Declarative Pipeline)
pipeline {
  agent {
    // Needs the Docker Pipeline plugin and Docker on the agent
    docker { image 'maven:3.10.0-eclipse-temurin-21' }
  }
  options {
    timeout(time: 30, unit: 'MINUTES')
    buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '10'))
  }
  stages {
    stage('Test') {
      steps {
        // Let test failures reach the junit step, which marks the build UNSTABLE
        sh 'mvn -B -Dmaven.test.failure.ignore=true verify'
      }
    }
  }
  post {
    always {
      junit testResults: '**/target/surefire-reports/TEST-*.xml, **/target/failsafe-reports/TEST-*.xml'
      archiveArtifacts artifacts: 'target/screenshots/**', allowEmptyArchive: true
    }
  }
}

What trips people up first

Getting test failures to show as test failures. If Maven exits non-zero when a test fails, the sh step fails, the build goes red and, unless the junit step sits in post always, no results are published at all, so the team sees a stack trace in the console instead of a list of failing tests. Pass -Dmaven.test.failure.ignore=true so Maven finishes, publish results in post always, and let the junit step mark the build UNSTABLE. The second early trap is the Docker agent: the docker block needs the Docker Pipeline plugin and an agent that can run Docker, not the controller.

In practice

Using Jenkins in practice

Structuring a test pipeline

Keep the Jenkinsfile short and declarative: checkout, build once, run test stages, publish. Split the suite into stages by cost so feedback arrives in order: unit tests, then API tests, then UI tests, each with its own timeout and its own junit call with a checksName so the stage that failed is obvious on the pull request. Use when conditions to run long regression stages only on the main branch or on a schedule, and a Multibranch Pipeline so every branch and pull request gets the same file. Put anything reusable, such as browser container setup or report publishing, in a shared library rather than copying it between repositories, and keep secrets in Jenkins credentials bound with withCredentials, never in the file.

Cross-browser runs with a matrix

A Declarative matrix turns one stage definition into parallel cells. Each cell gets its own agent and its own post section, so results publish per browser. Read the axis value in the shell as an environment variable, and pass it to the suite as a system property. Leave failFast off for regression runs, because you want to know every browser that fails, and turn it on for pull request checks where the first failure is enough.

pipeline {
  agent none
  stages {
    stage('UI tests') {
      matrix {
        axes {
          axis {
            name 'BROWSER'
            values 'chrome', 'firefox', 'edge'
          }
        }
        agent { label 'linux && docker' }
        stages {
          stage('Run') {
            options { timeout(time: 40, unit: 'MINUTES') }
            steps {
              // Single quotes: the shell expands $BROWSER, not Groovy
              sh 'mvn -B -Dbrowser=$BROWSER -Dmaven.test.failure.ignore=true verify'
            }
            post {
              always {
                junit testResults: '**/target/failsafe-reports/TEST-*.xml', checksName: 'ui-tests'
                archiveArtifacts artifacts: 'target/screenshots/**', allowEmptyArchive: true
              }
            }
          }
        }
      }
    }
  }
}

Handling flaky tests honestly

Jenkins has no built-in flaky test detection, so decide where retries live. The cleanest place is the build tool: Surefire and Failsafe accept rerunFailingTestsCount, rerun only the failed tests, and write flakyFailure entries into the XML so the flake is recorded rather than hidden. Use the Jenkins retry step only for infrastructure, with conditions such as agent(), so a lost agent is retried but a failing assertion is not. Set failOnFlakeCount in Surefire if you want a build to fail once flakiness passes a threshold, and review the flaky list weekly. A suite where reruns quietly turn red into green stops being a signal within a few months.

stage('API tests') {
  steps {
    // Retry only when the agent itself is lost, never on test failures
    retry(count: 2, conditions: [agent(), nonresumable()]) {
      node('linux && docker') {
        checkout scm
        // Surefire reruns failed tests up to twice and records them as flaky
        sh 'mvn -B -Dsurefire.rerunFailingTestsCount=2 -Dmaven.test.failure.ignore=true test'
        junit testResults: '**/target/surefire-reports/TEST-*.xml', checksName: 'api-tests'
      }
    }
  }
}

Scaling agents and splitting suites

Parallel stages only help when there are agents to run them, so capacity is the first decision. Static agents are simplest and suit physical device labs. The Kubernetes plugin creates a pod per build from a template and removes it afterwards, which suits browser suites that need a clean environment and spiky capacity. Once agents exist, balance the work: a matrix over browsers parallelises by configuration, while the splitTests step from the Parallel Test Executor plugin parallelises one long suite by measured duration, handing each branch an inclusion or exclusion list for Surefire. Keep shared state out of the suite first; parallel branches against one shared test database are the usual reason splitting makes a suite flakier.

Keeping the controller maintainable

Treat the controller as code. Build a custom image from the LTS tag with a plugins.txt installed by jenkins-plugin-cli, so plugin versions change through a pull request, and load global configuration from Configuration as Code. Upgrade on the LTS line, reading the upgrade guide for each release: 2.555.1 required Java 21 or 25, and 2.580.1 stopped bundling several plugins. Set buildDiscarder in every pipeline so test history and screenshots do not fill JENKINS_HOME. Replace Blue Ocean, deprecated since July 2026 with no further security fixes, with the Pipeline Graph View plugin. Back up JENKINS_HOME, and test restoring it, before every upgrade.

Pitfalls

Common pitfalls

Running builds on the controller

Why it happens: Jenkins ships with executors on the built-in node, so the first jobs run there and nobody moves them. Builds then share the controller’s memory and file system access, and a runaway browser suite can stall the scheduler or read its secrets.

The fix: Set the built-in node’s executors to 0 and run every build on agents. Label agents by capability, such as docker or android, and target labels rather than machine names.

Publishing test results only when the build passes

Why it happens: The junit step is placed after the test command in steps. When a test fails the command exits non-zero, the stage stops, and results are never published, which hides exactly the runs where they matter.

The fix: Call junit in post always, let the build tool finish with maven.test.failure.ignore or ignoreFailures, and let the junit step set UNSTABLE.

Upgrading an old controller straight to the latest LTS

Why it happens: Jenkins 2.555.1 and later refuse to run on Java 17, and 2.580.1 no longer bundles the JUnit, Mailer and Matrix Project plugins. A controller that skipped several LTS releases can come back without the plugins its jobs depend on.

The fix: Move to Java 21 or 25 first, list required plugins explicitly in plugins.txt, read each LTS upgrade guide in between, and rehearse the upgrade on a copy of JENKINS_HOME.

Doing real work in pipeline Groovy

Why it happens: Groovy feels like an ordinary programming language, so teams parse reports, transform JSON and loop over test lists inside the Jenkinsfile. All of it runs on the controller, which slows every build on the instance.

The fix: Move logic into scripts run with sh on the agent, or into a build tool plugin. Keep the Jenkinsfile as glue between steps, as the official best practices recommend.

Configuration that only exists in the UI

Why it happens: Clicking through Manage Jenkins is quick, so credentials, agent clouds and plugin choices accumulate with no record. Rebuilding after a disk failure, or reproducing a problem, becomes guesswork.

The fix: Adopt Configuration as Code and a version-controlled plugins.txt early, and treat any change made in the UI as a bug to be copied into Git.

Following tutorials built on Blue Ocean

Why it happens: Many guides still show Blue Ocean screens and its pipeline editor. It has been deprecated since July 2026 and will not receive further security fixes.

The fix: Uninstall Blue Ocean and use the Pipeline Graph View plugin for stage visualisation. Write Jenkinsfiles by hand with the Pipeline Syntax snippet generator rather than a visual editor.

Compared

Jenkins alternatives compared

ToolHostingPipeline definitionFree allowanceBuilt-in test report UIRetry optionsTest splitting
JenkinsSelf-hosted onlyJenkinsfile, Groovy-based DSLAll free; you pay for serversYes, with history and trendsretry step, with agent conditionsPlugin splits by previous test durations
GitHub ActionsGitHub-hosted or self-hosted runnersYAML in .github/workflows2,000 minutes a month on FreeNo; needs a marketplace actionRe-run failed jobs; no retry keywordMatrix jobs; you split the suite
GitLab CI/CDGitLab.com, self-managed or Dedicated.gitlab-ci.yml in the repository400 compute minutes a month on FreeYes, in merge requests and pipelinesretry: up to 2, by failure typeparallel: N with node index variables
Azure DevOpsMicrosoft-hosted or self-hosted agentsYAML pipelines in the repositoryOne hosted job, 1,800 minutes, enable firstYes, plus flaky test managementFlaky detection with VSTest rerunsparallel strategy with slice variables

FAQ

Frequently asked questions

What is Jenkins?

Jenkins is a free, self-hosted automation server under the MIT licence. Pipelines are written as code in a Jenkinsfile, run on agents you provide, and gain almost every capability through plugins, including JUnit result publishing, Docker agents and parallel test splitting. The current long-term support line, 2.580.1, was released on 30 September 2026 and needs Java 21 or 25.

What are the best Jenkins alternatives?

The alternatives most often weighed against Jenkins are GitHub Actions, GitLab CI/CD, Azure DevOps and CircleCI. The comparison on this page sets them side by side on hosting, pipeline definition, free allowance, built-in test report ui, retry options and test splitting, and the verdict above says where Jenkins is the wrong choice and which of them to pick instead.

Is Jenkins free?

Yes. Jenkins is open source under the MIT licence, with no paid edition, no user limits and no charge for build minutes. What you pay for is infrastructure and time: servers or cloud instances for the controller and agents, disk for build history and artefacts, and the hours spent upgrading, securing and backing it up. Third parties such as CloudBees sell commercial distributions and support, priced separately.

Jenkins or GitHub Actions for test automation?

If your code is on GitHub and your tests can run on hosted runners, GitHub Actions is less work: no server, workflows beside the code, and a matrix for browsers in a few lines. Choose Jenkins when builds must run inside your network, when you need per-test history without extra tooling, or when you already have a Jenkins estate and the people to run it. Many organisations run both, with Jenkins kept for jobs that need private infrastructure.

What changed in Jenkins 2.580.1 LTS?

Released on 30 September 2026, 2.580.1 stops bundling several plugins in the WAR, including JUnit, Mailer, Matrix Authorization Strategy, Matrix Project, OWASP Markup Formatter and the bouncycastle API, and refreshes the build status icons. Jenkins no longer installs those plugins automatically for very old upgrades, so check your plugin list. It also continues the Java 21 or 25 requirement introduced in 2.555.1. Read the LTS upgrade guide and test on a copy of JENKINS_HOME first.

How do I run tests in parallel in Jenkins?

There are three levels. Inside one agent, let the test framework parallelise, through Surefire forkCount or JUnit parallel execution. Across agents by configuration, use a Declarative matrix or parallel stages, for example one cell per browser. Across agents for one long suite, use the splitTests step from the Parallel Test Executor plugin, which divides tests by their previous durations. All three need tests that do not share mutable state.

How does Jenkins handle flaky tests?

Not by itself. Jenkins records results but has no built-in flaky detection or test-level retry. The usual approach is to rerun failed tests in the build tool, with Surefire’s rerunFailingTestsCount or Gradle’s test-retry plugin, which mark passes after a rerun as flaky in the XML. The Flaky Test Handler plugin can show those flaky results in Jenkins. Use the retry step only for infrastructure failures, with the agent condition.

Is Blue Ocean still supported?

No. Blue Ocean has been deprecated since July 2026 and will not receive further security fixes or feature updates. The Jenkins documentation points to the Pipeline Graph View plugin, which is actively maintained and covers the most used Blue Ocean views, such as the stage graph and step logs. Remove Blue Ocean from existing controllers rather than leaving an unpatched plugin installed.

Is Jenkins still worth learning in 2026?

Yes, for anyone working in enterprise QA. Jenkins runs a large share of existing build estates, including most Java automation suites, and those pipelines will need maintaining and migrating for years. The underlying ideas, agents, pipelines as code, artefacts and test result publishing, transfer directly to GitHub Actions, GitLab CI/CD and Azure Pipelines. For a new project with no constraints, learn a hosted CI first.

Should I use the LTS or the weekly release?

Use LTS for anything other than experimentation. The weekly line ships every week, 2.585 being current on 13 October 2026, and receives features first. An LTS baseline is chosen roughly every twelve weeks, stabilised, and receives backported fixes, which gives plugin authors and administrators a predictable target. Upgrade to each new LTS within a few weeks rather than skipping several.

Alternatives

Jenkins alternatives worth weighing

Resources

Where to go next

Ready

Picking the wrong tool costs more than picking late.

QAble advises on toolchain decisions and then implements them, with engineers who have run these tools on real delivery. Start with a free QA audit.

Talk to QA Advisor