CI/CD, Cloud & Deployment for QA/SDET โ Concepts + Interview Q&A¶
The DevOps/cloud knowledge a QA/SDET needs for interviews โ explained in simple words, with model answers. You don't need to be a DevOps engineer; you need to run tests in pipelines, containerize, understand cloud basics, and speak the vocabulary.
Do the hands-on alongside this:
../cicd-cloud-lab/โ a runnable app + tests + GitHub Actions CI/CD + cloud-deploy steps. Reading teaches; building sticks.
The realistic goal (what interviews actually want from QA)¶
Be able to: (1) run your tests in a CI pipeline and gate the build, (2) containerize with Docker, (3) understand cloud basics and test an app deployed there, (4) do a smoke test after deploy. That's it. Depth beyond that is a bonus.
PART 1 โ CI/CD¶
The three terms (don't mix them up)¶
- CI (Continuous Integration): every code push is automatically built and tested. Goal: catch breakage within minutes of a commit. In plain words: a robot runs your tests on every change.
- CD (Continuous Delivery): every change that passes CI is automatically prepared and deployable to production at the click of a button (a human approves the release).
- CD (Continuous Deployment): goes one step further โ every change that passes automatically ships to production with no human step.
Remember: CI = test every change; Continuous Delivery = one-click release; Continuous Deployment = zero-click release.
A pipeline = a series of stages¶
A typical pipeline: Checkout โ Build โ Lint/Static analysis โ Unit tests โ Package (build artifact/image) โ Deploy to staging โ Smoke/Integration tests โ Deploy to prod โ Post-deploy checks. Each stage must pass before the next runs.
Key vocabulary (define these crisply)¶
- Trigger / event: what starts the pipeline (a push, a pull request, a schedule, a manual "dispatch").
- Job / step: a job is a unit of work run on a fresh machine (a "runner"); steps are the commands inside it.
- Artifact: a file the pipeline produces and saves โ a test report, a built binary, a Docker image.
- Gate / quality gate: a pass/fail check that blocks progress โ e.g., "tests must pass," "coverage โฅ 80%," "no critical security findings." Failing a gate stops the pipeline.
- Branch protection: a GitHub/GitLab rule that a PR can't merge unless the pipeline is green โ this is how a CI gate is enforced.
- Runner / agent: the machine that executes the pipeline (GitHub-hosted, or your own "self-hosted" runner).
- Secrets: credentials (API keys, cloud logins) stored securely in the CI system, never in code.
- Matrix build: run the same job across combinations (e.g., Python 3.10/3.11/3.12, or Chrome/Firefox) in parallel.
Where QA fits in a pipeline¶
- Unit tests โ run on every push (fast, first gate).
- API/integration tests โ after the app is built/deployed to a test environment.
- Smoke E2E tests โ on every PR (a fast, critical-path subset).
- Full regression โ nightly or on release branches (slower, run on a schedule).
- Test report โ published as an artifact so failures are inspectable.
CI/CD Q&A¶
Q: Difference between Continuous Delivery and Continuous Deployment?
"Both automatically build, test, and prepare a release. Continuous Delivery stops at a manual approval before production โ a human clicks 'release.' Continuous Deployment removes that step, so every change that passes the pipeline ships straight to prod. Deployment needs very high test confidence, because there's no human gate."
Q: What's a quality gate, and how do you enforce it?
"A quality gate is a pass/fail check that blocks the pipeline if not met โ tests passing, coverage threshold, no critical vulnerabilities. I enforce it with branch protection: the PR can't merge unless the pipeline is green. In the pipeline itself, the test step exits non-zero on failure, which fails the job and blocks the next stage."
Q: How would you add your test suite to a CI pipeline?
"A job that checks out the code, sets up the runtime, installs dependencies, runs the tests producing a JUnit report, and uploads that report as an artifact (with
if: always()so I get it even on failure). I run fast unit/API tests on every PR as the blocking gate, and the full regression on a nightly schedule to keep PRs quick. If tests fail, the job exits non-zero and blocks the merge." (This is literally the lab'sci.yml.)
Q: How do you keep a pipeline fast?
"Cache dependencies, run independent jobs in parallel (lint alongside tests), use a matrix for cross-version/browser runs, split fast smoke tests (per-PR) from slow full regression (nightly), and only build/deploy if tests passed (
needs:)."
Q: How do you handle secrets in CI?
"Never in code or logs. Store them in the CI system's secrets store (GitHub Actions Secrets, Jenkins Credentials) and inject them as environment variables at runtime. For cloud, prefer short-lived credentials via OIDC/role assumption over long-lived keys."
PART 2 โ Docker & Containers¶
The concepts (plain words)¶
- Container: a lightweight package with the app plus its exact dependencies, so it runs the same everywhere โ your laptop, CI, cloud. Solves "works on my machine."
- Image: the blueprint; a container is a running instance of an image.
- Dockerfile: the recipe to build an image (base image โ copy code โ install deps โ command to run).
- Registry: where images are stored/shared โ Docker Hub, GitHub Container Registry (GHCR), AWS ECR, Azure ACR.
- docker-compose: run multiple containers together with one command (app + DB + Selenium Grid).
- Orchestration (Kubernetes/ECS): runs many containers across many machines at scale โ know the word; deep k8s isn't expected of QA.
Remember: image = recipe, container = the running dish, registry = the pantry you share it from.
Why testers care¶
- Spin up the exact app version + dependencies for reliable tests (no environment drift).
- Run Selenium Grid or browsers in containers via compose.
- The same image you tested is the one deployed โ what you tested is what ships.
Docker Q&A¶
Q: Image vs container?
"An image is the immutable blueprint built from a Dockerfile; a container is a running instance of that image. One image โ many containers."
Q: Why is Docker useful for testing?
"It kills environment drift โ the app and its dependencies are pinned in the image, so tests behave identically on my laptop, in CI, and in the cloud. It also lets me stand up dependencies (a DB, a Selenium Grid, a mock API) with
docker compose upfor reliable, isolated integration tests, and the image I tested is exactly what gets deployed."
Q: Walk me through a Dockerfile.
"Start from a base image (
python:3.12-slim), set a working dir, copyrequirements.txtand install deps first so that layer caches, copy the app code, expose the port, and set the run command โ in prod a real server like gunicorn, not the dev server." (That's the lab's Dockerfile.)
PART 3 โ Cloud fundamentals (AWS, with Azure/GCP equivalents)¶
You only need working knowledge + the vocabulary. Learn the core four categories:
| Category | AWS | Azure | GCP | What it's for |
|---|---|---|---|---|
| Compute | EC2 (VMs), Lambda (serverless), ECS/EKS (containers), Elastic Beanstalk / App Runner (managed) | Virtual Machines, Functions, App Service, AKS | Compute Engine, Cloud Functions, Cloud Run, GKE | Run your app |
| Storage | S3 (objects), EBS (disks), RDS (SQL DB) | Blob Storage, Managed Disks, Azure SQL | Cloud Storage, Persistent Disk, Cloud SQL | Store files/data |
| Identity/Access | IAM (users, roles, policies) | Entra ID / RBAC | IAM | Who can do what (least privilege) |
| Monitoring/Logs | CloudWatch (metrics, logs, alarms) | Azure Monitor / App Insights | Cloud Monitoring/Logging | See health, set alerts |
| Networking | VPC, Security Groups, ELB (load balancer) | VNet, NSG, Load Balancer | VPC, Cloud Load Balancing | Connectivity + traffic |
Deploy options, easiest โ most control¶
- Managed (start here): AWS Elastic Beanstalk / App Runner, Azure App Service, GCP Cloud Run โ give them your app/image, they handle servers, scaling, health checks.
- Containers: AWS ECS/Fargate (or EKS), Azure AKS, GCP GKE.
- Raw VM: AWS EC2 โ you manage the OS. Most control, most work.
- Serverless: AWS Lambda + API Gateway โ no servers, pay per request; great for small APIs.
Cloud Q&A¶
Q: What cloud services have you used, and for what?
"I've deployed a containerized app to AWS โ Elastic Beanstalk/App Runner for managed hosting โ stored artifacts and test data in S3, used IAM roles for least-privilege access from CI, and watched health via CloudWatch with an alarm on the health-check endpoint. The concepts map directly to Azure (App Service, Blob, Entra ID, App Insights) and GCP." (Adjust to what you actually did in the lab.)
Q: What is IAM / why least privilege?
"IAM controls who can do what in the cloud via users, roles, and policies. Least privilege means giving each identity the minimum permissions it needs โ so a leaked CI key can't delete your database. In pipelines I prefer a role the CI assumes short-term over long-lived access keys."
Q: EC2 vs Lambda vs a managed service โ when each?
"EC2 is a raw VM โ full control, most maintenance. Lambda is serverless โ no servers, pay per call, great for small/bursty APIs but with cold-start and time limits. A managed service (Beanstalk/App Service/Cloud Run) is the middle ground โ you hand over a container and it runs/scales it. For a small app I'd start managed or serverless, not EC2."
PART 4 โ Cloud application testing¶
Testing an app that lives in the cloud adds a few things beyond functional tests:
- Post-deploy smoke tests: after each deploy, hit the live URL's critical endpoints (health, one key flow) and fail the deploy if they break. (The lab's test_smoke_live.py.)
- Health checks: the /health endpoint the load balancer polls โ test it exists and reflects real readiness.
- Environment configuration: the same tests run against dev/staging/prod via a BASE_URL/env var โ never hard-code URLs or secrets.
- Cloud browser/device testing: run cross-browser/device suites on BrowserStack / Sauce Labs / AWS Device Farm instead of maintaining a local grid.
- Performance/load in the cloud: k6 / JMeter / Gatling against the deployed endpoint; watch server-side metrics (CPU, memory, DB) in CloudWatch at the same time.
- Monitoring & alerting: set an alarm (CloudWatch/App Insights) on error rate or a failing health check so prod issues page you, not your users.
- Resilience/chaos (advanced): kill an instance and confirm the load balancer/auto-scaler recovers.
Q: How do you test an application deployed in the cloud?
"Functional tests run against the deployed URL via an environment variable so the same suite covers dev/staging/prod. After every deploy I run smoke tests on the live critical endpoints and fail the release if they break. I add cloud browser testing (BrowserStack/Device Farm) for cross-platform coverage, load tests against the real endpoint while watching CloudWatch metrics, and monitoring alarms on health and error rate so regressions in prod alert us automatically."
PART 5 โ Tools compared (name them confidently)¶
| Tool | What it is | Note |
|---|---|---|
| GitHub Actions | CI/CD built into GitHub (YAML workflows) | Easiest to start; what the lab uses |
| Jenkins | Self-hosted CI server; pipelines in a Jenkinsfile (Groovy) |
Older, very common in enterprises โ worth running once |
| GitLab CI | CI/CD built into GitLab (.gitlab-ci.yml) |
Common where GitLab is the SCM |
| Azure DevOps Pipelines | Microsoft's CI/CD (YAML or classic) | Common in Azure/enterprise shops |
| AWS CodePipeline/CodeBuild | AWS-native CI/CD | Appears in AWS-heavy shops |
| Docker | Containerization | Universal |
| Kubernetes / ECS | Container orchestration at scale | Know the word; deep k8s optional for QA |
| Terraform | Infrastructure as Code (define cloud in files) | Bonus; strong signal if you know the concept |
Jenkins one-liner to know: a
Jenkinsfiledefinespipeline { stages { stage('Test'){ steps{ sh 'pytest' } } } }โ same idea as a GitHub Actions workflow, different syntax.
PART 6 โ Day-to-day commands (what each does & when you use it)¶
The commands a QA/SDET actually types in a normal day. You don't memorise all of these โ but in an interview you should be able to say what a command does and when you'd reach for it. Grouped by tool.
Git โ every single day (version control your tests)¶
| Command | What it does | When you use it |
|---|---|---|
git clone <url> |
Copy a repo to your machine | First time you pick up a project |
git checkout -b feature/login-tests |
Create + switch to a new branch | Starting new test work (never commit straight to main) |
git status / git diff |
Show changed/staged files / line changes | Before every commit, to see what you're about to save |
git add . / git commit -m "msg" |
Stage changes / save them with a message | After finishing a logical chunk of work |
git pull --rebase |
Get teammates' latest changes, replay yours on top | Start of day + before pushing, to avoid conflicts |
git push origin <branch> |
Upload your branch to the remote | When work is ready for a PR/review |
git merge / git rebase |
Combine branches | Integrating main into your branch (or vice-versa) |
git stash / git stash pop |
Shelve uncommitted work / bring it back | Need to switch branches urgently mid-change |
git log --oneline / git blame <file> |
History / who changed a line | Debugging "when did this test break and why?" |
Docker โ when containerizing the app/tests¶
| Command | What it does | When you use it |
|---|---|---|
docker build -t myapp:latest . |
Build an image from the Dockerfile | After changing app/Dockerfile; in CI to package |
docker run -p 5000:5000 myapp |
Start a container from an image, map a port | Run the app locally exactly as it runs in prod |
docker ps / docker ps -a |
List running / all containers | Check what's up; find a container's ID |
docker logs <container> |
Show a container's output | Debugging why a containerized app/test failed |
docker exec -it <container> bash |
Open a shell inside a running container | Poke around the container's filesystem/env |
docker stop/rm <container> / docker rmi <image> |
Stop/remove container / delete image | Cleanup after runs |
docker pull/push <registry>/<image> |
Download/upload an image to a registry | Pull a DB image; push your tested image from CI |
Docker Compose โ multi-container test environments¶
| Command | What it does | When you use it |
|---|---|---|
docker compose up -d |
Start all services (app + DB + grid) in background | Stand up a full test environment in one command |
docker compose down |
Stop and remove everything | Tear the environment down after tests |
docker compose logs -f <svc> |
Follow one service's logs live | Watch the app while your tests hit it |
Maven โ Java/Selenium/REST Assured projects¶
| Command | What it does | When you use it |
|---|---|---|
mvn clean |
Delete the target/ build output |
Start a clean build (avoid stale artifacts) |
mvn compile |
Compile source only | Quick check that code builds |
mvn test |
Compile + run the tests | Run your TestNG/JUnit suite locally & in CI |
mvn test -Dtest=LoginTest |
Run one test class/method | Debug a single failing test fast |
mvn test -DsuiteXmlFile=testng.xml |
Run a specific TestNG suite | Run a smoke vs regression suite |
mvn install -DskipTests |
Build + install to ~/.m2 without running tests |
Build an artifact when you don't need the test run |
mvn dependency:tree |
Show the full dependency graph | Diagnose version conflicts |
npm / Playwright โ TypeScript/JS UI projects¶
| Command | What it does | When you use it |
|---|---|---|
npm ci |
Clean, exact install from package-lock.json |
In CI (reproducible) and fresh clones |
npx playwright install |
Download the browser binaries | First setup / in CI before running UI tests |
npx playwright test |
Run the whole Playwright suite | Local run + CI gate |
npx playwright test --project=chromium -g "login" |
Run a subset (browser / title filter) | Debug a specific test or browser |
npx playwright test --headed --debug |
Run with a visible browser + inspector | Watch a flaky test to see what happens |
npx playwright show-report / show-trace |
Open the HTML report / Trace Viewer | Investigate a failure after the run |
npx playwright codegen <url> |
Record actions into generated code | Quickly scaffold locators for a new page |
pytest โ Python test/eval projects¶
| Command | What it does | When you use it |
|---|---|---|
pip install -r requirements.txt |
Install dependencies | Setup / in CI |
pytest / pytest -v |
Run all tests (verbose) | Local run + CI gate |
pytest path/test_file.py::test_name |
Run one file/test | Debug a single case |
pytest -k "login and not slow" |
Run tests matching an expression | Focus on a feature; skip slow ones |
pytest -m "not ui and not slow" |
Run by marker (fast subset) | The fast CI gate (exactly the LLM-eval CI) |
pytest -n auto (pytest-xdist) |
Run tests in parallel across cores | Speed up a big suite |
pytest --maxfail=1 -x |
Stop at first failure | Fast feedback while fixing |
GitHub CLI / Actions โ the pipeline¶
| Command | What it does | When you use it |
|---|---|---|
gh pr create / gh pr checks |
Open a PR / see its CI status | Submitting work; checking if the gate is green |
gh run list / gh run watch |
List/watch workflow runs | Monitor a pipeline you just triggered |
gh run view <id> --log-failed |
Show logs of failed steps | Debug why CI failed without leaving the terminal |
gh workflow run <file> |
Manually trigger a workflow (workflow_dispatch) |
Kick off a nightly/regression run on demand |
kubectl โ containers at scale (know the basics)¶
| Command | What it does | When you use it |
|---|---|---|
kubectl get pods |
List running pods | Check if the app is up in a k8s cluster |
kubectl logs <pod> |
Show a pod's logs | Debug the deployed app |
kubectl describe pod <pod> |
Detailed pod state/events | Diagnose crashloops / why a pod won't start |
kubectl port-forward <pod> 8080:80 |
Tunnel a cluster port to localhost | Hit an internal service from your test |
Cloud CLIs โ AWS / GCP (occasional, deploy & debug)¶
| Command | What it does | When you use it |
|---|---|---|
aws s3 cp <file> s3://bucket/ |
Upload/download to S3 | Publish test reports/artifacts to cloud storage |
aws logs tail <group> --follow |
Stream CloudWatch logs live | Watch the deployed app while smoke-testing |
aws ecr get-login-password \| docker login ... |
Authenticate Docker to AWS ECR | Push your image to AWS from CI |
gcloud run deploy <svc> --image <img> |
Deploy a container to Cloud Run | Managed deploy of the app under test |
Jenkins โ enterprise CI (know these exist)¶
| Command / concept | What it does | When you use it |
|---|---|---|
Jenkinsfile (pipeline { stages { ... } }) |
Defines the pipeline as code (Groovy) | The Jenkins equivalent of a GH Actions YAML |
sh 'mvn test' (a pipeline step) |
Run a shell command in a stage | Running your test suite inside a Jenkins stage |
| "Build Now" / webhook trigger | Start a job manually / on push | Trigger a build; auto-run on commits |
Interview tip: if asked "what commands do you use day-to-day?", don't list 50 โ say: "Mostly git for version control,
mvn test/npx playwright test/pytestto run suites locally and in CI,docker build/runto containerize, and I read pipeline results viagh runor the Actions UI. For cloud I've used the AWS CLI to push images and tail logs." That's honest, specific, and shows real day-to-day fluency.
PART 7 โ Your hands-on plan (4โ6 weeks, free tier)¶
- Week 1: Run the lab locally, push it to GitHub, watch the CI pipeline; break a test on purpose and see it block the merge.
- Week 2:
docker build/compose up; push the image to GHCR from CI. - Week 3: Make a free AWS account; deploy the container (Elastic Beanstalk/App Runner); open the live URL.
- Week 4: Add the smoke-test-after-deploy step (CD); add a CloudWatch alarm; try a BrowserStack run.
- Weeks 5โ6: Study for and take AWS Cloud Practitioner or AZ-900; run one Jenkins pipeline locally (via Docker).
PART 8 โ Certifications (good ROI for QA)¶
- Foundational (do one): AWS Certified Cloud Practitioner (CLF-C02) or Azure Fundamentals (AZ-900) โ ~2โ3 weeks casual study, cheap, a clear rรฉsumรฉ signal that you know cloud basics.
- Next (optional): AWS Developer/SysOps Associate, or Azure DevOps (AZ-400). ISTQB if you want a testing cert.
The one-paragraph answer for "what's your CI/CD & cloud experience?"¶
"I containerize apps with Docker and run tests in CI โ a GitHub Actions pipeline that installs, tests, builds the image, and blocks the merge on failures, with the test report saved as an artifact. On the CD side I deploy the container to AWS and run a smoke test against the live URL so a bad deploy is caught automatically. I understand pipeline stages, quality gates, artifacts, secrets, containers, health checks, IAM least-privilege, and cloud monitoring โ and I've done it hands-on, not just read about it."