Automation Testing · Tests on Kubernetes
Why Every Automation Tester Should Learn Kubernetes in 2026
Quick summary — why automation testers should learn Kubernetes
Every automation tester should learn Kubernetes in 2026 because it changes how test suites run, not just where apps run. Kubernetes lets you package a suite as a Job, split it into parallel shards, run Selenium Grid or Playwright browsers in pods and create a short-lived environment per pull request. That means faster feedback and fewer conflicts on shared test servers.
In this guide you will learn:
- Test suites as Jobs — run once, report exit code, clean up.
- Parallel execution — Indexed Jobs with Playwright or pytest shards.
- Browsers in the cluster — Selenium Grid and Playwright containers.
- Ephemeral environments — a fresh namespace for each pull request.
- Interview questions — what SDET and automation interviews ask.
SECTION 01Running your automation suite as a Kubernetes Job
Most people meet Kubernetes through long-running apps managed by Deployments. Test suites are different: they should start, run every test, report pass or fail and stop. Kubernetes has a built-in object for exactly that, the Job. A Job creates one or more pods, waits for them to finish, and records whether they succeeded based on the container's exit code. Because Pytest, Maven and Playwright all exit with a non-zero code when tests fail, a Job naturally reports your suite result.
For an automation tester this is powerful. Instead of keeping a dedicated test machine with the right browser, driver and library versions, you build one container image with your framework inside and let the cluster run it on whatever node has spare capacity. Settings such as backoffLimit control retries, activeDeadlineSeconds stops a hung run, and ttlSecondsAfterFinished cleans up finished Jobs automatically.
| Job setting | What it does | Good value for tests | Why it matters |
|---|---|---|---|
| restartPolicy | What happens when the container exits | Never | Failed tests should not silently rerun |
| backoffLimit | How many failed pods before the Job fails | 0 or 1 | Retries can hide real failures |
| activeDeadlineSeconds | Maximum run time for the whole Job | A little above normal run time | Stops hung browsers wasting resources |
| ttlSecondsAfterFinished | Deletes the Job after it ends | A few hours | Keeps the namespace tidy |
# e2e-job.yaml - runs a pytest + Selenium suite once
apiVersion: batch/v1
kind: Job
metadata:
name: e2e-tests
spec:
backoffLimit: 0
activeDeadlineSeconds: 1800
ttlSecondsAfterFinished: 7200
template:
spec:
restartPolicy: Never
containers:
- name: tests
image: registry.example.com/qa/e2e-tests:1.3.0
command: ["pytest", "tests/e2e", "-q", "--junitxml=/reports/results.xml"]
env:
- name: BASE_URL
value: http://shop-frontend.qa.svc.cluster.local
- name: SELENIUM_REMOTE_URL
value: http://selenium-hub.qa.svc.cluster.local:4444
resources:
requests: { cpu: 500m, memory: 512Mi }
# Start the run
kubectl apply -f e2e-job.yaml -n qa
# Watch the pod being created and finishing
kubectl get pods -n qa -l job-name=e2e-tests -w
# Follow the test output
kubectl logs -f job/e2e-tests -n qa
# Wait for success (use in CI; returns non-zero on timeout)
kubectl wait --for=condition=complete job/e2e-tests \
-n qa --timeout=30m
# Did it pass?
kubectl get job e2e-tests -n qa \
-o jsonpath='{.status.succeeded}{" "}{.status.failed}'
SECTION 02Parallel runs: sharding Playwright and pytest across pods
A regression suite that takes a long time on one machine is a common complaint in automation teams. Kubernetes helps through Indexed Jobs. When you set completionMode: Indexed with, for example, four completions and a parallelism of four, Kubernetes starts four pods together and gives each a unique number in the JOB_COMPLETION_INDEX environment variable, from 0 to 3. Your test command uses that number to pick its share of the tests.
Playwright supports this directly with its --shard option, which takes a one-based value such as 1/4. For pytest you can use a sharding plugin or split by folder. Each pod runs independently, so total time is close to the slowest shard rather than the sum. The trade-off is that tests must be independent: no shared user accounts, no order dependency and no test that cleans data another test needs.
| Approach | How tests are split | Best for | Watch out for |
|---|---|---|---|
| Single Job, one pod | No split, one runner | Small smoke suites | Long runs as the suite grows |
| Indexed Job + Playwright --shard | Playwright divides tests by index | Large Playwright suites | Shared test data between tests |
| Indexed Job + pytest by folder | Index maps to a folder or marker | Python Selenium frameworks | Uneven folder sizes |
| pytest-xdist inside one pod | Worker processes in one container | Medium suites, simple setup | Pod CPU and memory limits |
# playwright-shards.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pw-regression
spec:
completionMode: Indexed
completions: 4
parallelism: 4
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: playwright
# Official image already contains the browsers
image: registry.example.com/qa/pw-tests:2.1.0
command: ["sh", "-c"]
args:
- >
npx playwright test
--shard=$((JOB_COMPLETION_INDEX + 1))/4
--reporter=blob
env:
- name: BASE_URL
value: http://shop-frontend.qa.svc.cluster.local
resources:
requests: { cpu: "1", memory: 1Gi }
# Dockerfile for the test image (based on the official Playwright image)
# FROM mcr.microsoft.com/playwright:v1.48.0-noble
# WORKDIR /tests
# COPY package*.json ./
# RUN npm ci
# COPY . .
# See each shard's output
kubectl logs -n qa -l job-name=pw-regression --prefix
# Blob reports from every shard must be copied to one place
# (shared volume or object storage), then merged:
npx playwright merge-reports --reporter=html ./all-blob-reports
# Check shard status: one pod per index
kubectl get pods -n qa -l job-name=pw-regression \
-o custom-columns=POD:.metadata.name,STATUS:.status.phase
SECTION 03Selenium Grid, Playwright browsers and ephemeral test environments
Selenium tests need browsers somewhere. The Selenium project publishes official container images and a Helm chart that deploys Selenium Grid on Kubernetes: a hub or router that receives WebDriver sessions and browser nodes for Chrome, Firefox and Edge. The chart can also integrate with KEDA to add browser nodes when sessions queue up and remove them when idle, so you are not paying for idle browsers. Your tests simply point RemoteWebDriver at the Grid service URL inside the cluster.
The bigger change is ephemeral environments. Instead of every tester sharing one QA server, the pipeline creates a new namespace for each pull request, deploys that branch of the app into it, runs the tests there and deletes the namespace afterwards. Nobody overwrites anyone else's data, and a failure clearly belongs to that one change. Automation testers who can script this flow become very valuable to their teams.
| Need | Kubernetes approach | What the tester controls | Benefit |
|---|---|---|---|
| Cross-browser Selenium runs | Selenium Grid Helm chart | Browser node types and counts | No local browser setup |
| Playwright without a Grid | Browsers inside the test image | Image version and shard count | Simple, self-contained runs |
| Isolated test data | Namespace per pull request | Seed data and teardown | No clashes between testers |
| Clean environment every run | Delete namespace after tests | Cleanup step in CI | No leftover state between runs |
# Install Selenium Grid with the official Helm chart
helm repo add docker-selenium https://www.selenium.dev/docker-selenium
helm repo update
helm install selenium-grid docker-selenium/selenium-grid -n qa
# Find the Grid service name and port
kubectl get svc -n qa
# Python test pointing at the Grid inside the cluster
from selenium import webdriver
opts = webdriver.ChromeOptions()
driver = webdriver.Remote(
command_executor="http://selenium-hub.qa.svc.cluster.local:4444",
options=opts,
)
driver.get("http://shop-frontend.qa.svc.cluster.local")
assert "Shop" in driver.title
driver.quit()
#!/usr/bin/env bash
# ephemeral-env.sh <pr-number> <image-tag>
set -euo pipefail
NS="pr-$1"
TAG="$2"
kubectl create namespace "$NS"
# Always clean up, even if tests fail
trap 'kubectl delete namespace "$NS" --wait=false' EXIT
helm install shop ./charts/shop -n "$NS" --set image.tag="$TAG"
kubectl rollout status deployment/shop-frontend -n "$NS" --timeout=5m
# Point the app URL at this namespace; keep the shared Grid in qa
sed "s/shop-frontend.qa.svc/shop-frontend.$NS.svc/" e2e-job.yaml | kubectl apply -n "$NS" -f -
kubectl wait --for=condition=complete job/e2e-tests -n "$NS" --timeout=30m
kubectl logs job/e2e-tests -n "$NS" > "e2e-$NS.log"
SECTION 04Templates: Job checklist, CI step and flakiness log
Use these when you move an existing Selenium, pytest or Playwright suite from a single test machine onto a Kubernetes cluster.
SUITE READINESS FOR KUBERNETES
Packaging
[ ] Test code and dependencies in one container image
[ ] Image tag pinned (no 'latest')
[ ] Base URL and Grid URL read from environment variables
[ ] No hard-coded localhost addresses
Independence (needed for sharding)
[ ] Each test creates its own data or uses unique users
[ ] Suite passes in random order
[ ] No test depends on another test's output
Reporting
[ ] Exit code non-zero when any test fails
[ ] JUnit XML or blob reports written to a known path
[ ] Reports copied to storage the CI can read
Resources
[ ] CPU and memory requests set for each pod
[ ] activeDeadlineSeconds set to stop hung runs
# .github/workflows/e2e.yml (CI step that runs tests in the cluster)
name: e2e
on: pull_request
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure cluster access
run: echo "${{ secrets.KUBECONFIG_QA }}" > kubeconfig
- name: Run tests in a fresh namespace
env:
KUBECONFIG: kubeconfig
run: ./ephemeral-env.sh ${{ github.event.number }} ${{ github.sha }}
- name: Save logs
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-logs
path: e2e-*.log
FLAKINESS LOG - track tests that behave differently in the cluster
Date | Test name | Shard | Failure | Root cause | Fix
-----|-----------|-------|---------|------------|----
| | | | |
Common causes to check:
- Fixed sleeps instead of waiting for elements
- Shared login account used by two shards
- Pod CPU limit too low, browser renders slowly
- App pod not Ready when tests started
- Timezone or locale different in container
Rule: a test that fails twice in this log without a
product bug gets fixed or quarantined before the next run.
SECTION 05Tips for automation testers learning Kubernetes
Focus on the parts of Kubernetes that make your test runs faster and more reliable:
- Start with Docker — get your suite running in a container locally before you think about Jobs or clusters.
- Learn Jobs before Deployments — for test execution, the Job object matters far more than long-running workloads.
- Make tests independent first — parallel runs only help when tests do not share data, order or accounts.
- Set resource requests — browsers are hungry; pods without enough CPU and memory create slow, flaky tests.
- Practise on kind — a local kind cluster is enough to try Jobs, Indexed Jobs and the Selenium Grid chart.
SECTION 06Interview Q&A — Kubernetes for automation roles
Q1Why would you run an automation suite as a Kubernetes Job instead of a Deployment?
A Deployment keeps pods running forever and restarts them if they exit. A test suite should run once and finish. A Job runs pods to completion and records success or failure from the exit code, which matches how test frameworks report results.
Q2How do you run tests in parallel on Kubernetes?
I use an Indexed Job with completions and parallelism set to the number of shards. Each pod gets a JOB_COMPLETION_INDEX value, which I pass to Playwright's --shard option or use to select a folder of pytest tests. Tests must be independent for this to work.
Q3How does Selenium Grid work on Kubernetes?
The official Helm chart deploys a hub or router that accepts WebDriver sessions and browser nodes that execute them. Tests use RemoteWebDriver pointed at the Grid service URL. With autoscaling enabled, browser nodes can scale with the session queue.
Q4What is an ephemeral test environment?
It is a short-lived environment created for one change, usually a namespace per pull request. The pipeline deploys that branch, runs tests against it and deletes the namespace afterwards, so tests never clash with other people's data or deployments.
Q5A test passes locally but fails only in the cluster. How do you investigate?
I check the pod logs and events, confirm the app was Ready before tests started, compare resource limits with what the browser needs, and look for differences such as timezone, screen size or network addresses. Then I reproduce in a local container.
SECTION 07Test yourself — Kubernetes for automation testers quiz
Five questions. No sign-up.
0 / 5Pick an answer to see why it is right or wrong.
SECTION 08Frequently asked questions
Do automation testers need Kubernetes skills for SDET jobs?
Many SDET and senior automation roles now expect some container and CI knowledge, and Kubernetes appears often where test infrastructure runs on clusters. It is rarely the main requirement, but being able to run and debug suites in a cluster is a clear advantage.
Can Playwright tests run inside Kubernetes?
Yes. Microsoft publishes official Playwright container images that include the browsers. You build your test image from one of them, run it as a Kubernetes Job and use Playwright's built-in sharding option to split large suites across several pods.
How do I run Selenium Grid on Kubernetes?
The Selenium project provides an official Helm chart in its docker-selenium repository. Add the chart repository, install the selenium-grid chart into a namespace, then point your RemoteWebDriver at the Grid service. Check the chart's documentation for autoscaling and browser options.
Is Docker enough for automation testers or is Kubernetes also needed?
Docker is the first step and is enough for running a suite in a container on one machine or in CI. Kubernetes becomes useful when you need many parallel runs, on-demand browsers or separate environments for each change across a team.
What is the best way to learn Kubernetes for test automation?
Containerise an existing test suite, install kind or minikube locally, run the suite as a Job, then convert it to an Indexed Job with shards. After that, try the Selenium Grid Helm chart and a small script that creates and deletes a test namespace.
SECTION 09Related reads
Classroom & online · Noida
Build automation frameworks that scale
Our Automation Testing Training Course covers Selenium, framework design, test execution in CI pipelines and the tools used by modern automation teams. Confirm the current syllabus with a counsellor.
Talk to a counsellor for current fees- Selenium & framework design
- CI pipeline integration
- 1:1 mock interviews
- Weekday & weekend batches