Automated Testing in Jenkins

Automated Testing in Jenkins

A complete, plain-English guide to letting Jenkins check your software for you: what automated tests are, where they run, how results are collected and read, how to make them fast and trustworthy, and how to keep them from becoming a burden.

Imagine a bakery that sells five hundred loaves a day. Before opening, a baker tastes one loaf, checks the crust, feels the weight, and looks at the color. If something is wrong, the whole batch is stopped before a single customer is disappointed. Now imagine the bakery grows and bakes ten thousand loaves a day, in twenty ovens. No single person can taste every loaf. So the bakery builds machines that check weight, temperature and color on every tray, all day long, and sound an alarm the moment something drifts. Automated testing is that machine for software, and Jenkins is the factory floor that keeps the machine running on every change.

Writing software is a little like baking. Every change, however small, might spoil something that used to work. Checking by hand is slow, boring and easy to forget. Automated tests solve this by turning checks into small programs that run by themselves. Jenkins, an automation server, is the tool that runs those programs at the right moments, collects the results, shows them to the team, and stops bad changes from moving forward. In this guide you will learn what automated testing is, how the different kinds of tests fit together, how Jenkins runs and reports them, and how to keep your test suite fast, reliable and useful. Every new word is explained when it first appears, so you can read from top to bottom without stopping.

WWhat Is Automated Testing in Jenkins?

Automated testing means letting programs check your software for you, and Jenkins is the server that starts those programs, gathers their results and acts on them.

Start with the words. A test is a small check that answers one question about your software, such as “Does adding two items to the cart show the right total?” An automated test is a test written as a program, so a computer can run it without a human clicking around. A test suite is a large collection of such tests, run together. Jenkins is an automation server, a program that stays switched on and performs tasks when triggered. A job is the saved description of a task, and a build is one run of it. When Jenkins runs your tests, it does so as steps inside a build.

The important point is the division of labor. Jenkins does not know how to test your software. The tests themselves are written by developers and testers, using testing tools for the programming language in use. What Jenkins adds is everything around the tests: it decides when they run, chooses where they run, prepares a clean machine, fetches the right code, runs the test commands, collects the results, draws charts, sends messages and, most importantly, decides whether the change is good enough to continue.

Everyday Analogy

Think of a school exam. The teacher writes the questions, and that is the hard, creative part. The exam hall, on the other hand, decides the date and time, checks who is present, hands out the papers, collects the answer sheets, and posts the results on the wall. Jenkins is the exam hall. The tests are the questions. The hall does not write a single question, but without it no exam happens fairly and on time.

Because the tests run automatically on every change, problems are found within minutes, while the person who caused them still remembers what they were doing. This short distance between cause and discovery is the greatest gift of automated testing. A bug found ten minutes after it was written costs a moment to fix. The same bug found ten weeks later, in front of customers, costs a crisis.

i
Tip

A simple rule of thumb: if you find yourself checking the same thing by hand more than twice, it should probably be an automated test, and Jenkins should be the one running it.

Minutes
from change to test result
Every change
gets the same checks
Fail fast
bad changes stop early

What Jenkins does for your tests

When

Triggers the run

Starts tests on every code change, on every pull request, on a nightly timer, or before a release.

Where

Chooses the machine

Sends the work to an agent with the right tools, or creates a fresh container for a clean start.

What

Fetches the code

Downloads the exact version of the code that caused the run, so results are traceable.

How

Runs the test tools

Calls the test commands for each language and collects their output.

Result

Reads and records results

Turns raw report files into charts, trends and pass or fail counts stored with the build.

Action

Decides and tells

Marks the build unstable or failed, blocks a release, and notifies the right people.

HA Short History: From Manual Checks to Continuous Testing

Testing has moved from a slow phase at the end of a project into a constant background activity. Jenkins played a big part in that shift.

In older ways of working, software was written for months, and only afterward did a separate group of testers check it. Bugs found at that stage were expensive, because they were tangled up with months of other work, and fixing them delayed the release. Testers repeated the same manual checks every time, which was tiring and error-prone, and often the checks were quietly shortened when a deadline loomed.

Several ideas changed this picture. Developers began writing unit tests, small programs that check individual pieces of code. Teams adopted continuous integration, the habit of merging changes into a shared copy many times a day and building and testing each merge automatically. Build servers such as Hudson, later Jenkins, made that habit practical, because they could run the tests on every change without anybody remembering. Over time, test results became something teams watched daily, with charts and trends, rather than a report read once before release.

Everyday Analogy

Think of a smoke alarm compared with a yearly fire inspection. The inspector arrives once a year, finds many problems at once, and leaves. The smoke alarm is always on, and rings the moment the first wisp of smoke appears. Continuous testing turned software checking from the yearly inspection into the always-on alarm.

1

Testing at the end

A separate phase after all the code is written. Bugs are found late and are costly to fix.

2

Unit tests by developers

Developers write small automated checks alongside the code, and run them on their own computers.

3

Continuous integration servers

Hudson and then Jenkins run the tests on every shared change, so nobody has to remember.

4

Test reports and trends

Results are collected as standard report files and shown as charts, so teams watch health over time.

5

Pipelines and parallel testing

Tests become stages in a pipeline, run in parallel on many machines, and gate releases.

6

Containers and cloud test farms

Clean, throwaway environments and rented machines let teams test on many systems quickly.

!
A tool is not a habit

Installing Jenkins does not create good testing. Teams can run a Jenkins full of red builds that nobody reads. The tool makes testing easy to run, but the team must still write good tests and act on the results.

CCore Concepts You Need to Know

A small vocabulary explains nearly everything about automated testing in Jenkins. Learn these words once and the rest becomes easy.

Check

Test case

One small check with a clear expected outcome, such as “the total should be 30.”

Group

Test suite

A collection of test cases that are run together, often grouped by feature or by type.

Tool

Test framework

A library that helps write and run tests in a language. Jenkins calls the framework’s command.

File

Test report

A file the test tool writes, listing what passed, failed or was skipped. Jenkins reads it.

Status

Unstable build

A build that ran to the end but had failing tests. Shown in yellow, softer than a red failure.

Rule

Quality gate

A rule that stops the pipeline if quality is not good enough, such as too many failures or too little coverage.

Number

Code coverage

The share of code that the tests actually exercise. Useful as a hint, not as a goal by itself.

Trouble

Flaky test

A test that sometimes passes and sometimes fails on the same code. A quiet enemy of trust.

Job, build, stage, agent

A pipeline is a job whose work is divided into stages, named phases such as Build, Test and Deploy. Each stage contains steps. The test stage runs the commands that start your test tools. It runs on an agent, a separate machine or container, in a slot called an executor. The main server, the controller, keeps the queue, the settings and the results.

Everyday Analogy

A restaurant again. The head waiter (controller) takes the order. The kitchen station (agent) has cooks (executors). The recipe (pipeline) has sections (stages), and each line in the recipe is a step. A test stage is like the tasting station, where a taster checks each dish before it leaves the kitchen, and a bad dish is sent back before any customer sees it.

i
Tip

Keep a clear separation in your mind: the test tool decides if a test passes, and Jenkins decides what to do about it. This makes it easy to swap test tools without changing how Jenkins reports and reacts.

KThe Kinds of Automated Tests

Not all tests are alike. Each kind answers a different question, runs at a different speed and belongs at a different moment in the pipeline.

KindWhat it checksTypical speedWhen Jenkins runs it
Unit testOne small piece of code in isolationMilliseconds each, thousands in minutesOn every change
Integration testSeveral pieces working together, such as code with a databaseSeconds eachOn every change or every merge
API testThe public doorways of a service, called over the networkSeconds eachAfter a build is deployed to a test environment
End-to-end testA whole user journey through the real interfaceMany seconds to minutes eachAfter deployment to a test environment, often in parallel
Smoke testA tiny set of checks that the basics workUnder a minuteRight after every deployment
Regression testThat old features still work after new changesMinutes to hoursNightly or before releases
Performance testSpeed and capacity under loadMinutes to hoursScheduled, or before big releases
Security testKnown weaknesses in code and librariesMinutesOn changes, and on a schedule for new advisories
Static analysis and style checksCode quality rules, without running the programSeconds to minutesVery early, often first
Everyday Analogy

Think of checking a new car. Testing one bolt with a wrench is a unit test. Checking that the engine and gearbox work together is an integration test. Driving the whole car around a track, using the pedals and steering like a real driver, is an end-to-end test. Turning the key to see that the engine starts is a smoke test. Each check is useful, and you would never test a car with only one of them.

The test pyramid

Teams often picture their tests as a pyramid. At the wide bottom are many small, fast unit tests. In the middle are fewer integration and API tests. At the narrow top are a small number of slow end-to-end tests that drive the whole system. The idea is that most checking should happen cheaply and quickly at the bottom, and only the most important journeys should be checked at the top, because top tests are slow, fragile and expensive.

flowchart TD
    E2E["End-to-end tests: few, slow, whole journeys"]
    INT["Integration and API tests: some, medium speed"]
    UNIT["Unit tests: many, very fast, small pieces"]
    E2E --> INT
    INT --> UNIT
    STATIC["Static analysis: runs first, cheapest of all"]
    UNIT --> STATIC
Figure 1: The test pyramid, with the cheapest and fastest checks at the base.

Reading the diagram

Read from the bottom up. At the base, static analysis checks code quality without even running the program, so it is the cheapest and fastest. Above it sit the unit tests: many, very fast, each checking a small piece. Above them are the integration and API tests: fewer, because each takes longer and needs more setup. At the very top are the end-to-end tests: few, slow and expensive, reserved for the most important user journeys. In Jenkins, the same order becomes a sensible pipeline: run the cheap checks first, and only spend time on the expensive ones if the cheap ones pass.

!
The upside-down pyramid

Some teams end up with the pyramid upside down: almost no unit tests and a huge pile of slow browser tests. Their builds take hours, fail randomly, and nobody trusts them. If your test stage is slow and flaky, look first at whether too much is being checked at the top of the pyramid.

AArchitecture: How Jenkins Runs and Collects Tests

Behind a green or red test stage is a simple flow. Seeing it clearly makes every problem easier to place.

flowchart LR
    Dev["Developer"] -->|"push code"| SCM["Git Repository"]
    SCM -->|"webhook"| Ctrl["Jenkins Controller"]
    Ctrl --> Queue["Build Queue"]
    Queue --> Agent["Agent or Container"]
    Agent --> Code["Checkout of Code"]
    Code --> Tools["Test Tools and Frameworks"]
    Tools --> Rep["Test Report Files"]
    Rep -->|"published to Jenkins"| Ctrl
    Ctrl --> Res["Results, Charts and Trends"]
    Ctrl -->|"pass or fail"| Gate["Pipeline Decision"]
    Ctrl --> Chat["Email and Chat"]
    Agent --> Env["Test Environment or Test Database"]
Figure 2: From a code push to a recorded test result and a pipeline decision.

Reading the diagram

Follow the arrows. A developer pushes code to a Git repository, the shared home of the source code. The repository sends a webhook, a message, to the Jenkins controller, which places a request in the build queue. When an agent or container has a free executor, it takes the work, downloads the code, and starts the test tools and frameworks. The tools may talk to a test environment or a test database. When they finish, they write test report files. Jenkins reads those files, and the controller stores the results, charts and trends. The controller then makes a pipeline decision: continue, mark as unstable, or stop. Finally, it sends messages to email and chat.

Why agents and containers matter for testing

Tests are only trustworthy when they run in a clean, known environment. If a test passes on a developer’s laptop because of a leftover file, it may fail everywhere else. Running tests on agents, and preferably in short-lived containers created for each run, gives every test the same starting point. A container is a lightweight, sealed box holding a program and everything it needs. Because it is thrown away afterward, nothing carries over from one run to the next, and results are repeatable.

Everyday Analogy

Think of a science experiment. A good experimenter uses freshly washed glassware every time, because leftover chemicals would spoil the result. A container is freshly washed glassware for your tests. Each run starts spotless, so a surprising result can be trusted.

i
Tip

Keep tests off the Jenkins controller. Heavy test runs can slow the whole server, and test code, which may be untrusted, should never run beside the secrets stored there. Set the controller to zero executors and run tests on agents.

RTest Reports: How Jenkins Learns the Results

Jenkins does not watch your tests as they run. It reads the report files that the test tools leave behind.

Test tools write their results into report files. Many tools in many languages agree on a common format, an XML file structure originally made popular by a Java testing tool called JUnit. Because so many tools can write this format, Jenkins can read the results of tests written in almost any language, from one simple mechanism. Jenkins has a plugin, often called the JUnit plugin, that reads these report files after the tests finish and turns them into results attached to the build.

What Jenkins builds from the report

  • A summary. The number of tests that passed, failed and were skipped, shown on the build page.
  • A list of failures. Each failing test with its error message and stack trace, so you can start investigating at once.
  • Durations. How long each test took, so slow tests can be spotted.
  • A trend chart. A graph across builds showing passes and failures over time.
  • Comparisons. Which tests are newly failing, and which have been failing for many builds.
Everyday Analogy

Think of teachers who all fill in the same standard mark sheet, whichever subject they teach. The head teacher does not need to understand physics or poetry to compile the results. Because every sheet has the same layout, the results can be read, added up and charted easily. The common report format is that mark sheet.

Passing versus failing versus unstable

Jenkins has a special way of treating test failures. When the test command itself crashes, for example because the code does not compile, the build is marked as a failure, shown in red. When the tests run to the end but some of them report problems, the build is usually marked unstable, shown in yellow. This difference is useful: red means “the machinery broke,” and yellow means “the machinery worked, but the product has issues.” Teams can also choose to make test failures stop the pipeline entirely, which is a decision about quality rules, covered later.

OutcomeTypical colorMeaningWhat to do
SuccessBlue or greenEverything ran, and every test passedMove on
UnstableYellowEverything ran, but some tests failedOpen the test results and fix
FailureRedA step crashed, such as a compile error or a broken test commandRead the console log for the first error
AbortedGreySomeone or something stopped the build, such as a timeoutFind out why, and check for stuck tests
!
A green build with no tests

If the test tool finds no tests, some setups report success. A build that ran zero tests is not a healthy build. Make Jenkins fail, or at least warn, when the number of tests is suspiciously low, so a broken test setup cannot hide behind a green ball.

LThe Life of a Test Run, Step by Step

Every test run in Jenkins follows the same road, from a change in the code to a decision about what happens next.

flowchart TD
    A["Code change pushed"] --> B["Build queued"]
    B --> C["Agent prepared with clean workspace"]
    C --> D["Code checked out"]
    D --> E["Static checks and unit tests"]
    E -->|"pass"| F["Integration tests"]
    E -->|"fail"| X["Stop and report"]
    F -->|"pass"| G["Deploy to test environment"]
    F -->|"fail"| X
    G --> H["Smoke and API tests"]
    H --> I["End-to-end tests in parallel"]
    I --> J["Publish reports and coverage"]
    J --> K{"Quality gate met?"}
    K -->|"Yes"| L["Promote build to next stage"]
    K -->|"No"| X
Figure 3: A typical test flow with early stops and a final quality gate.

Reading the diagram

A code change enters the queue, and an agent prepares a clean workspace and checks out the code. The pipeline first runs the static checks and unit tests, which are quick. If they fail, the pipeline stops and reports at once, because there is no point running slow tests on broken code. If they pass, integration tests run, with the same early stop. Then the build is deployed to a test environment, where smoke and API tests check that the basics work, and the slower end-to-end tests run, often in parallel. After that, reports and coverage are published, and a quality gate asks whether the results are good enough. If yes, the build is promoted. If not, the pipeline stops and tells the team.

1

Trigger

A change, a pull request, a timer or a person starts the run. Jenkins records the reason.

2

Prepare

A clean agent or container is chosen, and the exact code version is fetched.

3

Cheap checks first

Style checks and unit tests run, giving feedback in minutes.

4

Deeper checks

Integration, API and end-to-end tests run against a real test environment.

5

Collect

Report files, screenshots, logs and coverage figures are published and saved.

6

Decide

Quality rules decide whether to continue, mark unstable or stop.

7

Tell

Messages go to the author and the team, and the record joins the build history.

i
Tip

Always publish test reports in a post section that runs even when the tests fail. If the report is only published on success, the failures you most need to see will never appear.

TTriggers: When Should Tests Run?

The right test at the right moment gives fast feedback without wasting machines.

TriggerWhat runsWhy
Every code pushStatic checks, unit tests, some integration testsFast feedback while the author is still focused
Every pull requestThe same quick set, plus key integration checksReviewers see a clear pass or fail before merging
Merge into the main lineA broader set, including deployment and smoke testsConfirms the shared code is healthy
Nightly scheduleThe full regression suite and slow end-to-end testsUses quiet machines and gives a fresh report each morning
Weekly schedulePerformance tests and deep security scansExpensive checks that need quiet, and catch newly announced weaknesses
Before a releaseEverything, including manual approval stepsThe final safety net
After a deploymentSmoke testsConfirms the new version actually started and works
Everyday Analogy

A hospital has different checks at different times. A nurse takes your temperature at every visit, which is quick. A blood test is ordered when needed, which takes longer. A full body scan is scheduled occasionally, because it is slow and costly. Testing in Jenkins follows the same rhythm: quick checks constantly, deeper checks regularly, and the deepest checks on a schedule.

Fast on change, deep on schedule

The most useful pattern is to split testing into two speeds. On every change, run a fast set that finishes in about ten minutes or less. This keeps developers in their flow. On a nightly or weekly schedule, run the deep, slow suites. The fast set catches the most common problems quickly, and the deep set catches the rare and subtle ones without holding anybody up. If the deep set finds a problem, the team reads the report in the morning and fixes it, and often adds a fast test that would have caught it earlier.

i
Tip

Use webhooks, not polling, so tests begin within seconds of a push. For scheduled runs, use the hash symbol in the schedule so that many jobs do not all start at the same minute and crowd the agents.

PSpeeding Up Tests: Parallel Runs and Smart Ordering

A test suite that takes two hours is a suite that people stop waiting for. Jenkins offers several ways to bring the time down.

Run tests in parallel

A pipeline can run several stages, or several slices of one big suite, at the same time on different agents. This is called parallel execution. If a suite of two thousand tests takes forty minutes on one machine, splitting it into eight equal groups on eight machines could bring it down to about five minutes, plus a little overhead. The picture in Jenkins shows the parallel branches side by side, and the whole stage finishes when the slowest branch finishes.

Everyday Analogy

Think of marking a pile of a thousand exam papers. One teacher would take days. Ten teachers, each marking a hundred, finish in an afternoon. Splitting the pile is parallel testing. The trick is to give each teacher a similar amount of work, so nobody is left marking long after the others have gone home.

Balance the groups

A common problem is unequal groups: one branch gets many slow tests, and the others finish early and wait. Good setups use the timing data from previous runs, which Jenkins can keep, to split tests into groups of similar total duration. Some tools do this automatically. Balanced groups make the best use of every machine.

Other ways to save time

Order

Cheap first

Run fast tests before slow ones, and stop at the first failure so no time is wasted.

Cache

Reuse downloads

Keep downloaded libraries between runs so each run does not fetch them again.

Select

Run only what changed

Where the tools allow, run only the tests related to the changed code on quick runs, and everything nightly.

Shape

Fix the pyramid

Move checks from slow top-level tests down to fast unit tests wherever possible.

Setup

Pre-built images

Use container images that already contain tools, so start-up takes seconds.

Cut

Delete dead tests

Remove tests for features that no longer exist, and merge duplicates.

!
Parallel is not magic

Tests that share a database, a file or a port can clash when run side by side, and fail in confusing ways. Before running in parallel, make tests independent: give each its own data and its own environment, or run those particular tests one after another.

ETest Environments and Test Data

Tests are only as reliable as the world they run in. A clean, predictable environment is half the battle.

Many tests need more than the code itself. An integration test may need a database. An end-to-end test may need the whole application running, with its web servers and services. Jenkins can prepare these environments in several ways. It can start containers for the database and the services just for this run, and throw them away at the end. It can deploy the build to a shared test environment. Or it can use a cloud environment created on demand, then destroyed after the run to save money.

Environment styleHow it worksStrengthsWatch out for
Throwaway containersEach run starts fresh containers for its needs, and deletes them afterClean, repeatable, cheapSlow start if images are large
Shared test environmentBuilds are deployed to one long-lived environmentClose to real life, simple to reachRuns can disturb each other, and state builds up
On-demand cloud environmentA full copy of the system is created for a run, then destroyedVery realistic and isolatedCost and setup time
Simulated servicesFake versions of outside services return prepared answersFast, and reliable when outside services are notThe fake can drift from the real thing
Everyday Analogy

Think of a driving test. A fair test happens on a marked course with the same conditions for every candidate. If one candidate got an empty road and another got rush hour, comparing them would be unfair. A clean test environment gives every run the same fair course.

Test data

Tests need data: customers, orders, products. Good practice is to let each test create the data it needs, and clean it up afterward, or to load a known, small set of data at the start of every run. Tests that depend on data left behind by other tests are fragile, because a change in order can break them. Never use real customer data in tests. It creates privacy risks, and it is not needed: made-up data works just as well.

!
Warning

Test logs and reports are stored in the Jenkins history and are read by many people. If tests use real customer details or real passwords, those secrets will spread. Use fake data, and keep real secrets in the Jenkins credentials store.

BBrowser and User-Interface Testing

Some tests act like a real user, clicking buttons and reading pages. They are valuable and tricky, and they deserve extra care.

An end-to-end test or user-interface test drives the real application through its screens. For a web application, this means a tool that controls a web browser: opening pages, typing into forms, clicking buttons, and checking what appears. On a build server nobody is looking at a screen, so these tests use headless browsers, browsers that run without a visible window. Some teams also run tests on many browsers and devices at once, using a shared collection of machines, or a cloud service that rents out browsers.

Everyday Analogy

Think of a mystery shopper who visits a store, walks the aisles, picks items, uses the checkout and reports on the experience. The shopper tests the whole store, not just one shelf. Browser tests are mystery shoppers for your application. They are powerful, but each visit takes a lot of time.

Why these tests are fragile

  • Timing. A page may load a little slower on a busy machine, and a test that clicks too soon fails.
  • Layout changes. A small change to a button’s name or place can break tests that look for it.
  • Shared state. Tests that log in with the same account can interfere with each other.
  • Outside services. Payment pages and email services can be slow or unavailable.
  • Machine differences. Screen size, fonts and browser versions can change how a page behaves.

Keeping them healthy

  • Keep them few. Test only the most important user journeys at this level, and cover the details with cheaper tests.
  • Wait for things, not for time. Tests should wait until an element appears, rather than sleeping for a fixed number of seconds.
  • Use stable identifiers. Give important elements fixed names for tests to find, so cosmetic changes do not break them.
  • Isolate accounts and data. Each test should use its own user and its own records.
  • Capture evidence. Save a screenshot, and if possible a recording, when a test fails, and archive them with the build.
i
Tip

A screenshot from a failed test is worth a thousand log lines. Archive screenshots for failed builds only, in a closing section that always runs, and let retention rules delete them after a couple of weeks.

QQuality Gates and Code Coverage

Running tests is only useful if the results change what happens next. Quality gates turn results into decisions.

A quality gate is a rule that a build must satisfy before it may continue. Examples include “no failing tests,” “coverage must not fall below the current level,” “no new serious security findings,” or “the number of code warnings must not grow.” When a gate fails, the pipeline stops, and the change cannot move on to the next stage or be merged. Jenkins can express these rules in a pipeline, and tools such as static analysis servers can supply the numbers.

Everyday Analogy

Think of a border checkpoint at an airport. Nobody boards the plane until passport, ticket and security checks are complete. A gate does not care how important your trip is. It applies the same rules to everybody. A quality gate is the checkpoint on the road to production.

Code coverage

Code coverage is a measurement of how much of your code is run by your tests. If coverage is eighty percent, the tests touch eighty percent of the lines. Coverage tools produce a report, and Jenkins plugins can show it as a chart and trend across builds. It is a helpful hint, because a part of the code that no test touches is certainly untested. But it is a poor goal by itself. A test that runs code without checking anything raises coverage without adding safety. Coverage tells you what is definitely not tested, and says less about what is well tested.

GateWhat it protectsCommon mistake
No failing testsBasic correctnessAllowing “known failures” to pile up until the rule means nothing
Coverage does not dropThe habit of testing new codeSetting a very high fixed number that encourages empty tests
No new serious warningsCode quality over timeBlocking on old warnings that nobody can fix at once
No high-severity security findingsSafety from known weaknessesIgnoring the findings list until a release deadline
Performance within limitsSpeed and capacityMeasuring on noisy machines and getting random results

Gates that help without hurting

The best gates are strict about new problems and gentle about old ones. Instead of demanding that a huge old project reach ninety percent coverage overnight, require that new and changed code is well covered and that overall coverage never falls. This keeps momentum without punishing teams for history they did not create.

!
Warning

Do not let a gate become a target that people game. If the only goal is a coverage number, people will write tests that check nothing. Pair gates with reviews, so tests are judged by what they verify, not only by what they touch.

FFlaky Tests: The Quiet Enemy

A flaky test is one that sometimes passes and sometimes fails, with no change in the code. It slowly poisons trust in the whole suite.

Imagine a smoke alarm that goes off randomly. At first, everyone runs outside. After a few false alarms, people stop reacting. Then one day there is a real fire. Flaky tests do the same to a team. When builds turn red for no reason, people learn to click “rebuild” and ignore the result, and eventually a genuine failure is ignored too.

Common causes

Time

Timing and waits

Tests that wait a fixed number of seconds, and sometimes the system is slower.

Order

Order dependence

Tests that only pass when another test ran before them.

Share

Shared state

Tests using the same database rows, files or ports at the same time.

Outside

External services

Tests that call real services over the internet, which are sometimes slow or down.

Clock

Dates and randomness

Tests that depend on today’s date, time zones or random numbers.

Machine

Resource pressure

Tests that fail only when a machine is short of memory or busy.

How to handle them

1

Detect

Use the test history to find tests that flip between pass and fail on the same code. Some plugins and tools list them automatically.

2

Quarantine

Move the flaky test into a separate group that runs, but does not block the pipeline, so the main suite regains trust while the fix is prepared.

3

Diagnose

Find the real cause: timing, shared state, order or an outside service.

4

Fix or delete

Repair the test, or remove it if it is not worth the trouble. A test that nobody trusts protects nobody.

5

Prevent

Write new tests independent of order and state, and wait for events, not for time.

!
Beware automatic retries

Retrying a failed test a few times can absorb a brief network hiccup, but it can also hide a real bug that only appears sometimes. If you use retries, count them, report them, and treat a test that needed a retry as a problem to fix, not as a success.

SSecurity and Automated Testing

Tests run real code with real permissions, and they touch many systems. That makes them both a security tool and a security risk.

Everyday Analogy

Think of a building inspector who carries master keys to check every room. Inspection makes the building safer, but the keys themselves must be guarded. Test runs in Jenkins carry keys to databases, services and servers, so they deserve the same care.

Testing for security

Jenkins can also run tests that look for weaknesses. Dependency scans check the libraries your project uses against lists of known problems. Static security analysis reads your code for risky patterns. Container image scans look inside your packaged software. Dynamic scans probe a running test copy of your application for weaknesses. Running these as pipeline stages, and blocking the pipeline on serious findings, turns security into an ordinary part of every build. Schedule them regularly as well, because new weaknesses are announced every day, even when your code has not changed.

Keeping the tests themselves safe

RiskWhy it mattersHow to reduce it
Secrets in test scripts or logsAnyone who reads the history can read the secretUse the credentials store, mask values, and never print secrets
Untrusted code from pull requestsStrangers’ tests run on your machinesRun outside contributions on isolated agents with no secrets and no network access to internal systems
Tests running on the controllerHostile code could read stored secretsKeep zero executors on the controller
Real data in test environmentsPrivacy breaches through logs and reportsUse made-up data, and scrub logs
Test environments open to the internetAttackers find weakly protected test systemsRestrict access and remove old environments
Over-broad test credentialsA leak gives wide accessUse least privilege and short-lived credentials
Outdated pluginsKnown weaknesses in the tooling itselfFollow advisories and update on a schedule
!
Warning

Never point automated tests at the live production database, and never give test jobs production credentials “just for now.” A single bad test could delete real customer data. Keep test and production worlds firmly apart.

MMonitoring, Logging and Metrics for Testing

A test suite is a living thing. Watching its health keeps it fast, honest and useful.

Everyday Analogy

A gym keeps records of your progress: how much you lift, how far you run, how long you rest. Without records, you only feel that you are getting fitter or slower. Test metrics are the progress chart for your suite.

MeasurementWhat it tells youTypical action
Pass rate over timeOverall health of code and testsInvestigate falling trends
Total number of testsWhether tests are being added, or silently lostAlert on sudden drops
Suite durationWhether feedback is getting slowerParallelize, cache, and clean up
Slowest testsWhere the time goesFix or move the slowest few
Flaky rateHow much trust the suite has lostQuarantine and repair
Coverage trendWhether new code is being testedSet a gate for new code
Time to fix a failing buildHow quickly the team respondsImprove alerts and ownership
Queue wait time for test jobsWhether there are enough agentsAdd agents or spread schedules

Logs that help

When a test fails, the log should tell a clear story: which test, what was expected, what actually happened, and, for browser tests, where the screenshot is. A test that only says “failed” wastes everyone’s time. Write clear failure messages, print helpful context, and keep the log short enough to read. Never print secrets or personal data in test output.

Metrics tools and long-term views

Jenkins shows trends for recent builds, but old builds are deleted by retention rules. To watch health over months, send numbers to a monitoring system. A common setup lets Prometheus, a widely used metrics collector, gather figures such as pass rate and duration, while Grafana draws charts and raises alerts. Other tools specialize in showing test results across many builds, with history, flaky lists and dashboards. Whichever you use, keep long-term numbers outside Jenkins, so cleaning old builds never erases your trends.

i
Tip

Alert on a sudden drop in the number of tests, not only on failures. If the count falls from five thousand to fifty, something is wrong, and the failure count will look wonderfully low.

AAdvantages, Disadvantages and Trade-offs

Automated testing is one of the best investments a team can make, and it also has real costs.

Advantages

  • Problems are found within minutes, while the change is still fresh
  • The same checks run every time, without tiredness or forgetting
  • Safe to change code, because tests catch accidental breakage
  • Results, trends and history are recorded automatically
  • Releases become smaller, more frequent and less stressful
  • Tests act as living documentation of what the software should do
  • Scales with the team, by adding agents and parallel runs

Disadvantages

  • Writing and maintaining tests takes real time and skill
  • Slow suites delay feedback and frustrate people
  • Flaky tests destroy trust if left alone
  • Machines, environments and licenses cost money
  • Tests can give false confidence if they check little
  • Test environments need care, data and cleanup

Trade-offs to think about

Fast vs thorough

How much per change

More tests give more safety but slower feedback. Run a quick set on every change and a deep set on a schedule.

Real vs fake

Outside services

Real services are realistic but unreliable. Fakes are fast and stable but can drift from reality.

Shared vs fresh

Environments

Shared environments are cheap but messy. Fresh ones are clean but cost setup time.

Strict vs flexible

Quality gates

Strict gates protect quality but can block urgent fixes. Gates on new code balance both.

Depth vs breadth

Test levels

Many unit tests are cheap, while a few end-to-end tests cover whole journeys. Use both in proportion.

Retry vs fix

Flaky handling

Retries hide symptoms, and fixes remove causes. Prefer fixes, and count every retry.

DDesign Patterns and Anti-patterns

A pattern is a proven way to solve a common problem. An anti-pattern is a habit that looks fine and causes pain later.

Patterns worth copying

Pattern

Fail fast

Run cheap checks first and stop at the first failure.

Pattern

Test pyramid

Many small tests, some medium, few large. Keep the shape.

Pattern

Fast on change, deep on schedule

Quick checks per push, heavy suites nightly.

Pattern

Throwaway environments

Fresh containers for each run, deleted afterward.

Pattern

Publish reports always

Use a closing section so reports appear even when tests fail.

Pattern

Quarantine flaky tests

Isolate unreliable tests until they are fixed.

Pattern

Build once, test that exact file

Test the same artifact that will be released, not a rebuilt copy.

Habits to avoid

ANTI-PATTERN 01Avoid
What it looks like

The team relies almost entirely on slow browser tests, with very few small tests underneath.

Why it hurts

Builds take hours, fail randomly, and give vague clues about what broke. People stop waiting for results.

Do this instead

Push checks down the pyramid. Cover details with unit and integration tests, and keep only key journeys in the browser.

ANTI-PATTERN 02Avoid
What it looks like

Red builds are ignored, and the team says, “That one always fails; just rebuild.”

Why it hurts

Real failures hide among the false ones, and trust in the suite disappears.

Do this instead

Treat every red build as a problem. Fix or quarantine flaky tests at once, and name an owner for the suite.

ANTI-PATTERN 03Avoid
What it looks like

Tests share one database and depend on data left by earlier tests.

Why it hurts

Results change with the order of tests, and parallel runs collide. Failures are impossible to reproduce.

Do this instead

Give each test its own data, or reset the environment before each run.

ANTI-PATTERN 04Avoid
What it looks like

Tests are deleted or skipped to make a failing build turn green before a deadline.

Why it hurts

The green ball says nothing anymore, and the hidden problem ships to customers.

Do this instead

Fix the problem, or make a visible, tracked decision to accept the risk. Alert when the test count drops.

ANTI-PATTERN 05Avoid
What it looks like

Test reports are published only when the build succeeds.

Why it hurts

The failing tests, the most important ones, leave no trace in Jenkins, and investigators have only a raw log.

Do this instead

Publish reports and screenshots in a closing section that always runs.

ANTI-PATTERN 06Avoid
What it looks like

The team chases a coverage number, adding tests that run code but check nothing.

Why it hurts

Coverage looks wonderful, yet bugs still slip through. The number stops meaning what people think it means.

Do this instead

Review what tests verify, and use coverage only to find code that no test touches.

BBest Practices and Common Mistakes

These are lessons that experienced teams usually learn the hard way. You can learn them the easy way, by reading them now.

Best practices

  • Keep the feedback loop short. Aim for results on every change within about ten minutes.
  • Run cheap tests first. Stop early, and save the expensive tests for changes that pass the basics.
  • Keep tests independent. Each test should set up its own data and not rely on another test.
  • Use clean environments. Fresh containers and known test data make results repeatable.
  • Publish reports always. Use a closing section so results and evidence are saved even on failure.
  • Save evidence. Keep screenshots, logs and recordings for failed runs, and delete them on a schedule.
  • Use timeouts. A stuck test should stop itself, not block an executor all night.
  • Watch flaky tests. Track them, quarantine them, and fix them quickly.
  • Gate on new code. Be strict about new problems and gentle about old ones.
  • Keep secrets safe. Use the credentials store and made-up test data.
  • Test the artifact you will ship. Build once, and run tests against that exact package.
  • Give the suite an owner. A named person or team who cares about its health keeps it healthy.

Common mistakes

  • Testing only at the end. Late feedback is slow and costly.
  • Making the suite too slow. People stop running it, or stop waiting for it.
  • Ignoring the test count. Silent loss of tests hides problems.
  • Trusting a green ball blindly. A build that ran no tests is green too.
  • Running tests on the controller. It slows the server and risks secrets.
  • Using production data or credentials. The risk is far bigger than any benefit.
  • Depending on outside services. Real services make tests flaky. Use fakes for most tests.
  • Writing tests nobody reads. A failing test should name what broke and how to find it.
i
Tip

Pick one project and make its testing excellent first: fast feedback, clean environments, clear reports, few flaky tests and a sensible gate. Then use that project as a template for others. A good example spreads faster than a long rulebook.

A worked example: a test plan for one small team

Imagine a team of eight building a web shop. On every push, Jenkins runs static checks and about two thousand unit tests, finishing in under five minutes, and publishes the results even when they fail. On every pull request, it also runs integration tests against a throwaway database container, taking about eight minutes in total, and the pull request shows a clear pass or fail mark. When a change is merged into the main line, the pipeline builds the package once, deploys it to a test environment, runs smoke tests, and then runs the browser tests for the six most important user journeys in parallel on four agents. Screenshots from failures are archived for two weeks.

Every night, during a hash-chosen time between one and four in the morning, the full regression suite runs, along with a dependency scan. Every weekend, a performance test runs on a quiet environment. A quality gate blocks any change that lowers coverage on new code or adds a serious security finding. A dashboard shows pass rate, duration and flaky tests, and an alert fires if the number of tests suddenly drops. Notice what this plan achieves: fast feedback where it matters, deep checks where time allows, clean and repeatable environments, and protection against silent decay.

TTroubleshooting: When Tests Misbehave

Sooner or later a test fails mysteriously, hangs, or passes for the wrong reasons. A calm routine finds the cause quickly.

A simple routine for a failing test

1

Find which test failed

Open the test results on the build page. The failing tests are listed with their messages and durations.

2

Read the message and the trace

The expected and actual values often explain the problem at once. Read the first error, not the last.

3

Ask the three questions

Did the code change? Did the environment change? Is the test unreliable? Most failures fall into one of these groups.

4

Compare with the last good build

Read the changes list between the last success and the first failure. The culprit is usually in that short list.

5

Reproduce and fix

Run the failing test locally or in a clean container, fix the cause, and confirm the next build turns green.

Common situations and their usual causes

SymptomLikely causeWhat to check
Passes locally, fails in JenkinsDifferent tool versions, leftover files, or missing settingsVersions, clean workspace, environment variables
Fails sometimes with no code changeFlaky test: timing, shared state or outside serviceTest history, waits, shared data
Build is green but no results appearReport path wrong, or tests did not runReport pattern, test count, tool output
Tests hang until the timeoutWaiting for input, a locked resource or a dead serviceLast log lines, service health, timeouts
Suite is suddenly much slowerNew heavy tests, cold caches or a busy agentSlowest tests, cache use, agent load
Failures only on one agentThat agent differs in tools, memory or diskAgent history and setup
Parallel runs clashShared database, file or portIsolation of data and ports
Failure count fell but total fell tooTests were skipped or removedTotal and skipped counts
i
Tip

Before you rebuild a failed build, write down why it failed. A rerun that turns green hides the lesson, and the same problem will return at a worse moment.

RReal-World and Industry Examples

Automated testing in a build server is now standard practice across nearly every industry. Here is how the ideas look in practice.

Large engineering organizations

Companies with thousands of developers run enormous test suites, split across many machines. They rely on the pyramid, fast checks on every change, and deep suites overnight. Platform teams measure duration and flaky rates as carefully as any product metric, because a slow or unreliable suite costs thousands of developer hours.

Online shops and payment services

Businesses that handle money test the most important journeys, such as adding to the cart and paying, on every release, using fake payment services in test environments. A single broken checkout can cost a great deal of money in minutes, so these smoke and end-to-end checks run after every deployment.

Mobile app teams

Teams building phone apps run tests on many devices and system versions, often on shared device farms or rented cloud devices. Jenkins starts the runs, collects the results from each device, and shows which models fail, so problems on one brand of phone are found before customers report them.

Regulated industries

Banks, hospitals and telecom providers must prove that software was tested before release. Jenkins records which tests ran, on which code, with which results, and who approved the release. This record becomes evidence for auditors, often exported to long-term storage.

Open-source projects

Public projects usually test every pull request automatically, and show a green or red mark beside it. Contributors learn within minutes whether their change breaks anything, and maintainers merge with confidence. Automated tests are the reason thousands of strangers can safely contribute to one codebase.

Small teams and startups

A team of five may run only unit tests and a few smoke tests on one small Jenkins server. Even so, every change is checked within minutes, and a red mark stops a bad change before it reaches customers. As the team grows, they add integration tests, parallel runs and nightly suites, step by step.

Lessons that repeat across teams

Look across these examples and a few lessons appear again and again. Successful teams keep the feedback loop short, and treat test speed as a feature. They keep the shape of the pyramid, with many small tests and few large ones. They run tests in clean, repeatable environments. They treat flaky tests as urgent, because trust is the most valuable thing a suite holds. They gate on new problems, protect secrets, and watch trends, not only single results. And they give the suite an owner who cares. None of this needs a large budget. A small team can follow every one of these habits from the first week.

Tests are only as valuable as the trust the team places in them. Guard that trust, and the tests will guard your software.

FFrequently Asked Questions

Q1What is automated testing in Jenkins, in the simplest words?
It is letting Jenkins run your test programs automatically on every change, collect the results, show them to the team, and stop bad changes from moving forward.
Q2Does Jenkins write or run the tests itself?
Jenkins does not write tests. Developers and testers write them using testing tools. Jenkins starts those tools, reads their report files and decides what to do with the results.
Q3How does Jenkins know which tests passed or failed?
Test tools write report files in a common format, and a Jenkins plugin reads them after the tests finish. It then shows counts, lists of failures, durations and trends on the build page.
Q4What does an unstable build mean?
It means the build ran to the end, but some tests failed. It is shown in yellow, and is different from a red failure, which means a step crashed. Teams can also choose to stop the pipeline on any test failure.
Q5Which tests should run on every code change?
The fast ones: static checks, unit tests and a small set of integration tests, ideally finishing within about ten minutes. Slower suites run on merges, nightly or weekly.
Q6What is the test pyramid?
A way of picturing a healthy suite: many fast unit tests at the base, fewer integration tests in the middle, and a small number of slow end-to-end tests at the top.
Q7How can I make my tests faster?
Run them in parallel on several agents, balance the groups by timing, run cheap tests first, reuse cached downloads, push checks down to unit tests, and delete tests that no longer matter.
Q8What is a flaky test and why does it matter?
A flaky test sometimes passes and sometimes fails on the same code. It matters because it teaches people to ignore red builds, and then a real failure is ignored too. Detect, quarantine and fix flaky tests quickly.
Q9What is a quality gate?
A rule that a build must satisfy to continue, such as no failing tests, no drop in coverage on new code, or no serious security findings. If the rule fails, the pipeline stops.
Q10Is high code coverage the same as high quality?
No. Coverage shows how much code the tests run, not how well they check it. Use it to find code that no test touches, and review what tests actually verify.
Q11Should tests run on the Jenkins controller?
No. Run tests on agents, ideally in throwaway containers. Tests on the controller can slow the whole server and put stored secrets at risk.
Q12Why does a test pass on my laptop but fail in Jenkins?
Usually because of different tool versions, leftover files on your laptop, missing settings, or timing differences. Run the test in a clean container to find the difference.
Q13Can Jenkins test on many browsers or devices?
Yes, by running the same tests in parallel on different agents, browsers or devices, using shared machines or rented cloud services, and collecting all results in one build.
Q14Is it safe to use real customer data in tests?
No. Test logs and reports are stored and read by many people, so real data can leak. Use made-up data and keep real secrets in the credentials store.
Q15What should I do first if my test suite is slow and unreliable?
Measure. Find the slowest tests and the flakiest ones, quarantine the flaky ones, split the suite into a fast set and a deep set, and push checks down the pyramid. Improve one thing at a time and watch the trends.

SSummary and Key Takeaways

Automated testing in Jenkins turns quality from a hope into a habit that runs on every change.

Key Takeaways

  • What it is: Test programs written by your team are run automatically by Jenkins on every change. Jenkins chooses when and where, collects the results, shows them, and decides what happens next.
  • How results flow: Test tools write report files in a common format, Jenkins reads them, and the build page shows counts, failures, durations and trends. Failing tests usually make a build unstable, and quality gates can stop the pipeline.
  • Shape your tests: Follow the test pyramid: many fast unit tests, fewer integration tests, and a few end-to-end tests. Run cheap checks first and stop early on failure.
  • Two speeds: Run a fast set on every change, in about ten minutes, and a deep set nightly or weekly. Use webhooks for instant starts and the hash symbol to spread schedules.
  • Go faster safely: Use parallel runs with balanced groups, caches and clean throwaway containers. Make tests independent so parallel runs do not clash.
  • Protect trust: Detect and quarantine flaky tests, count retries, alert on falling test counts, and publish reports and screenshots even when tests fail.
  • Stay safe and watch health: Keep tests off the controller, use fake data and the credentials store, gate on new problems, and track pass rate, duration and coverage over time in a metrics system.