SQA Sprint
0 / 32
SQA → Job → Django · Bangladesh QA Market · 200-Hour Edition

SQA Sprint

A trimmed, BD-market-focused manual + API QA curriculum, expanded to 200 hours with real hands-on Playwright automation, OS/networking fundamentals, and a scratch-to-advanced SQL track built for both QA data validation and RCM data-analyst roles (e.g. Commure/Augmedix Dhaka) — built to get you hired quickly, with self-check drills so you walk into the exam room unstoppable.

200
total hours
31
modules
160+
interview questions
55
drill flashcards

How this is organized

Use the tabs at the top to move between stages, and the round chips below them to jump between modules inside a stage. Every module keeps its original priority badge — Must Master Must Know Should Know Awareness — so you always know where to spend your limited hours. The Drill tab is a standalone self-check flashcard deck pulling every "memorize cold" fact from across the guide.

What changed from the 120-130 hour version

The original trimmed guide deliberately cut hands-on automation to stay inside ~125 hours. With 200 hours available, that trade-off no longer applies — this edition adds a full Automation module (Page Object Model, a CI pipeline) and a CS Fundamentals module (OS + networking, the layer just below what Part 2 already teaches) on top of the complete original curriculum. Nothing from the original was removed.

What changed in this revision

Three targeted updates: (1) SQL (Part 12) was rewritten start-to-finish — it now ramps from absolute scratch through window functions, CTEs, recursive CTEs, correlated subqueries, reconciliation/anomaly queries, and indexes/EXPLAIN, using a healthcare RCM (claims/payments/denials) schema, specifically to also prepare you for RCM Data Analyst roles like Commure/Augmedix Dhaka — not just SQA roles. (2) The Automation module is now Playwright-only instead of Selenium + Playwright, since splitting hands-on time across two tools was producing shallow knowledge of both; a short awareness-level Selenium vocabulary mapping was kept so you're not blindsided if a specific job asks for it. (3) The Roadmap's hour totals and schedule (1.1/1.2) were corrected — they were still showing stale pre-expansion numbers — and the tab/chip highlight colors were simplified to a plain white background with black text.

Read This First — Strategy, Scope, and Honesty About What Was Cut

0.1 Your actual goal (stated plainly, so we don't drift)

You are not trying to become a career QA engineer. You are trying to:

  1. Get hired as a Manual/API QA Engineer at a Bangladeshi software company, as fast as reasonably possible, to establish income and stability.
  2. Use that job as a runway — you'll keep working while learning Django backend development in the evenings/weekends.
  3. Transition into a Backend Developer (Django) role in roughly 4–5 months after starting the QA job.

Every decision in this guide — what's included, what's cut, how deep each topic goes — was made against that goal. This is not the same guide I'd write for someone who wants to become a Senior SQA Automation Engineer or SDET for the next ten years. If that ever becomes your actual goal, this guide should be treated as a foundation, not the ceiling.

0.2 What was deliberately cut or trimmed, and why

The original ask (see your own notes, if you kept them) covered a much larger 250–350 hour curriculum including deep Selenium framework architecture, JMeter performance engineering, a Therap-specific mock exam, a 60–80 problem LeetCode grind, and an exhaustive 30-object test-case scenario library. Here's what changed and why:

Cut/trimmed Why
Selenium framework building (POM, pytest architecture, CI integration) You confirmed most broad BD QA roles — and Therap specifically — don't require it at entry level. Hands-on Selenium takes 40–60 hours to do properly. That's the single biggest time cost removed. You'll still get a conceptual chapter so you're never blindsided if it comes up.
JMeter hands-on performance engineering Same logic — kept as a short conceptual chapter, not a hands-on module.
Deep security/pentesting depth Kept as awareness-level only (what a junior QA is expected to recognize, not exploit).
60–80 problem LeetCode grind Trimmed to 15–20 carefully chosen problems — enough to survive a basic screening round. Real DSA depth is deferred to your backend-dev interview prep later, where it actually matters more.
Therap-specific mock exam You're targeting BD broadly, not just Therap. You still get a general BD-style written mock exam (many BD companies use a similar shape: SQL + scenario writing + a bit of logic/coding), just not framed as a leaked/specific Therap simulation.
30-object test case scenario library Trimmed to ~14 well-chosen, genuinely diverse objects. The thinking framework is what matters — once you have it, you can apply it to any 31st object an interviewer throws at you.
3rd portfolio project (Selenium) Dropped. You get 2 strong, complete portfolio projects (Manual QA + API Testing) instead of 3 mediocre ones.

What was NOT cut, and was actually deepened relative to a "pure QA" guide:

  • Python — taught with half an eye on the fact that you'll be writing Django code in 4–5 months. Where a pure-QA course would stop at "enough to script a test," this one goes a bit further into functions, OOP, and file/JSON handling, because that's the same foundation Django needs.
  • SQL — kept fully deep. SQL is used identically in QA (data validation) and backend dev (ORM/queries), so this is 100% dual-purpose time.
  • Git — kept solid. Every dev job needs it.
  • API/HTTP concepts — kept deep. Understanding REST, status codes, and request/response cycles is directly transferable to building APIs later, not just testing them.
  • Linux basics — kept practical. Useful in both worlds.

0.3 Priority classification used throughout this guide

Every topic is tagged with one of these. Spend your limited hours accordingly.

Tag Meaning Time strategy
🔴 MUST MASTER You will be tested on this in nearly every BD QA interview or written test. Weakness here disqualifies you. Practice until automatic. Don't just read — do the exercises.
🟠 MUST KNOW Commonly asked; expected working knowledge. Understand deeply, practice a moderate amount.
🟡 SHOULD KNOW Comes up often enough to matter; differentiates you from weaker candidates. Understand the concept and one worked example. Don't over-invest.
⚪ NICE TO HAVE / AWARENESS ONLY Rarely required at entry level for the roles you're targeting; included so you're never caught flat-footed. Read once. Don't practice extensively — this is explicitly what we trimmed.

0.4 A note on sourcing honesty

Where this guide states something is "commonly expected in BD QA hiring," that reflects a synthesis of widely-reported patterns across junior QA job postings and public interview-experience discussions (BDJobs, LinkedIn, Glassdoor-style writeups, QA community forums) — not a single verified source per claim, and not insider/leaked material from any specific company including Therap. Where something is industry-standard testing theory (ISTQB-adjacent concepts like BVA, EP, severity/priority), that's standard and stable regardless of geography. The guide flags the difference inline where it matters (e.g., "this exact wording is industry-standard; the emphasis on it in interviews is a BD-market pattern").


The Roadmap

1.1 Total time budget

Total: ~203 hours (the "200-Hour Edition"), organized into 6 levels that match the tabs at the top of this page. This table replaces an earlier draft that still showed the pre-expansion ~120-130 hour numbers — those were stale; this is the real total across every module currently in the guide, including Playwright automation and CS Fundamentals.

Level Tabs covered Focus Hours Cumulative
Level 1 Foundations, Concepts Software fundamentals, SDLC/STLC, testing fundamentals & types 24h 24h
Level 2 Test Design Test design techniques, test case design, scenario testing, bug reporting 24h 48h
Level 3 Tools, SQL Jira, Linux, Git, and the full scratch-to-advanced SQL track (12.1-12.33) 45h 93h
Level 4 API & Python, Automation API testing, Postman, Python for QA, Playwright automation 48h 141h
Level 5 CS Fundamentals, Pro Skills OS & networking, awareness chapter, light DSA, Agile/communication, QA metrics 35h 176h
Level 6 Interview Prep, Portfolio Interview bank, mock exams, both portfolio projects 27h 203h

1.2 Your schedule: 2 hours/day, starting Friday, September 25, 2026

At 2 hrs/day, 6 days/week (assume 1 rest day — burnout kills consistency more than pace does), that's ~12 hours/week. 203 hours ÷ 12 ≈ 17 weeks. This is longer than the guide's earlier 10-week estimate — that estimate was written before the Playwright, CS Fundamentals, and expanded SQL modules existed. 17 weeks is the honest number for everything currently in this guide, top to bottom.

Week Dates (approx.) Focus Hours
1Sept 25 – Oct 1Software fundamentals, SDLC, start STLC12h
2Oct 2 – Oct 8Finish STLC, Testing Fundamentals, Types of Testing12h
3Oct 9 – Oct 15Test Design Techniques, start Test Case Design12h
4Oct 16 – Oct 22Finish Test Case Design, Scenario Testing, Bug Reporting12h
5Oct 23 – Oct 29Jira, Linux, Git, begin SQL (12.2-12.9: basics through conditional aggregation)12h
6Oct 30 – Nov 5SQL — joins, self joins, subqueries, correlated subqueries, EXISTS (12.10-12.14)12h
7Nov 6 – Nov 12SQL — CTEs, recursive CTEs, window functions intro, ROW_NUMBER/RANK (12.15-12.19)12h
8Nov 13 – Nov 19SQL — LAG/LEAD, dates, strings, NULLs, reconciliation & anomalies, indexes/EXPLAIN, then start API Testing (12.20-12.33)12h
9Nov 20 – Nov 26API Testing, Postman project, begin Python12h
10Nov 27 – Dec 3Python for QA (core)12h
11Dec 4 – Dec 10Finish Python, begin Playwright automation12h
12Dec 11 – Dec 17Playwright — locators, auto-waiting, POM, CI pipeline12h
13Dec 18 – Dec 24OS & Networking fundamentals12h
14Dec 25 – Dec 31Finish OS/Networking, Awareness chapter, begin Light DSA12h
15Jan 1 – Jan 7Finish DSA, Agile/Communication, QA Metrics, begin Interview Prep12h
16Jan 8 – Jan 14Interview Prep & Mock Exams, begin Portfolio Projects12h
17Jan 15 – Jan 21Finish Portfolio Projects, apply for jobs11h

Target: applying to jobs in earnest around January 18-22, 2027, roughly 17 weeks after you start. Interview cycles in BD can add another 2–6 weeks on top of that before an offer, so a realistic "employed" target is February–April 2027. That then starts your 4–5 month Django clock, landing a backend transition target around June–September 2027.

If you can occasionally do 3 hrs instead of 2 on weekends, you can compress this by 2-3 weeks. Don't force it on weekdays — 2 focused hours beats 1 exhausted hour plus 1 distracted hour. If you're specifically targeting the Commure/Augmedix RCM Data Analyst role, it's reasonable to prioritize finishing SQL (Level 3) ahead of schedule even if that means moving faster through lower-priority Awareness-tagged content later — see 0.3's priority tags.

1.3 What to practice vs. what to memorize

Practice (do it repeatedly, build muscle memory) Memorize (know cold, recall instantly)
Writing test cases from a spec Severity vs. Priority definitions
Writing SQL queries from scratch — especially joins, CTEs, and window functions Defect lifecycle states and order
Applying BVA/EP to a new input field HTTP status code meanings (200s/300s/400s/500s)
"How would you test X" on objects you've never seen SDLC/STLC phase names and order
Writing bug reports from a bug description Core testing terminology (verification vs validation, etc.)
Reading and debugging someone else's SQL/Python ROW_NUMBER vs RANK vs DENSE_RANK behavior on ties

Rule of thumb: anything that requires judgment or construction, you practice. Anything that's a fixed definition or fact, you memorize with flashcards/repetition and move on — don't over-study static facts.

1.4 Milestones

Level Milestone What "done" looks like
Level 1 Basic QA understanding You can explain SDLC, STLC, and 15+ core QA terms correctly without notes.
Level 2 Junior manual QA readiness You can write a 10-step professional test case and a professional bug report from a vague description, unaided.
Level 3 Strong SQA + RCM analyst candidate You can write joins, CTEs, and window functions from scratch, build an aging/reconciliation report unaided, and navigate Linux/Git comfortably.
Level 4 QA + API + automation candidate You can design and execute a full Postman test collection including negative/boundary cases, read/write basic Python, and have a working Playwright suite with CI.
Level 5 Well-rounded technical candidate You can explain OS/networking fundamentals cleanly and hold your own in an Agile/Scrum conversation.
Level 6 Interview-ready You've completed the mock written exam under time pressure, done both mock interviews, and have 2 portfolio projects on GitHub.

1.5 Dependency map

flowchart TD
    A[Software Fundamentals] --> B[SDLC / STLC]
    B --> C[Testing Fundamentals & Types]
    C --> D[Test Design Techniques]
    D --> E[Test Case Writing]
    E --> F[Bug Reporting + Jira]
    C --> G[SQL: Scratch to Advanced]
    A --> H[API Testing Concepts]
    H --> I[Postman Project]
    G --> J[Linux + Git]
    F --> J
    I --> K[Python for QA]
    J --> K
    K --> L[Playwright Automation]
    K --> M2[Light DSA]
    L --> T[CS Fundamentals: OS & Networking]
    E --> M[Scenario Practice / How-would-you-test-X]
    F --> M
    T --> N[Interview Prep + Mock Exam]
    M2 --> N
    M --> N
    I --> N
    N --> O[Portfolio Projects]
    O --> P[Apply for Jobs]
    P --> Q[QA or RCM Analyst Job Secured]
    Q --> R[Django Learning Track — 4-5 months]
    R --> S[Backend Developer Transition]

Software Fundamentals for QA

Must Master
Estimated time: 6 hours

Dual-purpose: this is also backend-dev groundwork.

2.1 What software actually is, and how it's built

Software is instructions running on hardware to produce useful behavior. As a QA engineer you almost never test "software" in the abstract — you test applications: web apps, mobile apps, or APIs, each with predictable moving parts. Understanding those parts is what turns you from someone who can click around and notice things look wrong into someone who can reason about where a bug is likely to live.

2.2 Client-server architecture

sequenceDiagram
    participant U as User (Browser/App)
    participant C as Client (Frontend)
    participant S as Server (Backend)
    participant D as Database

    U->>C: Clicks "Login"
    C->>S: HTTP POST /api/login {email, password}
    S->>D: SELECT * FROM users WHERE email = ?
    D-->>S: User row (hashed password)
    S->>S: Compare password hash
    S-->>C: 200 OK + auth token
    C-->>U: Redirect to dashboard
  • Client: what the user directly interacts with — a browser rendering HTML/CSS/JS, or a mobile app.
  • Server (backend): receives requests, applies business logic, talks to the database, returns a response.
  • Why QA needs this: almost every bug you'll triage is really the question "is this a frontend bug (wrong thing displayed/sent) or a backend bug (wrong thing computed/stored)?" You can't write an accurate bug report without being able to at least guess the answer, and you certainly can't do API testing without understanding that the API is the server side, tested directly, bypassing the client.

2.3 Frontend vs. backend, web vs. mobile

Frontend Backend
Runs where User's browser/device Server
Typical tech HTML, CSS, JavaScript, React/Vue Python/Django, Node, Java, databases
What QA tests Layout, interactions, validation messages, responsiveness Business logic, data correctness, APIs, performance

Web apps run in a browser (no install). Mobile apps are installed (native — Swift/Kotlin, or cross-platform — React Native/Flutter). As QA you'll mostly test web apps and their APIs at entry level in BD; mobile testing (if it comes up) adds device/OS fragmentation as a new axis of testing (see Part 6, compatibility testing).

2.4 APIs — the concept, before the testing

An API (Application Programming Interface) is a defined contract that lets one piece of software ask another for data or action, without needing to know how the other one works internally. A REST API is the dominant style: it uses HTTP, treats things as "resources" (e.g., /users, /orders/42), and uses HTTP methods to say what you want to do to that resource. You'll go deep on this in Part 15 — for now, just internalize: the API is the backend's front door, and testing it directly (skipping the UI) is often faster and more precise than clicking through screens.

2.5 HTTP / HTTPS and the request-response cycle

HTTP (HyperText Transfer Protocol) is the language browsers and servers speak to each other. HTTPS is the same thing, encrypted (via TLS/SSL) — this matters for security testing (Part 19) because unencrypted HTTP means anyone on the network can read the traffic, including passwords.

Every interaction is a request (from client) and a response (from server):

Request:
  GET /api/products/17 HTTP/1.1
  Host: shop.example.com
  Authorization: Bearer eyJhbGciOi...

Response:
  HTTP/1.1 200 OK
  Content-Type: application/json

  {"id": 17, "name": "Wireless Mouse", "price": 850, "in_stock": true}

2.6 Common HTTP status codes Must Master

Range Meaning Examples you must know
2xx Success 200 OK, 201 Created, 204 No Content
3xx Redirection 301 Moved Permanently, 304 Not Modified
4xx Client error (you did something wrong) 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity
5xx Server error (the backend broke) 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable
Interview trap

401 (Unauthorized) actually means "not authenticated" — you don't know who this is. 403 (Forbidden) means "I know who you are, and you're not allowed." Mixing these up is a very common junior mistake and interviewers know to probe it.

2.7 JSON

The standard data format for APIs. Key-value pairs, nested objects, arrays:

{
  "user": {
    "id": 5,
    "name": "Shahed",
    "roles": ["tester", "admin"],
    "active": true,
    "last_login": null
  }
}

You need to read this fluently — API testing is 80% "does the JSON response match what it should."

2.8 Cookies, sessions, authentication, authorization

  • Cookie: small piece of data the server asks the browser to store and send back on every request (e.g., a session ID).
  • Session: server-side record of "this user is logged in," usually tied to a cookie or token.
  • Authentication: proving who you are (login).
  • Authorization: what you're allowed to do once you're known (roles/permissions).
  • Why QA cares: a huge share of real-world bugs are auth bugs — a regular user seeing admin data, a logged-out user accessing a page they shouldn't, a session that doesn't expire. "Try accessing X without logging in" and "try accessing another user's data by changing the ID in the URL" are two of the most common exploratory testing moves you'll ever make.

2.9 Basic networking & browser basics

You don't need deep networking, but know: DNS resolves a domain name to an IP address; a port identifies a specific service on a server (80 = HTTP, 443 = HTTPS); localhost means your own machine. In the browser, know how to open DevTools (F12) — the Network tab (see actual requests/responses/status codes — this is your best friend for both manual and API-adjacent testing) and the Console tab (see JS errors).

Interview questions — Part 2

  1. What's the difference between authentication and authorization?
  2. What does a 404 vs a 500 status code tell you about where the problem might be?
  3. Explain client-server architecture to a non-technical person in two sentences.
  4. Why might a QA engineer use browser DevTools even for "manual" testing?

Practice

  • Open any website, press F12, go to Network tab, reload the page. Find one request, note its status code and one response header.
  • Pick a public JSON (e.g., from https://jsonplaceholder.typicode.com/users/1) and write down what each field means and what data type it is.

SDLC (Software Development Life Cycle)

Must Master
Estimated time: 3 hours

3.1 The models

Model Shape QA's role
Waterfall Sequential: Requirements → Design → Development → Testing → Deployment → Maintenance. Each phase finishes before the next starts. Testing happens only after development is "done" — late, risky, expensive to fix bugs.
V-Model Waterfall's twin, but each dev phase pairs with a matching test phase planned in parallel (e.g., requirements ↔ acceptance testing, design ↔ system testing). Testing is planned early even if executed late.
Iterative Build in repeated cycles, each producing a working (if incomplete) version. Testing happens each cycle, catching issues earlier than Waterfall.
Agile/Scrum Short, fixed-length iterations ("sprints," usually 1-2 weeks) delivering working increments continuously. Testing is continuous, embedded in every sprint. This is what you'll encounter at almost every BD software company.
flowchart LR
    subgraph Waterfall
    A1[Requirements] --> A2[Design] --> A3[Development] --> A4[Testing] --> A5[Deployment] --> A6[Maintenance]
    end
flowchart TD
    subgraph Scrum Sprint Cycle
    B1[Sprint Planning] --> B2[Daily Standups + Development + Testing]
    B2 --> B3[Sprint Review]
    B3 --> B4[Sprint Retrospective]
    B4 --> B1
    end

3.2 Agile/Scrum vocabulary you must know cold Must Master

Term Meaning
User story A feature described from the user's perspective: "As a [user], I want [goal], so that [reason]."
Acceptance criteria Specific, testable conditions a story must meet to be considered done. This is literally the seed of your test cases.
Backlog The full list of stories/tasks not yet completed, prioritized.
Sprint A fixed time-box (commonly 1-2 weeks) in which a set of backlog items are built and tested.
Sprint planning Meeting at sprint start: what will we build this sprint?
Daily standup Short daily sync: what I did, what I'll do, blockers.
Sprint review End-of-sprint demo of what was built.
Retrospective End-of-sprint meeting: what went well, what didn't, what to improve.
Definition of Ready (DoR) Criteria a story must meet before work starts (e.g., acceptance criteria written, designs attached).
Definition of Done (DoD) Criteria before a story is considered complete (e.g., code reviewed, tests passed, no critical bugs open).

3.3 Shift-left testing Must Know

The principle of moving testing activities as early as possible in the SDLC — reviewing requirements for testability, writing test cases before/during development instead of after, testing each piece as it's built rather than waiting for a "testing phase." This is the dominant modern industry philosophy and interviewers like to hear you understand why: bugs found in requirements cost far less to fix than bugs found in production (commonly cited rule of thumb: cost roughly multiplies at each later stage).

Example: acceptance criteria → test cases

User story

"As a registered user, I want to reset my password via email, so that I can regain access if I forget it."

Acceptance criteria

  • User can request a reset link by entering their registered email.
  • Reset link expires after 30 minutes.
  • Reset link can only be used once.
  • New password must meet the site's password policy.

Notice each bullet is already almost a test case title. This is exactly how professional QAs work — acceptance criteria are the primary input to test design, not an afterthought.

Interview questions — Part 3

  1. Why is Agile/Scrum more common than Waterfall in modern BD software companies?
  2. What's the difference between Definition of Ready and Definition of Done?
  3. Explain "shift-left testing" and why it saves money.
  4. Given a user story, how would you derive test cases from its acceptance criteria?

STLC (Software Testing Life Cycle)

Must Master
Estimated time: 5 hours

4.1 The phases

flowchart LR
    R[Requirement Analysis] --> P[Test Planning]
    P --> D[Test Case Development]
    D --> E[Test Environment Setup]
    E --> X[Test Execution]
    X --> C[Test Closure]
Phase What happens Key deliverable
Requirement Analysis Understand what's being built; identify testable vs. non-testable requirements; ask clarifying questions. List of queries/clarifications; testability assessment
Test Planning Decide scope, approach, resources, schedule, entry/exit criteria. Test Plan document
Test Case Development Write test cases/scenarios, prepare test data. Test cases, test data
Test Environment Setup Prepare the system under test (staging server, test DB, test accounts). Confirmed working environment
Test Execution Run the test cases, log actual results, raise bugs for failures. Execution results, defect reports
Test Closure Summarize results, evaluate exit criteria, document lessons learned. Test summary/closure report

4.2 Entry and exit criteria Must Know

  • Entry criteria for test execution: e.g., "build deployed to test environment," "smoke test passed," "test cases reviewed."
  • Exit criteria: e.g., "95% of planned test cases executed," "no open Critical/High severity bugs," "test coverage target met."

Interviewers sometimes ask "when do you stop testing?" — the honest professional answer is never purely by feeling; you define exit criteria up front and check against them, while acknowledging in practice teams also weigh time/budget/risk.

4.3 Worked example: STLC on a real small feature

Feature

"Users can filter a product list by price range on an e-commerce site."

  1. Requirement Analysis: Is "price range" a slider or two input boxes? What happens if min > max? Is there a currency consideration? (You'd raise these as clarifying questions before writing test cases — a hallmark of a good QA engineer is asking sharp clarifying questions, not guessing.)
  2. Test Planning: In scope — filter UI, filter logic, combining filter with other filters (category + price). Out of scope (for this cycle) — performance under 10,000 products.
  3. Test Case Development: e.g., "Verify filtering with min=100, max=500 returns only products in that range (inclusive)"; "Verify min > max shows validation error"; "Verify filter persists after pagination."
  4. Test Environment Setup: Staging site with seeded product data covering edge prices (e.g., a product at exactly 100, one at exactly 500, one at 0, one with no price).
  5. Test Execution: Run cases, log pass/fail, file bugs (e.g., "product priced exactly at max boundary is excluded — off-by-one bug").
  6. Test Closure: 40/42 cases passed, 2 bugs filed (1 High, 1 Low), decision: release with Low bug tracked for next sprint, High bug must be fixed first.

Interview questions — Part 4

  1. Walk me through STLC for a login feature.
  2. What's the difference between a Test Plan and a Test Case?
  3. What are exit criteria, and why do teams define them in advance instead of deciding "when it feels done"?
  4. Give an example of a good clarifying question you'd ask before writing test cases for an ambiguous requirement.

Exercise (do this — don't skip)

Take this vague requirement: "Add a 'Remember Me' checkbox to the login page." Write down 5 clarifying questions you'd ask before test design, and then draft 3 test case titles assuming reasonable answers to your own questions.

Testing Fundamentals & Core Terminology

Must Master
Estimated time: 4 hours

5.1 QA vs. QC vs. Testing

Term Scope Focus
Quality Assurance (QA) Process-oriented, whole project Preventing defects by improving the process itself
Quality Control (QC) Product-oriented Identifying defects in the actual product
Testing A subset of QC The specific activity of executing software to find defects

In real BD job postings, "SQA Engineer" almost always means what is technically QC + Testing work day-to-day, despite the title. Don't get hung up on the terminology mismatch in job titles — but do know the correct definitions cold, because interviewers ask this specific question extremely often as a warm-up.

5.2 Verification vs. Validation Must Master

  • Verification: "Are we building the product right?" — checking against specifications/documents, without executing code (reviews, walkthroughs, inspections).
  • Validation: "Are we building the right product?" — actually executing the software to confirm it meets user needs.

Classic interview one-liner: verification is static, validation is dynamic.

5.3 Error, Defect, Bug, Failure — the causal chain Must Master

flowchart LR
    E[Human Error
mistake by developer/analyst] --> D[Defect / Fault
flaw in the code] D --> F[Failure
observed wrong behavior when executed]
  • Error: a human mistake (developer misunderstands a requirement).
  • Defect/Fault/Bug: the flaw that results in the code (these three terms are used near-interchangeably in industry; "bug" is the casual term, "defect" is the formal/Jira term).
  • Failure: the observable incorrect behavior when the defective code actually runs.

A defect can exist without a failure (dead code path never executed). Know this distinction — it's a favorite trick question.

5.4 Test artifacts vocabulary Must Master

Term Definition
Test condition An item or event that could be verified (e.g., "login with valid credentials")
Test scenario A high-level "what to test" — one line, no steps (e.g., "Verify user can log in successfully")
Test case Detailed steps, data, and expected results for a specific scenario
Test suite A collection of related test cases
Test plan The document describing scope, approach, resources, schedule for testing
Test script Step-by-step instructions (manual) or automated code implementing a test case
Test data The specific input values used during execution
Test environment The hardware/software setup where tests run (staging server, test DB, browsers, devices)

Scenario vs. Test Case — the #1 confused pair. A scenario is what. A test case is how (detailed steps + expected result). One scenario often expands into multiple test cases (positive, negative, boundary variants).

5.5 Manual vs. Automation testing

Manual Automation
Who/what executes A human A script/tool
Best for Exploratory testing, usability, one-off/changing features, early-stage features Repetitive regression, stable features, high-volume data checks
BD entry-level reality This is what you'll do 80-90% of the time in your first QA job Nice to have, rarely the sole job of a true junior/fresher role

5.6 Functional vs. Non-functional

  • Functional: does the feature do what it's supposed to do? (login works, calculation is correct)
  • Non-functional: how well does it do it? (performance, security, usability, reliability)

5.7 Black-box, White-box, Grey-box

Type Tester knows internal code? Typical tester
Black-box No — tests based on inputs/outputs only Manual/functional QA (you, day-to-day)
White-box Yes — tests internal logic/code paths Developers, unit testers
Grey-box Partial knowledge QA who also reads some code/DB schema (common for API/DB testing)

5.8 Positive vs. Negative testing Must Master

  • Positive: valid input, expected to succeed. "Enter a valid email and password → login succeeds."
  • Negative: invalid input, expected to fail gracefully. "Enter no password → see 'password required' error, not a crash."

A shockingly large share of real bugs live in negative testing — junior candidates who only think positive are immediately identifiable as weak.

5.9 Static vs. Dynamic testing

  • Static: examining artifacts without executing code — requirement reviews, code reviews, walkthroughs.
  • Dynamic: actually running the software.

Interview questions — Part 5

  1. Explain verification vs validation with a real example.
  2. What's the difference between error, defect, and failure?
  3. What's the difference between a test scenario and a test case? Give an example of one scenario expanding into 3 test cases.
  4. Why is negative testing often more valuable for finding real bugs than positive testing?

Types of Testing

Must Master
Estimated time: 6 hours

For each: definition → purpose → example → common confusion.

6.1 The testing pyramid (context)

flowchart TD
    U["UI / E2E Tests
(few, slow, expensive)"] I["Integration Tests
(some, medium speed)"] Un["Unit Tests
(many, fast, cheap)"] U --- I --- Un

As a manual/API QA, you'll live mostly at the top two layers. Developers own the unit layer. Knowing this pyramid exists — and that it's a best-practice ideal often not fully followed in real BD companies — is enough at entry level.

6.2 By development level Must Master

Type Tests what Who usually does it Example
Unit testing Smallest piece of code (a function) in isolation Developers Testing a calculate_discount() function
Integration testing Interaction between two or more modules/components Devs + QA Testing that the payment module correctly talks to the inventory module
System testing The whole integrated system, end to end QA Full checkout flow: browse → cart → pay → order confirmation
Acceptance testing (UAT) Whether the system meets business/user needs, often done by the client/business Client/business users, sometimes QA-facilitated Client verifies the new invoicing feature matches their actual workflow

6.3 By purpose — regression family Must Master

Type Definition When used
Smoke testing Quick, shallow check that the build is stable enough to test further ("is it even worth testing today?") Immediately after a new build/deployment
Sanity testing Narrow, focused check that a specific fix/feature works, without full regression After a small bug fix, before deeper testing
Regression testing Re-running existing tests to confirm previously-working functionality still works after a change After any code change, especially before release
Retesting Specifically re-testing a previously failed test case after the fix, to confirm that exact bug is resolved After a bug is marked "Fixed"
The classic confusion (guaranteed interview question)

Smoke = broad but shallow, done first, on a new build. Sanity = narrow but deeper, done after a targeted fix. Regression = broad, done to catch side effects. Retest = specifically re-checking the exact bug that was reported.

6.4 By approach

Type Definition
Exploratory testing Simultaneous learning, test design, and execution — unscripted but disciplined and purposeful, guided by a tester's experience
Ad-hoc testing Informal, unstructured testing without any plan or documentation — closer to "random poking" than exploratory testing's disciplined approach
End-to-end testing Testing a complete real-world user workflow from start to finish across all integrated systems

6.5 Compatibility & related Should Know

Type Definition
Cross-browser testing Does it work correctly on Chrome, Firefox, Safari, Edge?
Cross-platform testing Does it work across OSes/devices (Windows/Mac/Linux, iOS/Android)?
Compatibility testing Umbrella term covering both, plus different versions/screen sizes/resolutions
Usability testing Is it intuitive and pleasant to use?
Accessibility testing Can users with disabilities use it (screen readers, keyboard navigation, color contrast)?
Localization testing (L10n) Does it work correctly for a specific locale (translated text, date/currency formats)?
Internationalization testing (I18n) Is the underlying app architecturally capable of supporting multiple locales (before actual translation)?

6.6 Reliability & operations Should Know

Type Definition
Installation testing Does the software install/uninstall/upgrade correctly?
Recovery testing Does the system recover gracefully after a crash/power failure?
Reliability testing Does the system perform consistently over an extended period without failure?

6.7 Non-functional performance family Awareness

Type Definition
Performance testing Umbrella term — how the system behaves under a workload (speed, stability, scalability)
Load testing Behavior under expected/normal user load
Stress testing Behavior under load beyond normal capacity, to find the breaking point
Volume testing Behavior with a large amount of data (not necessarily many users)
Security testing Umbrella term — see Part 19

Common mistakes across this whole section

  • Calling every retest a "regression test" (they're related but distinct).
  • Confusing localization (translated content) with internationalization (architectural readiness).
  • Treating "exploratory" and "ad-hoc" as synonyms — exploratory is a skilled, disciplined technique; ad-hoc is genuinely unstructured.

Interview questions — Part 6

  1. Differentiate smoke, sanity, regression, and retesting with a single shared example (e.g., a bug fix to the checkout page).
  2. What's the difference between load testing and stress testing?
  3. What's the difference between localization and internationalization?
  4. Give an example of exploratory testing that a scripted test case would likely miss.

Test Design Techniques

Must Master
Estimated time: 7 hours

This is the single highest-leverage section for both written tests and interviews — nearly every BD QA written test includes an EP/BVA question.

7.1 Equivalence Partitioning (EP) Must Master

Concept

Divide input data into partitions (groups) where all values in a partition should behave the same way. Instead of testing every possible input, test one representative value per partition — this is the core efficiency argument for EP.

Simple example

A field accepts age 18–60.

  • Partition 1 (invalid): < 18
  • Partition 2 (valid): 18–60
  • Partition 3 (invalid): > 60

Test one value from each: e.g., 10 (invalid), 35 (valid), 75 (invalid) — 3 tests instead of exhaustively testing every age.

Realistic software example

A discount code field that requires alphanumeric, 6-8 characters.

  • Valid partition: alphanumeric, 6-8 chars
  • Invalid: too short (< 6), too long (> 8), contains special characters, empty
Worked example

An e-commerce quantity selector accepts 1–10 items per order. | Partition | Representative value | Expected | |---|---|---| | Invalid (below) | 0 | Rejected | | Valid | 5 | Accepted | | Invalid (above) | 15 | Rejected | | Invalid (type) | "abc" | Rejected |

Exercise

A password field requires 8-20 characters. Identify the partitions and one representative test value for each. (Answer at the end of this section.)

7.2 Boundary Value Analysis (BVA) Must Master

Concept

Bugs cluster at the edges of partitions, not in the middle — off-by-one errors are the most common defect type in real software. BVA tests the boundary values directly: the minimum, just below minimum, just above minimum, the maximum, just below maximum, just above maximum.

Simple example

Same age field, 18–60. | Test value | Boundary | Expected | |---|---|---| | 17 | just below min | Rejected | | 18 | min | Accepted | | 19 | just above min | Accepted | | 59 | just below max | Accepted | | 60 | max | Accepted | | 61 | just above max | Rejected |

Realistic software example

File upload accepts max 5MB.

  • 4.99MB → accepted, 5.00MB → accepted (boundary itself is usually inclusive — confirm with requirements!), 5.01MB → rejected.
  • Real bug pattern this catches: developers frequently write if size > 5MB (correct) vs if size >= 5MB (off-by-one bug that rejects exactly-5MB files that should be allowed). BVA is the technique for catching this class of bug.

EP + BVA together is how professional QAs actually design test cases for any bounded input — EP gives you the categories, BVA gives you the sharpest values within them.

Exercise

A discount system gives 10% off for orders ৳500–৳2000. Design BVA test cases. (Answer at the end.)

7.3 Decision Table Testing Must Master

Concept

Used when output depends on a combination of multiple input conditions. Lay out all combinations of conditions as columns, and the resulting action as the last row.

Example

A loan approval system — approve if (Credit Score ≥ 700) AND (Income ≥ ৳30,000). Otherwise reject, unless there's a co-signer, in which case a lower bar applies.

Condition Rule 1 Rule 2 Rule 3 Rule 4
Credit Score ≥ 700 Y Y N N
Income ≥ 30,000 Y N Y N
Has co-signer – Y Y N
Action: Approve ✅ ✅ ✅ ❌

Each column becomes one test case. This technique is exactly what interviewers mean by "how would you test a feature with multiple business rules interacting."

7.4 State Transition Testing Must Know

Concept

Used when the system's behavior depends on its current state and moves to a new state based on an event. Model as states + transitions.

Example

An order's lifecycle — Placed → Confirmed → Shipped → Delivered, with a Cancelled state reachable from Placed or Confirmed but NOT from Shipped.

stateDiagram-v2
    [*] --> Placed
    Placed --> Confirmed
    Placed --> Cancelled
    Confirmed --> Shipped
    Confirmed --> Cancelled
    Shipped --> Delivered
    Shipped --> Cancelled: INVALID (should be blocked)

Good state transition tests specifically include invalid transitions — e.g., "verify a Shipped order cannot be cancelled" is often the highest-value test case, because that's exactly the transition developers forget to guard against.

7.5 Pairwise Testing Should Know

Concept

When multiple independent variables combine (e.g., Browser × OS × Login type), testing every combination explodes exponentially. Pairwise testing selects a much smaller subset that still covers every pair of values at least once — based on the empirical observation that most real bugs are triggered by interactions between just two parameters.

Example

3 browsers × 3 OSes × 2 login types = 18 full combinations, but a pairwise-designed set can cover all pairs in about 9 test cases. (Free tools like PICT can generate these — awareness-level only for you; understanding why it's used is what's tested, not tool proficiency.)

7.6 Cause-Effect Graphing Should Know

A more formal, visual precursor to decision tables — mapping causes (inputs) to effects (outputs) with logical operators (AND/OR/NOT), then converting the graph into a decision table. In practice, most BD interviews just want you to produce the decision table directly; know this term exists and that it's the theoretical basis for decision tables.

7.7 Error Guessing Should Know

Concept

Using experience and intuition to guess where bugs are likely to hide — no formal technique, just informed pattern recognition (empty fields, extremely long strings, special characters, double-clicking a submit button, going back in browser history mid-transaction).

7.8 Checklist-Based Testing Should Know

Using a pre-built checklist of common concerns (e.g., a standard "form validation checklist") to guide testing quickly, especially useful under time pressure.

7.9 Risk-Based Testing Must Know

Concept

Prioritizing testing effort based on the probability a feature will fail combined with the impact if it does. A payment feature (high impact, moderate probability) gets more testing attention than a footer link color (low impact, low probability), even under time pressure.

Low impact High impact
Low probability Test last / skip if no time Test with moderate priority
High probability Test with moderate priority Test first, most thoroughly

7.10 Exploratory Testing (technique view)

Already introduced in Part 6 — here it's worth noting it's a formal technique, not just "clicking around": experienced testers use structured approaches like session-based test management (time-boxed, documented exploration sessions with a specific charter/goal) to make it disciplined and reportable rather than ad-hoc.


Answers to exercises

7.1 Password field (8-20 chars) EP

Invalid-short (<8, e.g. 5 chars), Valid (8-20, e.g. 12 chars), Invalid-long (>20, e.g. 25 chars). If special-character rules exist, that's an additional partition axis.

7.2 Discount ৳500-৳2000 BVA

৳499 (just below min, no discount), ৳500 (min, discount applies), ৳501 (just above min, discount applies), ৳1999 (just below max, discount applies), ৳2000 (max, discount applies), ৳2001 (just above max, discount should NOT apply — verify this exact boundary carefully, it's where off-by-one bugs hide).

Interview questions — Part 7

  1. What's the difference between Equivalence Partitioning and Boundary Value Analysis, and why are they usually used together?
  2. Design a decision table for a shipping-fee system: free shipping if (order ≥ ৳1000) OR (user is Premium member).
  3. When would you use pairwise testing instead of testing every combination?
  4. Give an example of a state transition bug you'd specifically design a test case to catch.
  5. What is risk-based testing and how would you apply it if you only had 2 days to test a feature that would normally take a week?

Exercise set (attempt before checking any answers online)

  1. Design EP + BVA test cases for a "coupon code" field requiring exactly 6 digits.
  2. Design a decision table for: a user gets a "Gold" badge if (posts ≥ 100) AND (account age ≥ 1 year), OR if they are manually verified by an admin.
  3. Model the state transitions for a support ticket system: New → In Progress → Resolved → Closed, with Reopened reachable from Resolved or Closed but not from New.

Test Case Design

Must Master
Estimated time: 8 hours

8.1 Anatomy of a professional test case

Field Purpose
Test Case ID Unique identifier (e.g., TC_LOGIN_001)
Title Short, specific description of what's being verified
Preconditions What must be true before execution starts
Test Data Specific input values to use
Steps Numbered, unambiguous actions
Expected Result What should happen — precise, verifiable
Actual Result Filled in during execution
Status Pass/Fail/Blocked
Priority Business importance (High/Medium/Low)
Severity Impact of the defect if this fails (Critical/Major/Minor/Trivial) — technically a bug-report field, but experienced testers estimate it during design too
Environment Browser, OS, device, build version
Attachments/Evidence Screenshots, logs

8.2 Good vs. bad test case — side by side

❌ Bad:

Title: Test login
Steps: Try to log in
Expected: It should work

✅ Good:

TC_LOGIN_002 — Verify login fails with incorrect password
Preconditions: User account test@example.com exists and is active.
Test Data: Email: test@example.com, Password: WrongPass123
Steps:
1. Navigate to the login page.
2. Enter test@example.com in the Email field.
3. Enter WrongPass123 in the Password field.
4. Click "Login".
Expected Result: Login is rejected. An error message "Incorrect email or password" is displayed. User remains on the login page. No session/token is created.
Priority: High | Severity if fails: Major

The difference: the bad version is unrepeatable and unverifiable — two different testers would do different things and disagree on "did it pass." The good version is precise enough that anyone could execute it identically and get the same verdict.

8.3 A critical, often-missed detail: negative test cases specify the exact expected error

"Should show an error" is weak. "Should show the error message 'Incorrect email or password', not a generic 500 error page, and should NOT reveal whether the email exists" is what a strong QA engineer writes — because that last clause is testing a real security concern (user enumeration).

8.4 Test scenarios → test cases: the systematic thinking process

Before writing any test case, run this checklist mentally for any input field or feature:

  1. Happy path — the simplest valid case.
  2. Negative cases — invalid/missing/malformed input.
  3. Boundary cases — min, max, just outside.
  4. UI/validation — error messages, field states, disabled buttons.
  5. Data integrity — does it save/persist correctly?
  6. Security — can it be bypassed, injected, or abused?
  7. Compatibility — does it behave the same across browsers/devices? (lower priority at entry level, but mention it)
  8. Usability — is the interaction sensible?

This 8-point checklist is your general-purpose "how do I not miss anything" tool — use it below.


8.5 Scenario walkthroughs — from thinking to test cases

Below are 14 objects/features. For each, a short worked example shows the systematic thought process (not just answers) — apply the 8-point checklist above. These deliberately span software UI, physical objects (a favorite BD-interview curveball to test raw testing thinking, decoupled from any tech knowledge), and backend-adjacent features.

1. Login page

  • Happy: valid email + valid password → success, redirected to dashboard.
  • Negative: wrong password; non-existent email; empty fields; SQL-injection-style string in email field (' OR '1'='1); case-sensitivity of email.
  • Boundary: password at min/max allowed length.
  • Security: account lockout after N failed attempts; error message doesn't reveal "email exists but password wrong" vs "email doesn't exist" (prevents user enumeration).
  • Usability: "forgot password" link visible; password field masks input; caps-lock warning.

2. Registration

  • Happy: valid unique email, strong password, all required fields.
  • Negative: duplicate email; weak password rejected per policy; mismatched confirm-password; invalid email format (abc@, abc.com).
  • Boundary: name field at max character limit; age field at policy boundary (e.g., must be 18+).
  • Data integrity: does the account actually get created in the DB with correct field values?
  • Security: password stored hashed, not plaintext (you can't verify this via UI, but you should know to ask/flag it).

3. Password reset

  • Happy: request reset → receive email → click link → set new password → can log in with new password.
  • Negative: request reset for non-existent email (should NOT reveal whether email exists — same message either way); expired link; reused link; link tampered (change token in URL).
  • Boundary: link expiry time — test just before and just after expiry (BVA applied to time!).
  • Security: old password should stop working immediately after reset; other active sessions should ideally be invalidated.

4. OTP (One-Time Password)

  • Happy: correct OTP within time window → verified.
  • Negative: wrong OTP; expired OTP; OTP reused after already being consumed; requesting OTP repeatedly (rate limiting?).
  • Boundary: OTP validity window edges (BVA on time again); max resend attempts.
  • Security: is there a lockout after N wrong attempts to prevent brute-force? Is OTP a predictable pattern (sequential, always same digits)?

5. Search box

  • Happy: valid search term returns relevant results.
  • Negative: empty search; search term with no matches ("no results found" message, not a blank/broken page); special characters; SQL-injection-style input; extremely long input.
  • Boundary: 1-character search; max-length search string.
  • Usability: autocomplete/suggestions behavior; case-insensitivity; whitespace trimming (" laptop " should match "laptop").

6. E-commerce cart

  • Happy: add item → cart count updates → correct price shown.
  • Negative: add out-of-stock item; add item then it goes out of stock while in cart; quantity set to 0 or negative.
  • Boundary: max quantity per item (if limited); max number of distinct items in cart.
  • Data integrity: price shown in cart matches product page price at time of adding — what happens if the price changes while item sits in cart?
  • Concurrency: two tabs open, remove item in one — does the other tab's cart stay consistent or go stale?

7. Checkout / Payment

  • Happy: valid payment method, valid address → order placed, confirmation shown.
  • Negative: expired/invalid card details; insufficient balance; payment gateway timeout; network drops mid-payment.
  • Boundary: order total at any minimum-order-value threshold.
  • Reliability/recovery: what happens if payment succeeds on the gateway side but the response back to the app is lost? (This is a real, high-severity class of bug — "was I charged twice?")
  • Security: no full card number should ever appear in logs or be displayed back.

8. ATM

  • Happy: valid PIN, sufficient balance, valid withdrawal amount → cash dispensed, balance updated, receipt offered.
  • Negative: wrong PIN (3 attempts then card retained — state transition!); insufficient balance; withdrawal amount not a multiple of available note denominations.
  • Boundary: withdrawal at daily limit; exactly at account balance.
  • Recovery: power/network failure after cash is dispensed but before balance is debited — does the bank's system reconcile this correctly? (This is the kind of question that separates strong candidates — thinking about failure mid-transaction.)

9. Elevator

  • Happy: press floor button → elevator arrives, doors open, transports to correct floor.
  • Negative: press button for a floor while already at that floor; press multiple floor buttons in sequence; weight limit exceeded (alarm, doors won't close).
  • Boundary: exactly at max weight/occupancy.
  • Safety/recovery: door obstruction sensor reopens door; power failure — does it stop safely, at nearest floor, with emergency lighting/alarm?
  • Concurrency: two people on different floors both call it simultaneously — correct scheduling logic?

10. Traffic light

  • State transitions: Red → Green → Yellow → Red, verify no invalid transition (e.g., Red directly to Yellow).
  • Timing: correct duration for each state (boundary testing on timing).
  • Edge cases: pedestrian crossing button interaction; power failure fallback behavior (flashing red/off); synchronization with adjacent intersection lights.

11. Calculator

  • Happy: basic operations produce correct results.
  • Negative: divide by zero (should show error, not crash); invalid sequences (pressing operators consecutively, e.g., 5 + + 3).
  • Boundary: very large numbers (overflow behavior); decimal precision limits.
  • Usability: clear/reset button behavior; does it correctly handle order of operations if it's a "smart" calculator?

12. File upload

  • Happy: valid file type/size uploads successfully.
  • Negative: unsupported file type; corrupted file; file with malicious extension disguised (e.g., .exe renamed .jpg); empty file (0 bytes).
  • Boundary: file size at exact max limit (just under, at, just over — BVA again).
  • Security: does the server validate the actual file content/type server-side, not just trust the client-reported extension? Can you upload a script and have it execute?
  • Reliability: upload interrupted mid-transfer — does it fail cleanly or leave a corrupted partial file?

13. Date picker

  • Happy: select a valid date → correctly populates the field.
  • Negative: manually typing an invalid date (Feb 30); selecting a date outside an allowed range (e.g., booking system won't allow past dates).
  • Boundary: first/last day of month; leap year Feb 29; year boundaries (Dec 31 → Jan 1).
  • Usability: does the calendar UI disable invalid dates, or let you pick them and then error?

14. Banking application (fund transfer)

  • Happy: valid recipient, sufficient balance, valid amount → transfer succeeds, both balances update correctly.
  • Negative: transfer to non-existent account; transfer amount exceeding balance; transfer to own account (should this be allowed?); negative or zero amount.
  • Boundary: transfer of exact full balance; daily transfer limit boundary.
  • Data integrity: sender's balance decreases by exactly the transferred amount, receiver's increases by exactly the same — verify via SQL, not just UI, if you have DB access (this is where SQL from Part 12 becomes directly useful in a QA job).
  • Concurrency: two simultaneous transfer requests draining the same account — does the system correctly prevent overdraft (race condition)?
  • Recovery: transaction fails halfway (network drop) — is it fully rolled back, or does money "disappear" from one side without appearing on the other? This is the single most important non-negotiable property of any financial system: atomicity.

8.6 Objects to practice independently (no walkthrough given — use the checklist yourself)

Password strength meter, image upload, messaging application (read receipts, message ordering), Facebook-like feed (infinite scroll, like/unlike toggling), microwave, vending machine, USB cable, water bottle. Write at least 5 test scenarios each using the 8-point checklist before moving on.

Interview questions — Part 8

  1. Write a complete, professional test case for "verify a user cannot withdraw more money than their account balance from an ATM."
  2. What's the difference between a good and bad expected result, and why does it matter for regression later?
  3. Pick any everyday object and demonstrate your systematic thinking process live (this is a real, common BD interview format).

Real-World Scenario Testing: "How Would You Test X?"

Must Master
Estimated time: 5 hours

9.1 The framework (memorize this structure — it's how you should answer out loud in an interview)

When asked "how would you test X," don't just list random ideas. Structure your answer:

  1. Clarify scope first — ask 1-2 sharp questions about what X actually does and its constraints (shows maturity, not guessing).
  2. State your categories, then fill each with 2-3 concrete examples: - Functional (does it do the job) - Negative (invalid inputs/misuse) - Boundary (edges of valid ranges) - Validation (format/data correctness) - Usability (is it sensible to use) - Compatibility (across environments) - Security (can it be abused/bypassed) - Performance (does it hold up under load) - Reliability/Recovery (does it survive failure gracefully) - Concurrency (simultaneous use conflicts) - Data integrity (is stored data correct and consistent)
  3. Prioritize — say out loud which 2-3 categories matter most for this specific feature, and why. This step is what separates strong candidates: showing judgment, not just an exhaustive checklist recital.

9.2 Twenty scenarios — practice independently first, model answers follow

Attempt each of these on paper/in your head using the framework above, before reading the model answers section further below. This is the single highest-value exercise in this entire guide for interview performance — don't skip the "attempt first" step.

  1. How would you test a mobile phone (as a hardware+software product)?
  2. How would you test a USB charging cable?
  3. How would you test a food delivery app's "track your order" feature?
  4. How would you test a URL shortener service?
  5. How would you test a "forgot password" flow end-to-end?
  6. How would you test a ride-sharing app's fare calculation?
  7. How would you test a hotel booking system's date-range availability?
  8. How would you test an image compression feature?
  9. How would you test a notification system (push notifications)?
  10. How would you test a "like" button on a social media post?
  11. How would you test a coupon/discount code system?
  12. How would you test a multi-language (i18n) website's language switcher?
  13. How would you test a video streaming app's playback quality selector?
  14. How would you test a "share this post" feature?
  15. How would you test an inventory management system's stock-count accuracy?
  16. How would you test a chat application's "typing..." indicator?
  17. How would you test a QR code payment feature?
  18. How would you test a form with 20 fields, half required and half optional?
  19. How would you test a "delete account" feature?
  20. How would you test a rate-limited public API?

9.3 Model answers (read these AFTER attempting the scenarios above)

#1 Mobile phone

Clarify — hardware, software, or both? Functional: calls, texts, camera, apps launch. Negative: low battery behavior, no SIM, airplane mode edge cases. Boundary: max storage full, max app count. Usability: screen responsiveness, button layout. Compatibility: different chargers/accessories, different OS versions if testing an app on it. Performance: app launch time, multitasking. Reliability: does it survive a restart mid-update, does battery drain reporting stay accurate. Priority: for a phone specifically, I'd prioritize core call/text reliability and battery behavior first — those are the "must never break" fundamentals users notice immediately.

#5 Forgot password flow

Clarify — email-based or SMS/OTP-based? Functional: request → email arrives → link works → new password set → can log in. Negative: non-existent email (no info leak), expired link, already-used link, mismatched password confirmation. Boundary: link expiry time edges. Security: old password invalidated immediately, no token reuse, rate-limit reset requests to prevent abuse. Data integrity: password is actually hashed and updated in the DB, old sessions ideally invalidated. Priority: I'd prioritize security and the negative/expiry cases hardest here, because a broken password-reset flow is a direct account-takeover risk, not just an inconvenience.

#9 Push notification system

Functional: triggering event sends notification, tapping it opens the right screen (deep linking). Negative: notification permission denied by user — does the app fail gracefully or crash trying to send anyway? Boundary: extremely long notification text (truncation behavior). Reliability: app killed/backgrounded — does notification still arrive? Concurrency: many notifications fired simultaneously — batching/grouping behavior, or does the user get spammed? Priority: deliverability and correct deep-linking are the two things that actually matter to users; visual polish is secondary.

#11 Coupon/discount code

Functional: valid code applies correct discount. Negative: expired code, already-used single-use code, code for a different user/region, invalid/typo'd code. Boundary: minimum order value required to use the code, exactly at that value. Data integrity: does using the code correctly decrement its usage-count/limit in the DB, and prevent a second simultaneous use (concurrency) if it's single-use? Security: can the discount be manipulated client-side (e.g., editing the price in a request before the server recalculates)? Priority: preventing double-use and client-side price manipulation are the two categories I'd hit hardest — that's where real money is lost.

#20 Rate-limited public API

Functional: requests under the limit succeed normally. Negative: request exactly at/over the limit returns the correct status code (commonly 429 Too Many Requests), with a clear error body. Boundary: the exact request count at the limit boundary (BVA again — off-by-one is extremely common here, e.g., is it "100 requests allowed" or "101"?). Reliability: does the rate-limit counter reset correctly at the stated interval? Concurrency: many simultaneous requests near the limit — does the system correctly count them all, or does a race condition let a few extra through? Priority: the boundary/off-by-one check and the concurrency race-condition check are the two a strong candidate calls out unprompted — most candidates only think of the simple "does it block after N requests" case.

In plain English

(Attempt the remaining 15 scenarios using the same framework — writing out your own answer, even briefly, is far more valuable than reading a 20th model answer.)

Interview questions — Part 9

  1. Demonstrate the framework live on a scenario the interviewer picks on the spot.
  2. What's the value of stating "clarifying questions" before diving into test ideas?
  3. Why does prioritization ("which categories matter most here and why") matter more than an exhaustive list?

Bug Reporting

Must Master
Estimated time: 4 hours

10.1 Anatomy of a professional bug report

Field Purpose
Title Short, specific, searchable — describes symptom + context
Description Brief summary of the problem
Environment Browser/OS/device/app version/build number
Preconditions State required before the steps (e.g., logged in as X role)
Steps to Reproduce Numbered, exact, minimal
Expected Result What should have happened
Actual Result What actually happened
Severity Technical impact of the defect
Priority Business urgency to fix
Evidence Screenshot, screen recording, logs, HAR file
Reproducibility Always / Sometimes (X out of Y attempts) / Once

10.2 Severity vs. Priority — the #1 most-asked QA interview question Must Master

Severity Priority
Definition How badly the defect affects the system/functionality How urgently it needs to be fixed, business-wise
Set by QA (technical judgment) Often product/business, sometimes jointly
Independent of each other? Yes — they don't have to match Yes
The classic example that proves you understand this

A spelling mistake in the company name on the homepage is Low severity (nothing is functionally broken) but High priority (embarrassing, must be fixed before anyone important sees it, fix immediately). Conversely, a crash in a rarely-used admin report page is High severity (a crash!) but might be Low priority if almost no one uses that page and a workaround exists.

Severity level Meaning Example
Critical/Blocker System crash, data loss, complete feature failure, no workaround Checkout page throws 500 error for all users
Major/High Major function broken, but a workaround exists or it's isolated Filter doesn't work, but users can still browse all products
Minor/Medium Minor function affected, doesn't block core use A secondary button is misaligned
Trivial/Low Cosmetic, doesn't affect functionality Typo in a tooltip

10.3 Bad bug report → rewritten professionally

❌ Bad:

Title: Login broken
It doesn't work when I try to log in. Please fix.

✅ Rewritten:

Title

Login fails with "Internal Server Error" when password contains a special character (e.g., #)
Environment: Chrome 128, Windows 11, staging build v2.4.1
Preconditions: User account exists with password containing #
Steps to Reproduce:
1. Navigate to /login
2. Enter valid email qa.test@example.com
3. Enter password Pass#1234
4. Click "Login"
Expected Result: User logs in successfully and is redirected to the dashboard.
Actual Result: Page displays "500 Internal Server Error." No redirect occurs. Console shows a JS error (see attached screenshot).
Severity: Critical (blocks login entirely for any user whose password contains this character)
Priority: High
Reproducibility: Always (5/5 attempts)
Evidence: [screenshot attached], [console log attached]

Notice everything that changed: specificity, exact reproduction steps, precise actual vs expected, environment details, and a severity/priority judgment with reasoning.

10.4 The defect lifecycle Must Master

stateDiagram-v2
    [*] --> New
    New --> Assigned
    Assigned --> Open
    Open --> Fixed
    Fixed --> Retest
    Retest --> Reopened: fix didn't work
    Retest --> Closed: fix confirmed
    Reopened --> Assigned
    New --> Rejected: not a valid bug
    New --> Duplicate: already reported
    New --> WontFix: accepted, won't be fixed
    Rejected --> [*]
    Duplicate --> [*]
    WontFix --> [*]
    Closed --> [*]
State Meaning
New Just reported, not yet triaged
Assigned Assigned to a developer
Open Developer acknowledges and is working on it
Fixed Developer believes it's resolved, ready for QA to verify
Retest QA is re-testing the fix
Reopened Retest failed — the bug still exists (or wasn't fully fixed)
Closed Retest passed — confirmed fixed
Rejected Not actually a bug (e.g., working as intended, or tester error)
Duplicate Already reported elsewhere
Won't Fix Valid bug, but a business decision was made not to fix it (low value, too risky, deprecated feature)

Interview questions — Part 10

  1. Explain severity vs priority with a real example where they don't match.
  2. Walk through the full defect lifecycle for a bug that gets fixed on the first attempt, and one that gets reopened.
  3. What's the difference between "Rejected" and "Won't Fix"?
  4. Why does "Steps to Reproduce" need to be minimal, not just complete?

Exercise

Rewrite this into a professional bug report: "The search doesn't show results sometimes, weird." Invent reasonable specific details (environment, exact steps, exact actual/expected) as you would need to in a real job.


Jira & Test Management Essentials

Must Know
Estimated time: 3 hours

11.1 Core Jira concepts

Term Meaning
Project Container for all work on a product
Issue Generic term for any trackable item (bug, story, task)
Epic A large body of work, broken into smaller stories
Story A user-facing feature/requirement
Task A piece of work, not necessarily user-facing
Bug A defect issue type
Subtask A smaller piece of a larger issue
Priority field Business urgency (Highest/High/Medium/Low/Lowest)
Status Workflow state (To Do / In Progress / In Review / Done, customizable)
Sprint A time-boxed iteration issues are assigned to
Backlog Unscheduled issues
Assignee Who's responsible for the issue
Reporter Who created the issue
Comment Discussion thread on an issue
Attachment Files (screenshots, logs) attached to an issue
Filter (JQL) Jira Query Language — search issues, e.g. project = "MYAPP" AND status = "Open" AND assignee = currentUser()

11.2 A QA's typical Jira workflow

  1. Find/create a Bug issue with all the fields from Part 10.
  2. Set Priority and Severity (severity is often a custom field, not built-in by default).
  3. Link the bug to the related Story/Epic.
  4. Attach evidence.
  5. Move status as it progresses (New → In Progress → In Review → Done, mapped to the lifecycle in 10.4).
  6. Comment when retesting: "Retested on build v2.4.2 — confirmed fixed" or "Reopening — issue persists, see new screenshot."

11.3 TestRail / test management tools (brief) Should Know

TestRail, Zephyr, and Xray are dedicated test-case management tools (often plugged into Jira) that organize test cases into suites/runs and track execution results and coverage separately from bug tracking. At entry level, know they exist and what problem they solve (organizing test cases, as distinct from Jira's job of tracking issues) — hands-on tool proficiency is picked up on the job in days, not something to pre-study deeply.

Practice exercise

Using a free Jira Cloud trial (or the free tier) or even just on paper: create a mock Epic ("User Authentication"), one Story under it ("Password Reset"), and 2 linked Bug issues with full fields filled per Part 10's structure.

Linux for SQA

Must Know
Estimated time: 4 hours

Dual-purpose: every backend dev job lives in a terminal too.

13.1 Why QA needs Linux

Many BD companies deploy on Linux servers; QA engineers often need to check application logs on a server, verify a file exists, check running processes, or use curl to hit an API directly. Written tests frequently include a "what does this command do" or "write a command to do X" section.

13.2 Command cheat sheet Must Master

Command Purpose Example
pwd Print working directory pwd
ls List files ls -la (show all, long format)
cd Change directory cd /var/log
mkdir Make directory mkdir test_data
touch Create empty file touch notes.txt
cp Copy cp file.txt backup.txt
mv Move/rename mv old.txt new.txt
rm Remove rm -r old_folder (recursive, be careful)
cat Print full file content cat app.log
less View file page-by-page less app.log
head First N lines head -n 20 app.log
tail Last N lines (great for logs) tail -f app.log (follow live)
grep Search text grep "ERROR" app.log
find Find files find . -name "*.log"
chmod Change permissions chmod +x script.sh
ps List running processes ps aux
top Live process/resource monitor top
kill Terminate a process kill -9 1234
curl Make HTTP requests from terminal curl -X GET https://api.example.com/users
wget Download a file wget https://example.com/file.zip

13.3 Pipes and redirection Must Master

# Pipe: send output of one command as input to the next
cat app.log | grep "ERROR" | wc -l     # count how many ERROR lines exist

# Redirection
echo "test run started" > log.txt      # overwrite file
echo "test run finished" >> log.txt    # append to file
grep "FAIL" results.txt > failures.txt # save matches to a new file
Why this matters for QA specifically

this exact cat | grep | wc -l pattern is how you'd quickly answer "how many errors happened in this log during the test run" without opening a huge file in an editor.

13.4 Environment variables Should Know

echo $HOME
export API_URL="https://staging.example.com"
echo $API_URL

Used constantly for storing config like API base URLs or credentials in test scripts without hardcoding them.

13.5 Logs — how QA actually uses them

A backend error often isn't visible in the UI at all (silent failure) but is visible in the server logs. Practical QA move: tail -f the application log while manually reproducing a bug, to capture the exact stack trace/error for your bug report — this single technique dramatically improves your bug reports' usefulness to developers.

Written-test-style exercises

  1. Write a command to find all .txt files in the current directory and subdirectories.
  2. Write a command to show the last 50 lines of server.log.
  3. Write a command to count how many lines in access.log contain the string "500".
  4. Write a command to give a script called run_tests.sh execute permission.
  5. Write a command chain to find all lines containing "timeout" in app.log and save them to timeouts.txt.

Git & GitHub

Must Know
Estimated time: 2 hours

14.1 Why QA needs Git

Test scripts, automation code, and test documentation increasingly live in version control alongside application code. Even manual QAs are commonly expected to check out a specific branch/build to test, and to know basic collaboration flow.

14.2 Core commands Must Master

git init                      # start a new repo
git clone <url>                # copy a remote repo locally
git status                     # see what's changed
git add file.txt                # stage a file
git add .                       # stage everything
git commit -m "Add login test cases"   # commit staged changes
git push                        # send commits to remote
git pull                        # fetch + merge latest remote changes
git branch                      # list branches
git branch feature/login-tests  # create a branch
git checkout feature/login-tests   # switch to a branch (older syntax)
git switch feature/login-tests     # switch to a branch (modern syntax)
git merge feature/login-tests      # merge a branch into current branch
git fetch                       # download remote changes without merging

14.3 Pull Requests (PRs)

A PR proposes merging one branch into another (commonly a feature branch into main), allowing review/discussion before the merge. As QA, you might open a PR for a new automated test script, or you might be asked to test the code in a PR branch before it merges.

14.4 .gitignore

A file listing patterns Git should never track (e.g., node_modules/, .env, __pycache__/, credentials, local config). Important because accidentally committing credentials/secrets is a real, common, embarrassing mistake — knowing to .gitignore sensitive files is a basic professional habit.

Practice exercise

Create a free GitHub account (if you don't have one), create a new repo called qa-practice, clone it locally, create a branch, add a file with 3 sample test cases in it, commit, push, and open a PR merging it into main. This exact workflow is also your first step toward Part 23's portfolio projects.

Resources

  • Git official docs — reference only, don't read cover-to-cover.
  • GitHub Skills — free interactive lessons, essential if you've never used Git hands-on before.

SQL — Scratch to Advanced (SQA + RCM Data Analyst track)

Must Master
Estimated time: 36 hours

Redesigned start-to-finish. This section now serves two goals at once: it's still the highest dual-purpose skill in the whole guide (QA data validation ↔ Django ORM later), and it's now also a real, advanced-level SQL track aimed at data-analyst roles like Commure/Augmedix Dhaka's RCM (Revenue Cycle Management) Data Analyst — window functions, CTEs, reconciliation logic, and query performance included. Don't rush the first half even if it feels easy; the advanced half assumes it's automatic.

12.1 Why this section is shaped the way it is

In plain English

SQL is just a structured way of asking a database questions — "show me," "count me," "which of these match." Everything from here to the end of this section is the same handful of questions asked in more and more sophisticated ways. Nothing here is a different subject; it's the same skill, going deeper.

QA data validation ("did this record actually save correctly?") uses the first half of this section constantly. An RCM data analyst role uses all of it, daily — that job is largely "write SQL against claims/payments/denial data to answer a business question, find a data problem, or build a report." So this section is ordered as one continuous ramp: basics → aggregation → joins → subqueries → CTEs → window functions → date/string/NULL handling → data cleaning & reconciliation → performance. Work through it in order; each part leans on the one before it.

12.2 Setup & the schema we'll use throughout

Install PostgreSQL locally (preferred — it's what most modern data/backend teams in BD, including Django shops, actually run) or use a free sandbox (SQLZoo, DB Fiddle set to Postgres). For the first few basics sections we'll reuse a small generic schema; from 12.10 onward we switch to a small healthcare RCM schema — patients, providers, payers, claims, payments, denials — because that's the exact shape of data an RCM analyst works with every day, and because it gives every JOIN/subquery/window-function example a real business meaning instead of an abstract one.

-- generic schema (Parts 12.3 - 12.9)
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100) UNIQUE,
    country VARCHAR(50),
    created_at DATE
);

CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT,
    product_name VARCHAR(100),
    amount DECIMAL(10,2),
    status VARCHAR(20),
    order_date DATE,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
-- RCM schema (Parts 12.10 onward) -- this is the one to really learn
CREATE TABLE payers (
    payer_id INT PRIMARY KEY,
    payer_name VARCHAR(100),      -- 'Blue Cross', 'Medicare', 'Self-Pay', ...
    payer_type VARCHAR(20)        -- 'Commercial' / 'Government' / 'Self-Pay'
);

CREATE TABLE providers (
    provider_id INT PRIMARY KEY,
    provider_name VARCHAR(100),
    specialty VARCHAR(50)
);

CREATE TABLE patients (
    patient_id INT PRIMARY KEY,
    full_name VARCHAR(100),
    dob DATE,
    payer_id INT REFERENCES payers(payer_id)
);

CREATE TABLE claims (
    claim_id INT PRIMARY KEY,
    patient_id INT REFERENCES patients(patient_id),
    provider_id INT REFERENCES providers(provider_id),
    payer_id INT REFERENCES payers(payer_id),
    service_date DATE,
    submitted_date DATE,
    billed_amount DECIMAL(10,2),
    claim_status VARCHAR(20)      -- 'Submitted' / 'Paid' / 'Partially Paid' / 'Denied' / 'Pending'
);

CREATE TABLE claim_payments (
    payment_id INT PRIMARY KEY,
    claim_id INT REFERENCES claims(claim_id),
    payment_date DATE,
    paid_amount DECIMAL(10,2)
);

CREATE TABLE denials (
    denial_id INT PRIMARY KEY,
    claim_id INT REFERENCES claims(claim_id),
    denial_code VARCHAR(10),      -- e.g. 'CO-16', 'CO-97'
    denial_reason VARCHAR(200),
    denial_date DATE
);
erDiagram
    PAYERS ||--o{ PATIENTS : covers
    PAYERS ||--o{ CLAIMS : bills
    PROVIDERS ||--o{ CLAIMS : renders
    PATIENTS ||--o{ CLAIMS : has
    CLAIMS ||--o{ CLAIM_PAYMENTS : receives
    CLAIMS ||--o{ DENIALS : may_have
What "RCM" means, in one paragraph

Revenue Cycle Management is the whole process of a healthcare provider getting paid: a patient is seen (encounter) → the visit is billed to an insurer as a claim → the payer (insurer) either pays it, partially pays it, or denies it with a reason code → unpaid/denied claims get worked, corrected, and resubmitted. An RCM data analyst's job is almost entirely: query this data to find where money is stuck, where claims are wrong, where denial patterns exist, and how fast (or slow) payers are paying. Every query pattern below maps directly onto that.

12.3 SELECT, WHERE, ORDER BY, LIMIT, DISTINCT Must Master

-- SELECT specific columns
SELECT name, email FROM users WHERE country = 'Bangladesh';

-- every column
SELECT * FROM users;

-- DISTINCT -- unique values only
SELECT DISTINCT country FROM users;

-- ORDER BY -- ASC is default, DESC reverses
SELECT name, created_at FROM users ORDER BY created_at DESC;

-- LIMIT -- cap the number of rows returned
SELECT * FROM users ORDER BY created_at DESC LIMIT 5;
In plain English

SELECT = "show me these columns." FROM = "out of this table." WHERE = "but only rows matching this." ORDER BY = "sorted like this." LIMIT = "only give me this many." Read any query top to bottom in that order and it reads like a sentence.

12.4 Filtering deeper: LIKE, IN, BETWEEN, NULL, AND/OR/NOT Must Master

-- LIKE (pattern matching: % = any characters, _ = exactly one character)
SELECT * FROM users WHERE email LIKE '%@gmail.com';
SELECT * FROM users WHERE name LIKE 'A%';          -- starts with A
SELECT * FROM users WHERE name ILIKE 'a%';         -- Postgres: case-insensitive LIKE

-- IN -- matches any value in a list
SELECT * FROM orders WHERE status IN ('Pending', 'Processing');

-- BETWEEN -- inclusive range
SELECT * FROM orders WHERE amount BETWEEN 500 AND 2000;

-- NULL handling -- this trips up almost everyone at first
SELECT * FROM users WHERE country IS NULL;         -- correct
SELECT * FROM users WHERE country = NULL;           -- WRONG -- always returns zero rows
SELECT * FROM users WHERE country IS NOT NULL;      -- correct "has a value"

-- AND / OR / NOT, and why parentheses matter
SELECT * FROM orders WHERE status = 'Delivered' AND amount > 1000;
SELECT * FROM orders WHERE status = 'Pending' OR status = 'Processing' AND amount > 500;
-- ^ ambiguous to a human reader -- AND binds tighter than OR, so this actually means:
--   status = 'Pending' OR (status = 'Processing' AND amount > 500)
-- Always parenthesize explicitly once you mix AND/OR:
SELECT * FROM orders WHERE (status = 'Pending' OR status = 'Processing') AND amount > 500;
Why = NULL is a trap, explained

NULL means "unknown," not "empty." Any comparison against an unknown value is itself unknown — not true, not false. IS NULL / IS NOT NULL exist specifically because = and != can never detect NULL. This single rule explains a huge share of "why is my WHERE clause silently returning nothing" bugs, in QA and in real analyst work.

12.5 CASE — conditional logic inside a query Must Master

SELECT name,
  CASE
    WHEN country = 'Bangladesh' THEN 'Domestic'
    ELSE 'International'
  END AS region
FROM users;

-- multi-branch CASE, RCM-flavored
SELECT claim_id, billed_amount,
  CASE
    WHEN billed_amount >= 5000 THEN 'High Value'
    WHEN billed_amount >= 1000 THEN 'Standard'
    ELSE 'Low Value'
  END AS claim_tier
FROM claims;

CASE is not a special feature — it's an expression, meaning it can appear anywhere a column can: in SELECT (shown above), inside WHERE, inside an aggregate function (12.9), even inside ORDER BY. That flexibility is exactly why it shows up constantly in both QA scripting and real analyst reporting.

12.6 Data modification: INSERT, UPDATE, DELETE Must Know

INSERT INTO users (id, name, email, country, created_at)
VALUES (101, 'Rafi Ahmed', 'rafi@example.com', 'Bangladesh', '2026-08-01');

UPDATE orders SET status = 'Delivered' WHERE id = 45;

DELETE FROM orders WHERE status = 'Cancelled' AND order_date < '2025-01-01';
The single most important habit in this whole section

Always test UPDATE/DELETE with a SELECT using the exact same WHERE clause first, to see precisely which rows will be affected before you run the destructive version. In a real RCM analyst job, an un-scoped UPDATE claims SET claim_status = 'Paid' with a typo'd or missing WHERE clause is the kind of mistake that shows up in a postmortem. This habit alone prevents that class of incident.

12.7 Aggregate functions & GROUP BY Must Master

SELECT COUNT(*) FROM orders;
SELECT SUM(amount) FROM orders WHERE status = 'Delivered';
SELECT AVG(amount) FROM orders;
SELECT MIN(order_date), MAX(order_date) FROM orders;

-- GROUP BY: one aggregate result per group
SELECT user_id, COUNT(*) AS order_count, SUM(amount) AS total_spent
FROM orders
GROUP BY user_id;

-- RCM version: total billed and claim count per payer
SELECT payer_id, COUNT(*) AS claim_count, SUM(billed_amount) AS total_billed
FROM claims
GROUP BY payer_id;
Rule that trips people up

Every column in the SELECT list that is not wrapped in an aggregate function must appear in the GROUP BY clause. SELECT user_id, product_name, COUNT(*) FROM orders GROUP BY user_id is invalid in Postgres — product_name is neither aggregated nor grouped, so the database doesn't know which row's product_name to show for a group that spans many rows.

12.8 HAVING & complex GROUP BY Must Master

-- HAVING filters AFTER grouping/aggregation -- WHERE can't do this
SELECT user_id, SUM(amount) AS total_spent
FROM orders
GROUP BY user_id
HAVING SUM(amount) > 5000;

-- grouping by more than one column (a "complex" GROUP BY)
SELECT payer_id, claim_status, COUNT(*) AS claim_count
FROM claims
GROUP BY payer_id, claim_status
ORDER BY payer_id, claim_status;

-- HAVING combined with a real business question:
-- which payers have more than 10 denied claims?
SELECT payer_id, COUNT(*) AS denied_count
FROM claims
WHERE claim_status = 'Denied'
GROUP BY payer_id
HAVING COUNT(*) > 10;
Critical distinction (frequently tested)

WHERE filters individual rows before grouping happens. HAVING filters entire groups after aggregation. You cannot write WHERE SUM(amount) > 5000 — at the point WHERE runs, no sum has been computed yet. This is one of the most commonly asked "explain the difference" questions in both QA and analyst interviews.

12.9 Conditional aggregation — the report-building pattern Must Master

In plain English

Putting a CASE expression inside an aggregate function lets you count or sum only the rows that match a condition, instead of running a separate query per condition. It's how you build a single "pivoted" summary row instead of many narrow ones — exactly what a report or dashboard query needs to do.

-- one row per payer, with paid/denied/pending counts side by side
SELECT
  payer_id,
  COUNT(*) AS total_claims,
  COUNT(CASE WHEN claim_status = 'Paid' THEN 1 END) AS paid_count,
  COUNT(CASE WHEN claim_status = 'Denied' THEN 1 END) AS denied_count,
  COUNT(CASE WHEN claim_status = 'Pending' THEN 1 END) AS pending_count,
  SUM(CASE WHEN claim_status = 'Paid' THEN billed_amount ELSE 0 END) AS paid_amount
FROM claims
GROUP BY payer_id;

Compare this to running four separate WHERE claim_status = 'X' GROUP BY payer_id queries and stitching the results together by hand — conditional aggregation does it in one pass, one query, one result set. This exact pattern is one of the most commonly asked "write me a query" questions in data-analyst screens, because it directly tests whether you can build a report, not just filter a table.

12.10 JOINs — INNER, LEFT, RIGHT, multi-table Must Master

From here on we use the RCM schema (12.2).

-- INNER JOIN: only rows with a match in both tables
SELECT c.claim_id, p.full_name, c.billed_amount
FROM claims c
INNER JOIN patients p ON c.patient_id = p.patient_id;

-- LEFT JOIN: all rows from claims, matched payment info if it exists (else NULL)
SELECT c.claim_id, c.billed_amount, cp.paid_amount
FROM claims c
LEFT JOIN claim_payments cp ON c.claim_id = cp.claim_id;

-- find claims that were never paid at all (classic RCM + QA task)
SELECT c.claim_id, c.billed_amount
FROM claims c
LEFT JOIN claim_payments cp ON c.claim_id = cp.claim_id
WHERE cp.payment_id IS NULL;

-- RIGHT JOIN: mirror of LEFT JOIN -- rarely used in practice; most people
-- just flip table order and write LEFT JOIN instead, for readability
SELECT c.claim_id, cp.paid_amount
FROM claim_payments cp
RIGHT JOIN claims c ON c.claim_id = cp.claim_id;

-- multi-table join: claim + patient + provider + payer, all at once
SELECT
  c.claim_id, p.full_name AS patient, pr.provider_name,
  py.payer_name, c.billed_amount, c.claim_status
FROM claims c
JOIN patients p  ON c.patient_id  = p.patient_id
JOIN providers pr ON c.provider_id = pr.provider_id
JOIN payers py    ON c.payer_id    = py.payer_id;
Interview-favorite question

"Find all claims that were never paid" is exactly the LEFT JOIN + WHERE ... IS NULL pattern above. Memorize this pattern — it's asked constantly in both QA and analyst interviews because it directly mirrors a real task: finding data-integrity gaps (QA framing) or unpaid revenue (RCM framing). Same query, two job titles.

12.11 Self joins Must Know

-- classic self join: employees and their managers, same table
SELECT e.name AS employee, m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;

-- RCM-flavored self join: find pairs of claims for the same patient
-- submitted on the same day (possible duplicate submission)
SELECT c1.claim_id AS claim_a, c2.claim_id AS claim_b, c1.patient_id, c1.submitted_date
FROM claims c1
JOIN claims c2
  ON c1.patient_id = c2.patient_id
 AND c1.submitted_date = c2.submitted_date
 AND c1.claim_id < c2.claim_id;   -- avoids matching a row with itself, and avoids duplicate mirror pairs
In plain English

A self join is just joining a table to a second copy of itself so you can compare rows within the same table to each other — "does any other row in this same table relate to this row." The c1.claim_id < c2.claim_id trick is how you stop it from matching a claim to itself, and from returning every pair twice (once each direction).

12.12 Subqueries Must Know

-- subquery in WHERE
SELECT full_name FROM patients
WHERE patient_id IN (SELECT patient_id FROM claims WHERE billed_amount > 5000);

-- subquery in FROM (a "derived table")
SELECT payer_id, AVG(claim_total) AS avg_claim_total
FROM (
  SELECT payer_id, SUM(billed_amount) AS claim_total
  FROM claims
  GROUP BY payer_id, patient_id
) sub
GROUP BY payer_id;

-- scalar subquery in SELECT
SELECT claim_id, billed_amount,
  (SELECT AVG(billed_amount) FROM claims) AS overall_avg
FROM claims;

12.13 Correlated subqueries Must Know

In plain English

A normal subquery runs once, on its own, and hands back a fixed result. A correlated subquery reruns once per row of the outer query, because it references a column from the outer row — think of it as a mini-question asked separately for every single row, instead of one question asked once.

-- for each claim, is its billed_amount above the average for THAT SAME payer?
-- (note: claims.payer_id below refers to the OUTER query's current row --
--  that's what makes this correlated, not a plain subquery)
SELECT c1.claim_id, c1.payer_id, c1.billed_amount
FROM claims c1
WHERE c1.billed_amount > (
  SELECT AVG(c2.billed_amount)
  FROM claims c2
  WHERE c2.payer_id = c1.payer_id
);
Why this matters for an interview

Being able to say out loud "this is correlated because the inner query references the outer query's current row, so conceptually it re-runs per outer row" is a strong signal in a data-analyst screen — it shows you understand why the query works, not just that it happens to return the right answer. It also foreshadows 12.29-12.31 (performance): a correlated subquery over a huge table can be slow precisely because of that per-row re-execution, which is exactly the kind of thing EXPLAIN will show you.

12.14 EXISTS / NOT EXISTS Must Know

-- EXISTS -- often faster than IN for large tables, because it can stop
-- at the first match instead of building a full list to compare against
SELECT p.full_name FROM patients p
WHERE EXISTS (SELECT 1 FROM claims c WHERE c.patient_id = p.patient_id AND c.billed_amount > 5000);

-- NOT EXISTS -- the professional-standard way to write "find missing" queries,
-- often preferred over LEFT JOIN ... IS NULL for readability at scale
SELECT c.claim_id FROM claims c
WHERE NOT EXISTS (SELECT 1 FROM claim_payments cp WHERE cp.claim_id = c.claim_id);

UNION and UNION ALL are worth knowing too: UNION combines two result sets and removes duplicates; UNION ALL combines them and keeps everything, which is also faster, since Postgres skips the duplicate-removal pass.

12.15 CTEs — the WITH clause Must Know

In plain English

A CTE (Common Table Expression) is a named, temporary result set you define at the top of a query with WITH name AS (...), then use later in that same query exactly like a real table. It exists purely to make a complicated query readable — break it into named, logical steps instead of nesting nine subqueries inside each other.

WITH denied_claims AS (
  SELECT claim_id, payer_id, billed_amount
  FROM claims
  WHERE claim_status = 'Denied'
)
SELECT payer_id, COUNT(*) AS denied_count, SUM(billed_amount) AS denied_value
FROM denied_claims
GROUP BY payer_id
ORDER BY denied_value DESC;

12.16 Multiple / chained CTEs Should Know

WITH payer_totals AS (
  SELECT payer_id, SUM(billed_amount) AS total_billed
  FROM claims
  GROUP BY payer_id
),
payer_paid AS (
  SELECT c.payer_id, SUM(cp.paid_amount) AS total_paid
  FROM claims c
  JOIN claim_payments cp ON c.claim_id = cp.claim_id
  GROUP BY c.payer_id
)
SELECT
  pt.payer_id,
  pt.total_billed,
  COALESCE(pp.total_paid, 0) AS total_paid,
  pt.total_billed - COALESCE(pp.total_paid, 0) AS outstanding
FROM payer_totals pt
LEFT JOIN payer_paid pp ON pt.payer_id = pp.payer_id
ORDER BY outstanding DESC;

This is a realistic shape for a real RCM report: each CTE computes one clean, named intermediate answer ("total billed per payer," "total paid per payer"), and the final SELECT just combines them. Chaining CTEs like this — instead of one giant nested query — is exactly how a readable analyst query is structured, and it's a strong habit to demonstrate in a take-home or live SQL screen.

12.17 Recursive CTEs — the basics Should Know

In plain English

A recursive CTE is a query that refers to itself, so it can walk through data that has a "repeat this logic on the result of the last step" shape — a chain of dates, an org chart, a category that contains sub-categories. You almost certainly won't be asked to write one from memory at entry level, but recognizing the shape and being able to read one is a real differentiator.

-- generate a series of dates (useful for building a complete aging report
-- that doesn't silently skip days with zero claims)
WITH RECURSIVE date_series AS (
  SELECT DATE '2026-01-01' AS d
  UNION ALL
  SELECT d + 1 FROM date_series WHERE d + 1 <= DATE '2026-01-31'
)
SELECT d FROM date_series;

-- (in real Postgres work you'd usually reach for generate_series() instead --
--  generate_series(DATE '2026-01-01', DATE '2026-01-31', INTERVAL '1 day') --
--  but understanding the recursive-CTE version is what explains WHY that
--  built-in function exists and what it's doing under the hood)

Structurally every recursive CTE has the same two halves: an anchor (the starting row(s), before UNION ALL) and a recursive term (the part after UNION ALL that refers back to the CTE's own name) that keeps running until it produces no more new rows.

12.18 Window functions — the concept Must Master

In plain English

GROUP BY collapses many rows into one row per group — you lose the individual rows. A window function calculates something across a group of related rows (a "window") but keeps every original row visible. That's the entire idea: aggregate-like power, without collapsing the detail.

-- every window function follows this shape:
--   FUNCTION() OVER (PARTITION BY ... ORDER BY ...)
-- PARTITION BY = "reset/group by this" (like GROUP BY, but doesn't collapse rows)
-- ORDER BY inside OVER() = the order the window function should process rows in

SELECT
  claim_id, payer_id, billed_amount,
  AVG(billed_amount) OVER (PARTITION BY payer_id) AS payer_avg_amount
FROM claims;
-- every claim row still shows individually, but now also shows its payer's average
-- alongside it -- impossible with plain GROUP BY without a self-join
This is the single highest-leverage new topic in this section

Window functions are what separates "can write basic reporting SQL" from "can write real analyst SQL." RCM-style questions like "rank each patient's claims by amount," "show each claim next to the payer's running total," or "find the days between a claim and that same patient's previous claim" are all window-function questions. Expect them in a Commure/Augmedix-style screen.

12.19 ROW_NUMBER, RANK, DENSE_RANK Must Master

SELECT
  claim_id, payer_id, billed_amount,
  ROW_NUMBER() OVER (PARTITION BY payer_id ORDER BY billed_amount DESC) AS rn,
  RANK()       OVER (PARTITION BY payer_id ORDER BY billed_amount DESC) AS rnk,
  DENSE_RANK() OVER (PARTITION BY payer_id ORDER BY billed_amount DESC) AS drnk
FROM claims;

-- classic use: the single highest-billed claim per payer
WITH ranked AS (
  SELECT claim_id, payer_id, billed_amount,
    ROW_NUMBER() OVER (PARTITION BY payer_id ORDER BY billed_amount DESC) AS rn
  FROM claims
)
SELECT * FROM ranked WHERE rn = 1;
FunctionTies (same value)Gaps after a tie
ROW_NUMBER()Breaks ties arbitrarily — always gives 1,2,3,4...No gaps, ever
RANK()Tied rows get the same rankSkips the next rank(s) — e.g. 1,2,2,4
DENSE_RANK()Tied rows get the same rankNo gap — e.g. 1,2,2,3
Interview trap

"What's the difference between RANK and DENSE_RANK" is asked constantly precisely because the table above is easy to memorize but easy to blank on live. The trick to never forgetting it: RANK "leaves a gap the size of the tie," DENSE_RANK never leaves gaps. ROW_NUMBER never even looks at ties — it just numbers 1..n regardless.

12.20 LAG / LEAD Must Know

-- for each claim, show the previous claim's submitted_date for that same patient
SELECT
  claim_id, patient_id, submitted_date,
  LAG(submitted_date) OVER (PARTITION BY patient_id ORDER BY submitted_date) AS prev_submitted_date,
  submitted_date - LAG(submitted_date) OVER (PARTITION BY patient_id ORDER BY submitted_date) AS days_since_last_claim
FROM claims;

-- LEAD works identically but looks FORWARD instead of backward
SELECT
  claim_id, patient_id, submitted_date,
  LEAD(submitted_date) OVER (PARTITION BY patient_id ORDER BY submitted_date) AS next_submitted_date
FROM claims;
In plain English

LAG = "what was the value in the previous row (within this patient's group)?" LEAD = "what's the value in the next row?" It's how you compare a row to its neighbor without a self-join — genuinely one of the most useful patterns for anything involving a sequence of events over time, which is most of what RCM data is.

12.21 Running totals & moving aggregates Should Know

-- running (cumulative) total of payments received, ordered by date
SELECT
  payment_date, paid_amount,
  SUM(paid_amount) OVER (ORDER BY payment_date) AS running_total
FROM claim_payments
ORDER BY payment_date;

-- 7-row moving average (frame clause -- advanced but good to recognize)
SELECT
  payment_date, paid_amount,
  AVG(paid_amount) OVER (
    ORDER BY payment_date
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) AS moving_avg_7
FROM claim_payments
ORDER BY payment_date;

This is exactly the query shape behind "collections trend over time" or "revenue running total" charts — a dashboard's line chart is almost always a window function like this, one row per data point, running underneath it.

12.22 Date & time analysis Must Master

-- date arithmetic
SELECT claim_id, submitted_date, submitted_date + 30 AS due_in_30_days FROM claims;

-- difference between two dates (Postgres returns an integer number of days)
SELECT claim_id, service_date, submitted_date, submitted_date - service_date AS days_to_submit
FROM claims;

-- EXTRACT -- pull out a part of a date
SELECT claim_id, EXTRACT(YEAR FROM submitted_date) AS yr, EXTRACT(MONTH FROM submitted_date) AS mo
FROM claims;

-- DATE_TRUNC -- round a date DOWN to a unit -- the standard way to group by month/week
SELECT DATE_TRUNC('month', submitted_date) AS claim_month, COUNT(*) AS claim_count, SUM(billed_amount) AS total_billed
FROM claims
GROUP BY DATE_TRUNC('month', submitted_date)
ORDER BY claim_month;

-- the single most important RCM date query: days-to-payment, and aging buckets
SELECT
  c.claim_id,
  c.submitted_date,
  cp.payment_date,
  cp.payment_date - c.submitted_date AS days_to_payment,
  CASE
    WHEN cp.payment_id IS NULL AND CURRENT_DATE - c.submitted_date <= 30 THEN '0-30 days'
    WHEN cp.payment_id IS NULL AND CURRENT_DATE - c.submitted_date <= 60 THEN '31-60 days'
    WHEN cp.payment_id IS NULL AND CURRENT_DATE - c.submitted_date <= 90 THEN '61-90 days'
    WHEN cp.payment_id IS NULL THEN '90+ days'
    ELSE 'Paid'
  END AS aging_bucket
FROM claims c
LEFT JOIN claim_payments cp ON c.claim_id = cp.claim_id;
Why aging buckets matter so much in RCM

"Accounts Receivable aging" (how long unpaid claims have been sitting, bucketed into ranges like 0-30/31-60/61-90/90+ days) is one of the single most common reports in any RCM role, because the older an unpaid claim gets, the less likely it is to ever be collected. Being able to build this query from scratch — CASE + date arithmetic + a LEFT JOIN for "unpaid" — is close to a guaranteed interview or take-home question for this exact role.

12.23 String manipulation Must Know

SELECT UPPER(payer_name), LOWER(payer_name) FROM payers;

-- concatenation
SELECT full_name || ' (' || patient_id || ')' AS patient_label FROM patients;
SELECT CONCAT(full_name, ' (', patient_id, ')') AS patient_label FROM patients;

-- substring / trimming / length
SELECT SUBSTRING(denial_code FROM 1 FOR 2) AS code_prefix FROM denials;  -- e.g. 'CO' from 'CO-16'
SELECT TRIM(payer_name) FROM payers;              -- strips leading/trailing whitespace
SELECT LENGTH(denial_reason) FROM denials;

-- REPLACE -- fixing/normalizing messy text data (very common in data cleaning)
SELECT REPLACE(payer_name, 'Ins.', 'Insurance') FROM payers;

-- pattern-based extraction with regex (Postgres)
SELECT denial_code FROM denials WHERE denial_code ~ '^CO-';   -- ~ = regex match

12.24 NULL handling, deeper Must Know

-- COALESCE -- return the first non-NULL value in a list; the standard way
-- to supply a default instead of a NULL
SELECT claim_id, COALESCE(cp.paid_amount, 0) AS paid_amount
FROM claims c
LEFT JOIN claim_payments cp ON c.claim_id = cp.claim_id;

-- NULLIF -- return NULL if two values are equal (useful to avoid divide-by-zero)
SELECT payer_id, total_billed / NULLIF(claim_count, 0) AS avg_claim_value
FROM (SELECT payer_id, SUM(billed_amount) AS total_billed, COUNT(*) AS claim_count FROM claims GROUP BY payer_id) t;

-- IS DISTINCT FROM -- a NULL-safe equality check (treats NULL = NULL as true)
SELECT * FROM claims WHERE claim_status IS DISTINCT FROM 'Paid';
In plain English

COALESCE(x, 0) means "use x, but if x is missing, use 0 instead." It's the single most-used NULL-handling function in real reporting SQL, because unmatched LEFT JOINs produce NULLs constantly (12.10) and you almost always want a clean default (0, 'Unknown', etc.) instead of a blank in your final report.

12.25 Duplicate detection, data cleaning & data validation Must Master

-- duplicate detection pattern -- memorize this, asked constantly
SELECT patient_id, service_date, provider_id, COUNT(*) AS cnt
FROM claims
GROUP BY patient_id, service_date, provider_id
HAVING COUNT(*) > 1;
-- reads as: "same patient, same day, same provider, more than once" --
-- a strong signal of an accidental duplicate claim submission

-- data validation: are billed_amount values ever impossible (negative, zero, absurd)?
SELECT * FROM claims WHERE billed_amount <= 0 OR billed_amount > 100000;

-- data validation: does every claim reference a patient/provider/payer that actually exists?
-- (referential-integrity check -- should return zero rows in a healthy database)
SELECT c.claim_id FROM claims c
LEFT JOIN patients p ON c.patient_id = p.patient_id
WHERE p.patient_id IS NULL;

-- data cleaning: normalize inconsistent status text before analysis
SELECT claim_id, INITCAP(TRIM(claim_status)) AS clean_status FROM claims;

12.26 Reconciliation queries Must Master

In plain English

Reconciliation just means "do two numbers that are supposed to match, actually match?" In RCM: does the sum of what was billed equal the sum of what was recorded as paid plus what's still outstanding? If not, money is unaccounted for — and finding exactly which claims caused the mismatch is the actual job.

-- does billed_amount reconcile against the sum of its payments?
SELECT
  c.claim_id,
  c.billed_amount,
  COALESCE(SUM(cp.paid_amount), 0) AS total_paid,
  c.billed_amount - COALESCE(SUM(cp.paid_amount), 0) AS variance
FROM claims c
LEFT JOIN claim_payments cp ON c.claim_id = cp.claim_id
GROUP BY c.claim_id, c.billed_amount
HAVING c.billed_amount - COALESCE(SUM(cp.paid_amount), 0) <> 0;

-- find "orphaned" payments -- a payment referencing a claim_id that
-- doesn't exist in claims at all (a real, damaging data-integrity bug)
SELECT cp.* FROM claim_payments cp
LEFT JOIN claims c ON cp.claim_id = c.claim_id
WHERE c.claim_id IS NULL;

-- claims marked 'Paid' that actually have NO payment row -- a status/data mismatch
SELECT c.claim_id FROM claims c
LEFT JOIN claim_payments cp ON c.claim_id = cp.claim_id
WHERE c.claim_status = 'Paid' AND cp.payment_id IS NULL;

12.27 Finding anomalies Should Know

-- claims billed far above the norm for their payer (simple outlier check)
WITH payer_stats AS (
  SELECT payer_id, AVG(billed_amount) AS avg_amt, STDDEV(billed_amount) AS stddev_amt
  FROM claims
  GROUP BY payer_id
)
SELECT c.claim_id, c.payer_id, c.billed_amount, ps.avg_amt
FROM claims c
JOIN payer_stats ps ON c.payer_id = ps.payer_id
WHERE c.billed_amount > ps.avg_amt + 3 * ps.stddev_amt;   -- more than 3 standard deviations out

-- a payer whose denial rate suddenly looks wrong this month vs. last month
-- (this is exactly a LAG comparison -- 12.20 -- applied to a monthly aggregate)
WITH monthly_denials AS (
  SELECT payer_id, DATE_TRUNC('month', denial_date) AS mo, COUNT(*) AS denied_count
  FROM denials d JOIN claims c ON d.claim_id = c.claim_id
  GROUP BY payer_id, DATE_TRUNC('month', denial_date)
)
SELECT payer_id, mo, denied_count,
  LAG(denied_count) OVER (PARTITION BY payer_id ORDER BY mo) AS prev_month_count
FROM monthly_denials;

You don't need to be a statistician for this role. "More than N standard deviations from the mean" and "compare this period to the previous period with LAG" cover the large majority of anomaly-detection questions an entry-level RCM analyst is realistically asked to build.

12.28 Complex business logic — putting it all together Must Master

A real analyst deliverable rarely uses just one technique — it chains several. Here's a full "denial rate and revenue impact by payer" report, combining a CTE, conditional aggregation, and a window function in one query:

WITH claim_summary AS (
  SELECT
    c.payer_id,
    py.payer_name,
    COUNT(*) AS total_claims,
    COUNT(CASE WHEN c.claim_status = 'Denied' THEN 1 END) AS denied_claims,
    SUM(CASE WHEN c.claim_status = 'Denied' THEN c.billed_amount ELSE 0 END) AS denied_revenue,
    SUM(c.billed_amount) AS total_billed
  FROM claims c
  JOIN payers py ON c.payer_id = py.payer_id
  GROUP BY c.payer_id, py.payer_name
)
SELECT
  payer_name,
  total_claims,
  denied_claims,
  ROUND(100.0 * denied_claims / NULLIF(total_claims, 0), 1) AS denial_rate_pct,
  denied_revenue,
  RANK() OVER (ORDER BY denied_revenue DESC) AS revenue_impact_rank
FROM claim_summary
ORDER BY revenue_impact_rank;

Notice the shape: a CTE builds one clean per-payer summary; the outer query turns that into percentages and a rank. This "CTE that summarizes, then an outer query that presents" pattern is worth internalizing — it's how the overwhelming majority of real analyst SQL is actually structured, and it's a strong signal to write it this way (instead of one giant nested query) in any live SQL exercise.

12.29 Indexes Should Know

In plain English

An index is like the index at the back of a textbook — instead of reading every page to find a topic, you jump straight to the right page. Without an index on a column, the database has to scan every single row to find matches on that column; with one, it can jump almost straight there.

CREATE INDEX idx_claims_patient_id ON claims(patient_id);
CREATE INDEX idx_claims_payer_status ON claims(payer_id, claim_status);  -- composite index
Good candidate for an indexUsually not worth indexing
Columns used constantly in WHERE/JOIN (e.g. patient_id, foreign keys)Columns almost never filtered/joined on
Columns used in ORDER BY on large result setsSmall tables (a full scan is already fast)
High-cardinality columns (many distinct values)Low-cardinality columns (e.g. a boolean flag) — an index barely helps

The tradeoff: indexes speed up reads but slow down writes slightly (every INSERT/UPDATE also has to update the index), and they take disk space. As an analyst you'll rarely be the one deciding what to index, but you're expected to recognize why a query is slow and be able to say "this needs an index on X" when asked.

12.30 EXPLAIN & reading query plans Should Know

EXPLAIN ANALYZE
SELECT c.claim_id, p.full_name
FROM claims c
JOIN patients p ON c.patient_id = p.patient_id
WHERE c.claim_status = 'Denied';
What to actually look for

You don't need to master every line of a query plan. Look for: Seq Scan (sequential scan — reading every row; fine on a small table, a red flag on a huge one if there's a WHERE/JOIN column that could be indexed instead) vs. Index Scan (using an index — the thing you generally want on large tables); the estimated vs. actual row counts (a huge mismatch means the database's statistics are stale, which can cause it to pick a bad plan); and the total execution time at the bottom. Being able to say "I ran EXPLAIN ANALYZE and saw a sequential scan on a 2-million-row table, which is why this took 8 seconds" is exactly the kind of answer that separates a candidate who's only ever written correct SQL from one who's also written fast SQL.

12.31 N+1 thinking & writing efficient queries against large datasets Should Know

In plain English

The "N+1 problem" is running one query to get a list, then a separate query per row of that list to get related data — 1 query becomes 1 + N queries. It's usually an application/ORM mistake (fetch 500 claims, then loop and run a separate "get payments for this claim" query 500 times) rather than something you'd write by hand in raw SQL, but recognizing it is valuable because the fix is almost always "do it in one JOIN or one window function instead" — exactly the tools from this whole section.

  • Select only the columns you need — avoid SELECT * in real reporting queries; it pulls unnecessary data across the network and can prevent certain index-only optimizations.
  • Avoid wrapping an indexed column in a function inside WHERE — WHERE DATE(submitted_date) = '2026-01-01' can prevent the database from using an index on submitted_date; WHERE submitted_date >= '2026-01-01' AND submitted_date < '2026-01-02' usually can.
  • Filter as early as possible — apply WHERE conditions before joining large tables together where the logic allows it, so the database has less data to join.
  • Prefer EXISTS over IN with a large subquery — EXISTS can stop at the first match (12.14); a large IN list has to be fully materialized first.
  • Use LIMIT while developing a query against a huge table, so you're not waiting on a full result set every time you tweak a WHERE clause.

12.32 Database testing for QA Must Master

ConceptWhat you actually check
CRUD validationDoes Create/Read/Update/Delete via the UI/API correctly reflect in the DB?
Data validationAre the values stored correct, correctly typed, correctly formatted?
Referential integrityAre foreign keys always valid — no orphaned records? (12.25/12.26)
Data consistencyDoes related data agree everywhere (e.g. "total claims" shown in a UI matches actual COUNT in DB)?
Migration validationAfter a data/schema migration, does row count and sampled data match pre-migration?
Duplicate detectionThe GROUP BY ... HAVING COUNT(*) > 1 pattern (12.25)
NULL validationAre required fields actually enforced as NOT NULL, or can bad data sneak in?

Notice that every row of this table is a direct application of a technique already taught above — database testing for QA isn't a separate skill from RCM analyst SQL, it's a subset use-case of the exact same queries.


12.33 Practice Problems — 55 problems, scratch → interview-level

In plain English

Problems 1-20 use the generic users/orders schema (12.2). Problems 21-55 use the RCM schema (patients, providers, payers, claims, claim_payments, denials) — set that schema up for real and run these against it; that combination is the closest realistic simulation of an actual Commure/Augmedix take-home you can give yourself.

Foundations (1–20)

  1. Select all columns from users.
  2. Select only name and email from users.
  3. Select all users from 'Bangladesh'.
  4. Select all orders with amount greater than 1000.
  5. Select all distinct status values from orders.
  6. Select all users ordered by created_at ascending.
  7. Select the 3 most recent orders.
  8. Select all users whose email contains 'gmail'.
  9. Select all orders with status 'Pending' or 'Processing'.
  10. Select all users where country is NULL.
  11. Count the total number of users, and separately, the total amount of all orders.
  12. Find the minimum and maximum order amount.
  13. Count the number of orders per user.
  14. Find users who have placed more than 3 orders.
  15. Find the total amount spent per user, only showing users who spent over ৳5000.
  16. List each user's name along with their order count, including users with zero orders.
  17. Find all users who have never placed an order.
  18. Add a label column showing 'High Value' if an order amount > 5000, else 'Standard', using CASE.
  19. Find duplicate emails in the users table, if any.
  20. Find the top 3 users by total amount spent.

Joins, subqueries, CTEs — RCM schema (21–35)

  1. List every claim with its patient name, provider name, and payer name in one row.
  2. Find all claims that have never received a payment.
  3. Find all patients who have never had a claim.
  4. Find the total billed amount and claim count per payer.
  5. Find the total billed amount per payer, only for payers with more than 15 claims.
  6. Using conditional aggregation, produce one row per payer showing counts of Paid, Denied, and Pending claims side by side.
  7. Find pairs of claims for the same patient submitted on the same day (self join).
  8. Using a subquery, find all patients whose total billed amount is above the overall average total billed per patient.
  9. Using a correlated subquery, find all claims billed above the average for their own payer.
  10. Rewrite the previous answer using EXISTS instead of a subquery in WHERE, where possible, and explain in one sentence why EXISTS might be more efficient.
  11. Using a CTE, compute total billed and total paid per payer, then a final column for outstanding balance.
  12. Using two chained CTEs, build a report showing each payer's denial rate as a percentage.
  13. Write a query that would prove referential integrity: claims referencing a patient_id that doesn't exist in patients (should return zero rows in a healthy DB).
  14. Find claim_payments that reference a claim_id that doesn't exist in claims (orphaned payments).
  15. Find claims marked 'Paid' that have no matching row in claim_payments at all (a status/data mismatch).

Window functions & date/time — RCM schema (36–48)

  1. For each claim, show its rank by billed_amount within its own payer, using RANK().
  2. Find the single highest-billed claim per payer, using ROW_NUMBER() and filtering to rn = 1.
  3. Explain, without running anything, what would differ in the output if you used DENSE_RANK() instead of RANK() in problem 36, given two tied claims.
  4. For each patient, show the number of days between their current claim and their previous claim, using LAG.
  5. Compute a running total of paid_amount from claim_payments, ordered by payment_date.
  6. Compute each claim's days_to_submit (submitted_date minus service_date).
  7. Group claims by month (DATE_TRUNC) and show total billed amount per month.
  8. Build a full aging-bucket report (0-30 / 31-60 / 61-90 / 90+ / Paid) for all claims, as shown in 12.22.
  9. Find the payer with the slowest average days_to_payment (submitted_date to payment_date).
  10. Using LAG on a monthly aggregate, find any payer whose denied-claim count increased month over month.
  11. Find claims billed more than 3 standard deviations above their payer's average (12.27's outlier pattern).
  12. Find the 3 most common denial_code values overall, with counts.
  13. For each payer, find their most recent claim's submitted_date only (not the whole row) using a window function instead of GROUP BY/MAX.

Full analyst-style problems (49–55)

  1. Build the complete "denial rate and revenue impact by payer" report from 12.28 from scratch, without looking, then check your answer against it.
  2. A stakeholder asks: "which payer is costing us the most in denied revenue this quarter?" Write the full query, including filtering to the current quarter.
  3. A stakeholder asks: "are claims getting paid faster or slower this year compared to last year?" Write a query comparing average days_to_payment year over year.
  4. You suspect a data-entry bug caused some claims to have a submitted_date earlier than their service_date (impossible in reality). Write a query to find and count them.
  5. Write a full reconciliation query: for every claim, show billed_amount, total paid, and variance, and filter to only claims where they don't match (12.26).
  6. Combine everything: for each provider, show total claims, denial rate, and their rank among all providers by denial rate — using a CTE, conditional aggregation, and RANK() together.
  7. Explain, in a few sentences as if to an interviewer, how you would use EXPLAIN ANALYZE to investigate why problem 54's query is slow on a 5-million-row claims table, and what you'd look for in the output.

Interview questions — Part 12

  1. What's the difference between WHERE and HAVING?
  2. Explain INNER JOIN vs LEFT JOIN with a real example, and when you'd choose one over the other.
  3. What's the difference between a regular subquery and a correlated subquery?
  4. What's a CTE, and why would you use one instead of a subquery?
  5. Explain the difference between ROW_NUMBER, RANK, and DENSE_RANK.
  6. What does PARTITION BY do, and how is it different from GROUP BY?
  7. How would you find duplicate records in a table?
  8. Walk me through how you'd build an Accounts Receivable aging report from a claims and payments table.
  9. What's the difference between COALESCE and NULLIF, and give a real use case for each.
  10. What is an index, and how would you decide whether a column is worth indexing?
  11. What would you look for in an EXPLAIN ANALYZE output if a query was running slowly?
  12. Why should you run a SELECT with the same WHERE clause before running a destructive UPDATE/DELETE?
  13. How would you reconcile billed amounts against payments to find claims where the numbers don't match?

Resources

  • SQLZoo — Essential. Interactive, free, right difficulty curve for 12.3–12.14. Do the SELECT basics, JOIN, subquery, and aggregate modules.
  • Mode SQL Tutorial — Optional. Good prose explanations, including a solid window functions chapter.
  • PostgreSQL Tutorial — Window Functions — Recommended for 12.18–12.21. The clearest free walkthrough of PARTITION BY/ROW_NUMBER/RANK/LAG specifically.
  • StrataScratch or LeetCode (Database) — Optional, once 12.3–12.28 feel solid. Realistic analyst-style SQL interview questions, several genuinely RCM/healthcare-data-adjacent.
  • PostgreSQL docs — Using EXPLAIN — Reference for 12.30. Not for start-to-finish reading, but the right place to look up a specific plan-node type you don't recognize.
  • PostgreSQL official docs — Optional/reference. Also the same documentation you'll use in the Django phase later, since Django commonly pairs with PostgreSQL.

API Testing

Must Master
Estimated time: 8 hours

This is a genuine differentiator in BD junior QA hiring — many candidates only know manual UI testing; API testing skill puts you ahead.

15.1 Why test the API directly instead of only the UI

APIs are faster to test (no UI rendering), more stable (UI changes don't break your tests), and let you test backend logic and edge cases the UI might not even expose (e.g., sending malformed data the UI form would normally prevent you from typing). API testing is also how you verify the backend is correct independent of whether the frontend correctly displays it — isolating where a bug actually lives.

15.2 REST fundamentals (recap + depth)

REST APIs organize functionality around resources (nouns, e.g. /users, /orders) and use HTTP methods (verbs) to say what to do:

Method Purpose Idempotent? Example
GET Retrieve data Yes GET /users/5
POST Create new data No POST /users
PUT Replace an entire resource Yes PUT /users/5
PATCH Partially update a resource No (generally) PATCH /users/5
DELETE Remove a resource Yes DELETE /users/5

Idempotent means calling it multiple times has the same effect as calling it once (GET-ing the same resource repeatedly doesn't change anything; PUT-ing the exact same full replacement repeatedly leaves the same end state). POST is NOT idempotent — calling it twice typically creates two resources. This idempotency distinction is a real interview question at API-testing-aware companies.

15.3 Request anatomy

Part Purpose Example
Headers Metadata about the request Content-Type: application/json, Authorization: Bearer <token>
Query parameters Key-value pairs in the URL, usually for filtering/pagination GET /orders?status=pending&page=2
Path parameters Part of the URL path identifying a specific resource GET /orders/{id} → /orders/42
Request body The actual data being sent (POST/PUT/PATCH) {"name": "Rafi", "email": "rafi@x.com"}

15.4 What "response validation" actually means

A full API test checks, at minimum:

  1. Status code — is it the correct one for this scenario?
  2. Response body structure — correct fields present, correct data types (schema validation).
  3. Response body values — correct actual data.
  4. Response headers — e.g., Content-Type: application/json present and correct.
  5. Response time — reasonable (basic performance awareness, not full load testing).

15.5 Positive, negative, and boundary API testing Must Master

Example endpoint

POST /api/users — creates a user, requires name (string, 2-50 chars) and email (valid format, unique).

Test Type Expected
Valid name + valid unique email Positive 201 Created, response body has new user with correct id
Missing name field Negative 400 Bad Request, error message identifies the missing field
email already exists Negative 409 Conflict (or 400, depending on API design — this is exactly the kind of thing you verify against the actual spec, not assume)
Invalid email format ("notanemail") Negative 400 Bad Request
name exactly 2 characters Boundary 201 Created (min boundary, valid)
name 1 character Boundary 400 Bad Request (just below min)
name exactly 50 characters Boundary 201 Created (max boundary, valid)
name 51 characters Boundary 400 Bad Request (just above max)
No Authorization header (if auth required) Security 401 Unauthorized
Extremely large request body (e.g., 10MB payload) Negative/stress Should reject gracefully, not crash the server
SQL-injection-style string in name (' OR '1'='1) Security Should be safely stored/rejected as a literal string, never executed as SQL

Notice: this is literally the EP/BVA techniques from Part 7 applied directly to an API instead of a UI field — same thinking, different surface.

15.6 Authentication in APIs Must Know

Most real APIs require auth on protected endpoints — commonly a Bearer token in the Authorization header (Authorization: Bearer <token>), obtained via a login/token endpoint first. Test both: valid token works, and — importantly — an expired/invalid/missing token is correctly rejected (401), and a valid token for User A cannot access User B's private data (403 or 404 depending on design — this is an authorization check, not authentication, and it's one of the most commonly missed real-world bug classes).

Interview questions — Part 15

  1. What's the difference between PUT and PATCH?
  2. What does "idempotent" mean, and which HTTP methods are idempotent?
  3. Design 5 negative test cases for a POST /login endpoint.
  4. What's the difference between testing that a token is valid vs. testing that it's authorized for a specific resource?

Postman

Must Master
Estimated time: 6 hours

16.1 Core concepts

Concept Purpose
Request A single API call configuration (method, URL, headers, body)
Collection A folder of related requests
Environment A named set of variables (e.g., "Staging" vs "Production") with different values
Variable A placeholder like {{base_url}} reused across requests
Tests tab JavaScript assertions run after the response arrives
Collection Runner Runs an entire collection's requests in sequence, useful for a quick regression pass

16.2 Writing assertions (Tests tab)

// Status code check
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

// Response body field check
pm.test("Response has correct user id", function () {
    const jsonData = pm.response.json();
    pm.expect(jsonData.id).to.eql(5);
});

// Response time check (basic performance awareness)
pm.test("Response time is under 1000ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(1000);
});

// Save a value from this response for use in a LATER request (chaining)
pm.test("Save auth token", function () {
    const jsonData = pm.response.json();
    pm.environment.set("auth_token", jsonData.token);
});

16.3 Chaining requests

A login request saves auth_token into an environment variable (as above); the next request (e.g., "Get My Orders") uses {{auth_token}} in its Authorization header. This models real user flows and is a core Postman skill.

16.4 Mini-project: build a real API test collection

Using a free public test API — e.g., ReqRes or JSONPlaceholder — build a Postman collection that:

  1. Has a folder of positive tests: GET a list, GET a single resource, POST a new resource, PUT/PATCH update, DELETE.
  2. Has a folder of negative tests: GET a non-existent ID (expect 404), POST with missing required fields, invalid data types.
  3. Uses an environment with a {{base_url}} variable.
  4. Has at least one chained request (if the API supports auth — ReqRes has a login endpoint good for this).
  5. Has assertions on every request (status code minimum; body checks where relevant).
  6. Is run successfully via the Collection Runner, producing a pass/fail summary.
  7. Is exported (as a .json collection file) — this becomes part of your Portfolio Project 2 in Part 23.

Interview questions — Part 16

  1. What's the difference between a Postman Environment and a Collection?
  2. How would you chain a login request's token into a subsequent authenticated request?
  3. Write a Postman test assertion that checks a response array is not empty.
  4. Why is the Collection Runner useful for quick regression testing?

Resources

Python for QA (and Future Backend Dev)

Must Master
Estimated time: 16 hours

This section is written slightly deeper than a pure-QA course would go, deliberately — this is the same foundation Django needs. Every extra hour here is time you won't have to re-spend in your Django phase.

17.1 Why Python specifically

Python is the most common scripting/automation language in BD QA job postings (alongside Java), reads close to plain English, and — not incidentally — is also what Django is written in. Learning it once, well, serves both purposes.

17.2 Variables & data types Must Master

name = "Shahed"          # str
age = 26                  # int
price = 199.99            # float
is_active = True          # bool
nothing = None             # NoneType

17.3 Strings Must Master

s = "Hello, QA World"
print(s.lower())          # hello, qa world
print(s.upper())          # HELLO, QA WORLD
print(s.strip())          # remove leading/trailing whitespace
print(s.replace("QA", "Testing"))
print(s.split(","))       # ['Hello', ' QA World']
print(len(s))              # 16
print(s[0:5])               # 'Hello' (slicing)
print(f"Name: {name}, Age: {age}")   # f-strings — use these, not old-style formatting

17.4 Lists, Tuples, Sets, Dictionaries Must Master

# List — ordered, mutable
fruits = ["apple", "banana", "cherry"]
fruits.append("date")
fruits.remove("banana")
print(fruits[0])           # 'apple'
print(len(fruits))

# Tuple — ordered, immutable
point = (10, 20)

# Set — unordered, unique values (great for "find duplicates" style logic)
unique_ids = {1, 2, 2, 3}    # {1, 2, 3}

# Dictionary — key-value pairs (this is what JSON becomes in Python)
user = {"name": "Shahed", "age": 26, "roles": ["tester"]}
print(user["name"])
user["email"] = "shahed@example.com"     # add a key
print(user.get("phone", "N/A"))           # safe access with default

17.5 Conditions & loops Must Master

score = 72
if score >= 90:
    grade = "A"
elif score >= 70:
    grade = "B"
else:
    grade = "C"

for fruit in fruits:
    print(fruit)

for i in range(5):          # 0,1,2,3,4
    print(i)

count = 0
while count < 3:
    print(count)
    count += 1

17.6 Functions Must Master

def calculate_discount(price, percent):
    """Returns the discounted price."""
    if percent < 0 or percent > 100:
        raise ValueError("Percent must be between 0 and 100")
    return price - (price * percent / 100)

print(calculate_discount(1000, 10))   # 900.0

17.7 Exceptions Must Know

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error occurred: {e}")
finally:
    print("This always runs")

Exception handling matters directly for QA: your test scripts need to handle unexpected API failures/timeouts gracefully instead of crashing the whole test run.

17.8 File handling & JSON Must Know

# Writing/reading a text file
with open("results.txt", "w") as f:
    f.write("Test run passed: 45/50\n")

with open("results.txt", "r") as f:
    print(f.read())

# JSON — critical for API testing scripts
import json

data = {"id": 5, "name": "Shahed", "active": True}
json_string = json.dumps(data)          # Python dict -> JSON string
parsed_back = json.loads(json_string)    # JSON string -> Python dict
print(parsed_back["name"])

17.9 OOP basics Must Know

class TestCase:
    def __init__(self, title, priority):
        self.title = title
        self.priority = priority
        self.status = "Not Run"

    def mark_passed(self):
        self.status = "Passed"

    def __str__(self):
        return f"{self.title} [{self.priority}] - {self.status}"

tc = TestCase("Verify login with valid credentials", "High")
tc.mark_passed()
print(tc)   # Verify login with valid credentials [High] - Passed


class SmokeTestCase(TestCase):        # inheritance
    def __init__(self, title):
        super().__init__(title, priority="Critical")

stc = SmokeTestCase("App loads successfully")
print(stc)

Why this matters beyond "QA scripting": Django is built entirely around classes (models, views) — this exact class/__init__/inheritance pattern is the syntax you'll be reading constantly in the Django phase. Don't skim this subsection.

17.10 The requests library — hitting real APIs from Python Must Know

import requests

response = requests.get("https://jsonplaceholder.typicode.com/users/1")
print(response.status_code)          # 200
data = response.json()
print(data["name"])

# POST with a body
payload = {"title": "test post", "body": "hello", "userId": 1}
response = requests.post("https://jsonplaceholder.typicode.com/posts", json=payload)
print(response.status_code)          # 201

This is the foundation of writing automated API tests in Python (an alternative/complement to Postman) — a genuinely valuable skill to show in your Portfolio Project 2 (Part 23).

Coding exercises — Part 17

  1. Write a function is_valid_email(email) that does basic validation (contains exactly one @, has characters before and after it).
  2. Write a function that takes a list of test results (["Pass", "Fail", "Pass", "Pass", "Fail"]) and returns a dict {"pass": 3, "fail": 2}.
  3. Write a script using requests that GETs https://jsonplaceholder.typicode.com/users and prints the names of all users whose id is even.
  4. Write a BugReport class with fields title, severity, priority, and a method summary() that returns a formatted one-line string.
  5. Write a function that reads a JSON file of test results and prints how many tests passed vs failed.

Automation Testing: Playwright

Must Know
Estimated time: 18 hours

This module exists because your budget grew from ~125 to 200 hours — automation was cut from the original trimmed guide specifically to save time. With the extra room, hands-on automation is worth doing for real, not just conceptually. It stays 🟠 MUST KNOW, not 🔴 MUST MASTER: most BD entry-level manual/API QA roles still don't require it day one, but walking into an interview with a real, working automation suite on your GitHub is one of the sharpest differentiators available to a fresher.

A.1 Why Playwright, and why only one tool

Two automation tools done shallowly is weaker than one done properly — trying to hand-roll both Selenium and Playwright inside a tight budget was producing surface-level knowledge of each instead of a real, working suite of either. Playwright is the better single choice for this: it auto-waits for elements by default (removing the single biggest source of flaky, hard-to-debug tests), installs its own managed browsers so setup rarely breaks, and ships a built-in trace viewer and codegen recorder that make debugging dramatically easier for someone building their first suite. It's also the direction a growing share of newer BD teams and greenfield projects are adopting, so it reads as current, not dated.

In plain English

Automation doesn't replace manual testing — it replaces the boring, repetitive parts of manual testing (regression) so a human tester has time for the parts that actually need judgment (exploratory, usability). Playwright is just the tool that drives a real browser — clicking, typing, reading the page — the way a script instead of a human.

A.2 How Playwright actually works

Concept

Playwright launches and controls a real browser (Chromium, Firefox, or WebKit) over a fast, persistent connection, and drives it exactly the way a human would — clicking, typing, reading the rendered page. It does not talk to your app's backend directly; it only sees what the browser sees, which is precisely why it's valuable for QA: it tests the same path a real user takes.

from playwright.sync_api import sync_playwright, expect

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com/login")

    page.get_by_label("Email").fill("qa.test@example.com")
    page.get_by_label("Password").fill("Pass1234")
    page.get_by_role("button", name="Login").click()

    # Playwright auto-waits for this element before asserting -- no manual wait needed
    expect(page.get_by_role("heading", name="Dashboard")).to_be_visible()

    browser.close()

A.3 Locators, ranked by how stable they are Must Master

Locator Example Stability
get_by_role page.get_by_role("button", name="Login") Best — mirrors how a real user/screen-reader identifies the element, survives most styling/markup changes
get_by_label page.get_by_label("Email") Excellent for form fields — matches the associated <label>
get_by_test_id page.get_by_test_id("submit-btn") Best when available — a data-testid attribute added specifically for tests, immune to styling/copy changes
get_by_text page.get_by_text("Forgot password?") Good for static, unique visible text
CSS selector page.locator(".btn-primary") Fine as a fallback when nothing above fits; more brittle to styling changes
Interview trap

A candidate who reaches for a raw CSS selector or XPath first, for everything, reads as inexperienced. The correct instinct with Playwright is get_by_role/get_by_label/get_by_test_id first — they're both more stable and more readable — with CSS only as a fallback when nothing semantic is available.

A.4 Auto-waiting — why you almost never write a manual wait

  • Old-style time.sleep(3): never do this. It's either too short (flaky failures) or wastes time (too long on every run, and at scale this compounds into hours of wasted CI time).
  • Playwright's default behavior: every action (.click(), .fill()) and every expect(...) assertion automatically retries until the element is actionable/visible or a timeout is hit. This single behavior removes the majority of "flaky test" bugs that plague junior-written Selenium suites — it's the main practical reason this module teaches only Playwright.
# no manual wait needed anywhere here -- Playwright retries internally
page.get_by_role("button", name="Submit").click()
expect(page.get_by_text("Saved successfully")).to_be_visible()

A.5 Page Object Model (POM) Must Know

Concept

Instead of scattering locators and interactions across every test, encapsulate one page's elements and actions inside a class. When the UI changes, you fix it in exactly one place instead of every test that touches that page.

# pages/login_page.py
class LoginPage:
    def __init__(self, page):
        self.page = page
        self.email = page.get_by_label("Email")
        self.password = page.get_by_label("Password")
        self.submit = page.get_by_role("button", name="Login")

    def login(self, email, password):
        self.page.goto("https://example.com/login")
        self.email.fill(email)
        self.password.fill(password)
        self.submit.click()

# tests/test_login.py
from pages.login_page import LoginPage
from playwright.sync_api import expect

def test_valid_login(page):
    login = LoginPage(page)
    login.login("qa.test@example.com", "Pass1234")
    expect(page.get_by_role("heading", name="Dashboard")).to_be_visible()

def test_invalid_password(page):
    login = LoginPage(page)
    login.login("qa.test@example.com", "WrongPass")
    expect(page.get_by_text("Incorrect email or password")).to_be_visible()

This is the exact shape a real BD test-automation team's repository looks like — small, readable, one page object per screen, one test file per feature.

A.6 A minimal runnable framework structure

qa-automation-suite/
  pages/
    login_page.py
    dashboard_page.py
  tests/
    test_login.py
    test_dashboard.py
  conftest.py          # pytest fixtures -- e.g. a shared `page` fixture
  pytest.ini
  requirements.txt
  README.md

Run with pytest --html=report.html (via the pytest-html plugin) to produce a shareable HTML test report — exactly the kind of artifact worth linking from your portfolio project (see Part 23). Playwright's own trace viewer (playwright show-trace trace.zip) is also worth demonstrating — it replays exactly what the browser did, step by step, which is a genuinely strong thing to show live in an interview.

A.7 Hooking it into CI Should Know

# .github/workflows/tests.yml
name: Run QA Suite
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install -r requirements.txt
      - run: playwright install --with-deps
      - run: pytest --html=report.html

A green checkmark on a GitHub repo, produced by a workflow you configured yourself, is worth far more in an interview than saying "I've read about test automation" — it's proof, not a claim.

A.8 If a job posting specifically asks for Selenium Awareness

Awareness only — not hands-on

Selenium is still what a share of existing BD QA job postings name explicitly (it's the incumbent, and legacy suites at established companies are written in it). You don't need hands-on Selenium experience for this guide's plan, but the underlying concepts transfer almost directly, so you won't be lost if it comes up:

Playwright (what you learned)Selenium equivalent (recognize, don't memorize)
page.goto(url)driver.get(url)
page.get_by_role(...) / page.locator(...)driver.find_element(By.ID, ...) / By.CSS_SELECTOR / By.XPATH
Automatic — built into every action/assertionWebDriverWait(driver, 10).until(EC.<condition>) — you write waits by hand
browser.close()driver.quit()

If a specific application you're applying to explicitly requires hands-on Selenium, treat that as a signal to deep-dive Selenium's syntax for that one application — the POM structure, waiting philosophy, and CI approach you already know from Playwright transfer over almost unchanged; only the exact API calls differ.

A.9 What "having automation experience" honestly means at your level

Calibrate this claim carefully

A junior candidate who says "I'm a Playwright expert" after one small suite gets caught out immediately by a follow-up question. The honest, stronger framing: "I understand manual testing is still the majority of the job, but I've built and can walk you through a small working Playwright automation suite — including POM structure, auto-waiting, and a CI pipeline that runs it on every push." That sentence, backed by a real repo link, outperforms a resume line that just says "Playwright" with nothing behind it.

Interview questions — Part A

  1. Walk me through what actually happens, step by step, when a Playwright script calls .click() on an element.
  2. Why is time.sleep() considered bad practice in automation, and how does Playwright avoid needing it?
  3. What problem does the Page Object Model solve, and what breaks in a test suite that doesn't use it?
  4. Rank get_by_role, get_by_test_id, and a raw CSS selector by how stable they are, and explain why.
  5. You're asked "do you know Selenium?" in an interview, but you only have Playwright experience. How do you answer honestly without either overselling or underselling what you've built?

Exercise (do this — don't skip)

Set up a real Playwright project against any public demo site (e.g. a demo login/e-commerce practice site). Write 3 tests: one happy-path login, one negative-path login (wrong password), and one that verifies a specific piece of text appears after an action. Get all 3 passing locally, then wire up the GitHub Actions workflow above so they run automatically on push. This suite becomes reusable evidence for Part 23's portfolio.

CS Fundamentals: OS & Networking for QA Exams

Must Know
Estimated time: 16 hours

Part 2 already covers client-server architecture, HTTP, and JSON at the depth a working QA needs day-to-day. This module goes one layer deeper — into operating-system and networking fundamentals — specifically because stronger BD written exams (and interviewers at companies that also hire developers) sometimes probe this layer to gauge general CS literacy, not just QA-tool knowledge. Nothing here requires memorizing implementation details; it requires being able to explain the concept cleanly when asked.

B.1 Why a QA engineer needs any of this

You will not implement an operating system or a network stack. You will, regularly: read a stack trace that mentions a "segmentation fault" or "deadlock" and need to know roughly what that means; debug why a test environment behaves differently under load (often a resource/OS-level issue, not an application bug); explain to a developer that a bug reproduces "only over a slow network" (a networking-layer testing concern); and answer a written-exam section that separates candidates who only know QA tools from candidates who understand what's actually running underneath.

B.2 Processes vs. threads Must Master

Process Thread
Definition An independent running program with its own memory space A unit of execution within a process, sharing that process's memory
Isolation Fully isolated from other processes (a crash in one usually doesn't crash another) Threads in the same process share memory — a bug in one can corrupt shared state used by another
Communication Needs explicit inter-process communication (sockets, pipes, shared files) Can directly share variables/data (which is also why threading bugs are harder to find)
Cost Heavier to create/switch between Lighter — cheaper to create, faster to switch between
Classic interview one-liner

a process is an isolated program; a thread is a lightweight worker inside that program, sharing its memory.

B.3 Memory basics Must Know

  • Stack: memory for function calls and local variables — fast, automatically freed when a function returns, limited in size (a runaway recursive function causes a stack overflow, the actual technical meaning behind the website's name).
  • Heap: memory for data that needs to outlive a single function call (objects, dynamically-sized structures) — must be explicitly managed or garbage-collected; a program that keeps allocating heap memory without releasing it has a memory leak, which is exactly why long-running services (and long-running automated test suites!) can slowly consume more and more RAM until they crash or slow to a crawl.
  • Virtual memory: each process believes it has its own full, private address space; the OS maps this onto physical RAM (and disk, via swapping) behind the scenes. This is why one process running out of memory doesn't directly corrupt another process's memory.
In plain English

A memory leak in a long-running test automation suite (Part A) is a real, common failure mode — if your CI suite gets progressively slower over hundreds of runs, memory (not just test logic) is a reasonable first suspect.

B.4 Deadlocks and race conditions Must Know

  • Race condition: the outcome depends on the unpredictable timing/order of two or more operations happening close together — exactly the bug class behind the "two simultaneous transfer requests draining the same account" scenario from Part 8.5's banking example. This is a real, testable QA concern, not just theory: concurrency test cases exist specifically to try to trigger these.
  • Deadlock: two (or more) processes/threads each hold a resource the other needs, and neither can proceed — everything freezes. The textbook analogy: two people trying to pass each other in a narrow hallway, each waiting for the other to move first.

B.5 CPU scheduling and OS basics — awareness level Awareness

The OS scheduler decides which process/thread gets CPU time next, using strategies like round-robin (each process gets a small time slice in turn) or priority-based scheduling. Awareness only at your level: know these terms exist and roughly what they mean if a written test asks a definitional question; you will not be asked to design a scheduler.

B.6 The networking model, simplified for QA use Must Master

Real networking courses teach a 7-layer OSI model. For QA purposes, a simplified 4-layer mental model covers everything you'll actually be asked or need:

flowchart TD
    A["Application layer
HTTP, HTTPS, DNS — what your browser/app speaks"] B["Transport layer
TCP or UDP — how data gets broken up and delivered"] C["Internet layer
IP — how data is addressed and routed between machines"] D["Link layer
Wi-Fi, Ethernet — the physical/local network hop"] A --> B --> C --> D

You already know the Application layer well from Part 2 (HTTP, status codes, JSON). This module fills in the layer just below it.

B.7 TCP vs. UDP Must Master

TCP UDP
Guarantee Reliable — guarantees delivery, in order, retransmits lost packets No guarantee — packets can arrive out of order or be dropped entirely
Speed/overhead Slower, more overhead (handshakes, acknowledgments) Faster, minimal overhead
Used for Web pages (HTTP/HTTPS), file transfer, anything where correctness matters more than speed Video/voice calls, live streaming, online gaming — where a dropped packet is preferable to a delayed, stale one
Why this matters for testing

if you're ever asked to test a video call or live-streaming feature, understanding that it likely runs over UDP (not TCP) explains why occasional glitches/frozen frames are an accepted trade-off rather than always a bug — and why your test cases should focus on graceful degradation, not "zero packet loss ever."

B.8 The TCP three-way handshake — concept only Awareness

Before any TCP data flows, the client and server exchange three messages to establish a connection: SYN (client: "let's connect") → SYN-ACK (server: "okay, let's connect") → ACK (client: "confirmed"). Awareness level: know it exists and why (it's how TCP establishes a reliable connection before trusting any data) — you won't be asked to diagram packet flags.

B.9 DNS — how a domain name becomes a server Must Know

sequenceDiagram
    participant Browser
    participant DNS as DNS Resolver
    participant Server
    Browser->>DNS: "What's the IP for shop.example.com?"
    DNS-->>Browser: "203.0.113.42"
    Browser->>Server: HTTP request to 203.0.113.42
    Server-->>Browser: HTTP response

DNS (Domain Name System) translates a human-readable domain into the IP address a computer actually connects to — already mentioned briefly in Part 2.9, expanded here because "explain what happens when you type a URL and press Enter" is one of the most common general-technical interview questions across both QA and dev roles, and DNS resolution is always expected as part of a complete answer.

B.10 Ports — why localhost:8000 and localhost:5432 don't collide Must Know

A port is a number that identifies a specific service on a machine, letting one IP address run many independent network services simultaneously. Common ones worth recognizing cold: 80 (HTTP), 443 (HTTPS), 22 (SSH), 3306 (MySQL), 5432 (PostgreSQL), 5173/3000/8000 (common local dev-server defaults). When your test environment URL is staging.example.com:8080, the :8080 is telling your browser which service on that server to talk to.

B.11 "What happens when you type a URL and press Enter?" — the model answer Must Master

This exact question (or a close variant) appears often enough across BD tech interviews — QA and dev alike — that it's worth having a clean, complete answer memorized:

  1. The browser checks if it already knows the IP for that domain (cache); if not, it asks a DNS resolver to look it up.
  2. The browser opens a TCP connection to that IP on the right port (443 for HTTPS).
  3. For HTTPS, a TLS handshake happens — client and server agree on encryption and verify the server's certificate, so the connection is encrypted from this point on.
  4. The browser sends an HTTP request (method, path, headers) over that encrypted connection.
  5. The server processes the request (runs backend logic, queries a database) and sends back an HTTP response (status code, headers, body).
  6. The browser parses and renders the response (HTML/CSS/JS, or in an API context, hands the JSON back to whatever called it).

Every single piece of this sentence maps to something you've already studied in this guide (Parts 2, 12, 15) or in B.6-B.9 above — this question is really just asking you to assemble the pieces into one coherent story.

B.12 TLS/HTTPS — what "encrypted" actually buys you Must Know

HTTPS is HTTP sent over a TLS-encrypted connection. Practically, for testing purposes, this means: data in transit can't be read or tampered with by anyone intercepting the network traffic between client and server (a public Wi-Fi network, for instance). It does not mean the data is encrypted once it reaches the server's database — that's a separate concern (encryption at rest), and conflating the two is a common junior mistake worth avoiding out loud in an interview.

B.13 File systems & permissions — the Linux tie-in Should Know

You already covered the practical command side of this in Part 13. The one conceptual piece worth adding: Linux file permissions (rwx for owner/group/others, as in -rwxr-xr-x) exist precisely to prevent one process or user from reading/modifying files it shouldn't — the same authorization principle from Part 2.8, applied at the operating-system level instead of the application level.

Interview questions — Part B

  1. What's the practical difference between a process and a thread, and why does that difference matter for debugging a crash?
  2. Explain what happens, step by step, when you type a URL into a browser and press Enter.
  3. Why would a video-streaming feature likely be built on UDP instead of TCP, and what does that imply about how you'd test it?
  4. What does HTTPS actually protect, and what does it not protect?
  5. What's the difference between a race condition and a deadlock? Give a QA-relevant example of each.

Exercise (do this — don't skip)

Open a terminal and run ping google.com, then nslookup google.com (or dig google.com if available). Write down, in your own words, what each command's output tells you and which layer of the B.6 model each one is operating at.

Awareness Chapter: Automation, Performance, Security, CI/CD

Awareness
Estimated time: 5 hours total

This entire chapter is intentionally conceptual, not hands-on. The goal: never be blindsided if these come up in an interview, without spending the 60+ hours real proficiency would take. If a specific job posting you're applying to explicitly requires hands-on Selenium or JMeter, treat that as a signal to deep-dive that one topic for that application — don't pre-invest broadly here.

19.1 Selenium & Browser Automation (concept only)

What it is

Selenium WebDriver is a tool that programmatically controls a real browser — clicking, typing, reading page content — so test scripts can replay UI interactions automatically instead of a human doing it by hand.

Core concepts to recognize by name (not implement):

Term Meaning
WebDriver The component that talks to and controls the browser
Locators Ways to find an element on a page: id, name, class, CSS selector, XPath
XPath A query language for navigating HTML/XML structure, e.g. //button[@id='submit']
Explicit wait Waiting for a specific condition (e.g., element becomes clickable) before proceeding — prevents flaky tests
Implicit wait A global timeout applied to all element lookups
Page Object Model (POM) A design pattern where each page of the app has a corresponding class encapsulating its elements/actions, keeping test code maintainable
Why POM matters conceptually

if the login button's HTML changes, without POM you'd have to fix that locator in every test file that clicks it; with POM, you fix it in one place (the LoginPage class). This design principle — separating "what a page can do" from "what a test asserts" — is worth understanding even without writing the code, because it's a genuinely good software engineering habit that also applies to Django's separation of concerns later.

Interview-safe things to say if asked

"I've built a real, working automation suite with Playwright — including Page Object Model structure, auto-waiting, and a CI pipeline — and I understand Selenium's core concepts (locators, explicit/implicit waits, POM) even though my hands-on depth is specifically in Playwright. The underlying approach transfers directly if a role needs Selenium specifically."

19.2 Performance Testing & JMeter (concept only)

Term Meaning
Performance testing Umbrella term: how the system behaves under load (speed, stability)
Load testing Behavior under expected/normal concurrent user load
Stress testing Push beyond normal capacity to find the breaking point
Spike testing Sudden, sharp increase in load, then back down
Endurance/soak testing Sustained normal load over a long duration (finds memory leaks, slow degradation)
Response time Time for a single request to get a response
Throughput Requests handled per unit time
Concurrent users How many users are active simultaneously
Bottleneck The specific component (DB, network, CPU) limiting overall performance

JMeter, at a glance: an open-source tool that simulates many virtual users hitting an application simultaneously, measuring response times/throughput/error rates under that load. You don't need to build a JMeter test plan for this guide's scope — just know what problem it solves and that it's the most common free tool for this in BD job postings that mention performance testing.

19.3 Security Testing Basics (recognize, don't exploit)

A junior QA is expected to recognize these risk categories during normal functional testing, not perform formal penetration testing.

Concept What a QA should recognize
SQL Injection Malicious SQL smuggled through an input field (e.g., ' OR '1'='1) that could manipulate a database query if the backend doesn't properly sanitize/parameterize input
XSS (Cross-Site Scripting) Malicious script (e.g., <script>alert(1)</script>) submitted through an input and later rendered/executed in another user's browser
CSRF (Cross-Site Request Forgery) Tricking a logged-in user's browser into making an unwanted request to a site they're authenticated on
Password security Passwords should never be visible in plaintext (in DB, logs, or network traffic over HTTP); should be hashed
Session management Sessions should expire, logout should actually invalidate the session (not just hide the UI), tokens shouldn't be guessable
Access control (authZ) A regular user should never be able to reach admin-only data/actions by directly manipulating a URL or API call
File upload security Uploaded files should be validated server-side, not just by client-reported extension
Input validation Every user input should be validated/sanitized server-side, never trusted from the client alone
The one practical technique worth actually trying

type ' OR '1'='1 or <script>alert(1)</script> into a normal text input during your own manual testing, and observe what happens. This costs nothing, requires no tooling, and is a real (if basic) security-awareness move that shows up favorably in interviews when you mention you do it as a habit.

19.4 CI/CD Fundamentals (concept only)

flowchart LR
    A[Code Commit] --> B[CI: Build]
    B --> C[CI: Run Automated Tests]
    C -->|Pass| D[CD: Deploy to Staging]
    C -->|Fail| E[Notify Team, Block Merge]
    D --> F[Manual/Exploratory QA on Staging]
    F --> G[CD: Deploy to Production]
  • CI (Continuous Integration): automatically building and testing code every time it's committed, catching integration issues early.
  • CD (Continuous Deployment/Delivery): automatically (or semi-automatically) releasing code that passes CI to staging/production.
  • GitHub Actions / Jenkins: common tools that run these pipelines. Know they exist and roughly what a pipeline config file does (triggers on a git event, runs a sequence of steps) — not hands-on pipeline authorship at this stage.
  • Why QA cares: in a CI/CD world, automated tests (if they exist) run on every commit automatically, and manual/exploratory QA typically happens on the resulting staging deployment, not on developers' laptops. Understanding this flow helps you understand where in the pipeline a bug likely slipped through.

Interview questions — Part 19

  1. What is the Page Object Model, and why is it useful even beyond automation (as a design principle)?
  2. What's the difference between load testing and stress testing?
  3. Give an example of an XSS vulnerability you might notice during normal manual testing, without any special tools.
  4. In a CI/CD pipeline, at what point does automated testing typically happen, and at what point does manual QA typically happen?
  5. Honest self-assessment question interviewers ask: "What's your automation experience?" — practice giving the honest, confident answer from 19.1 rather than either overclaiming or being apologetic.

Light DSA / Problem-Solving

Should Know
Estimated time: 8 hours

Deliberately trimmed — real DSA depth is deferred to your backend/Django interview prep later, where it will actually be weighted much more heavily. This section exists so a basic coding-screening round doesn't eliminate you.

18.1 What's realistic to expect

Most broad BD manual/API QA roles do not test DSA at all. Some stronger companies (and Therap, per public reports) include a lighter programming/logic section — usually basic string/array manipulation and simple algorithmic thinking, not competitive-programming-level problems. The goal here is "don't freeze up," not "solve anything in under 15 minutes."

18.2 Concepts worth 2-3 hours each (understand + do 2-3 problems, don't grind)

Concept What to know
Big-O basics O(1), O(n), O(log n), O(n²) — recognize which is which for a piece of code, not derive formally
Arrays/Lists Iteration, searching, basic manipulation
Strings Reversal, palindrome check, character counting
Hash maps/sets (Python: dict/set) Fast lookup, duplicate detection — this is the single highest-value DSA concept for QA-adjacent thinking, since it mirrors "find duplicates in test data"
Two pointers Simple technique for sorted-array/string problems
Basic recursion Factorial, Fibonacci — just enough to not be confused when you see it
Sorting Know that sorted()/.sort() exist and roughly what "sorting takes O(n log n)" means — not implementing sort algorithms by hand
Binary search The classic "guess the number" halving technique — very commonly asked as a simple standalone problem

Explicitly not covered at this trim level (defer to backend-dev prep): trees, graphs/BFS/DFS, dynamic programming, advanced greedy algorithms, linked lists beyond basic awareness. If a specific job posting mentions these, treat that as a signal to study them for that interview specifically — don't pre-invest broadly.

18.3 Curated problem list — 18 problems

# Problem Difficulty Concept Why it matters for QA screening
1 Two Sum Easy Hash map The single most commonly asked screening problem anywhere
2 Valid Palindrome Easy Two pointers, strings Extremely common warm-up
3 Valid Anagram Easy Hash map/counting Common, tests basic string/dict fluency
4 Contains Duplicate Easy Set/hash Directly mirrors real QA "find duplicate data" thinking
5 Binary Search Easy Binary search Classic; also a common conceptual interview question even without coding
6 Reverse String Easy Two pointers Common basic warm-up
7 First Unique Character in a String Easy Hash map/counting Common, practical string logic
8 Best Time to Buy and Sell Stock Easy Single-pass array logic Frequently appears in "basic logic" screening rounds
9 Maximum Subarray Easy/Medium Array, basic DP intuition Common, good stretch problem
10 Valid Parentheses Easy Stack Very commonly asked, teaches stack concept cleanly
11 Merge Two Sorted Lists Easy Linked list basics Common; enough linked-list exposure to not be blindsided
12 FizzBuzz Easy Loops/conditionals Sounds trivial — is still occasionally used as a literal filter question; must be instant
13 Palindrome Number Easy Basic math/logic Common variant of the palindrome theme
14 Roman to Integer Easy Hash map, string parsing Common, tests careful logic under a slightly fiddly spec — good BVA-adjacent practice
15 Missing Number Easy Array/math Common, has a satisfying "aha" trick worth learning
16 Two Sum II (sorted array) Easy Two pointers Reinforces two-pointer technique in a different shape
17 Climbing Stairs Easy Basic recursion/DP intuition The most commonly used "simple recursion" teaching problem
18 Number of 1 Bits Easy Bit basics Occasionally appears; low effort to learn once
How to use this list

don't grind all 18 back-to-back. Spread 2-3 per study session across weeks 8-9 of your schedule. For each: attempt for 15-20 minutes unaided first, then look up the pattern if stuck — the goal is pattern recognition, not raw memorization.

Interview questions — Part 18

  1. What's the time complexity of a hash map lookup, and why does that make it useful for "find duplicates" problems?
  2. Walk through binary search conceptually, without writing code — what's the core idea?
  3. Given an unsorted list, how would you find if it contains any duplicate values, and what's the time complexity of your approach?

Resources

  • LeetCode — Essential, use the free tier; the "Easy" filter plus the list above is sufficient at this stage.
  • NeetCode.io — Optional, free video explanations if a problem's pattern doesn't click from the problem statement alone.

Agile QA & Professional Communication

Must Know
Estimated time: 4 hours

20.1 QA's actual day-to-day inside a Scrum team

A realistic sprint, from a QA's chair:

  1. Sprint planning: you review upcoming stories for testability, flag ambiguous acceptance criteria.
  2. During the sprint: as devs finish pieces, you write test cases from acceptance criteria, execute them as builds become available, log bugs, retest fixes.
  3. Regression: near sprint end, you re-run a regression suite (manual checklist or automated, if it exists) to make sure nothing else broke.
  4. Bug triage: meeting (formal or informal) where the team collectively decides bug priority — is this fixed this sprint, or backlogged?
  5. Sprint review: you may demo tested functionality or confirm what's genuinely "done."
  6. Retrospective: you raise process issues (e.g., "we keep getting builds too late in the sprint to test properly").

20.2 Communicating with different roles

Audience What they care about How to adjust your communication
Developers Exact technical reproduction steps, logs, root cause hints Be precise, technical, non-judgmental — "I found X" not "you broke X"
Product Managers Business impact, user experience risk Lead with impact ("this blocks checkout for X% of users"), not technical detail
Business Analysts Whether behavior matches requirements/acceptance criteria Reference the specific acceptance criterion that's violated
QA Lead Test coverage, risk areas, blockers Be honest about what's NOT tested yet, not just what passed
Customers (rare, but possible) Confidence the product works, plain language No jargon, focus on outcomes not internals

20.3 Scenario-based professional judgment Must Master

"How do you disagree professionally with a developer who says a bug isn't a bug?" Model answer approach: restate the acceptance criteria or expected behavior objectively, provide clear reproduction evidence, ask clarifying questions rather than asserting ("Can you help me understand the intended behavior here? Based on the acceptance criteria, I expected X but observed Y.") — avoid framing it as a personal disagreement; frame it as a shared question about what's correct.

"How do you report a critical bug found right before release?" Escalate immediately and directly (don't wait for the next standup) to whoever owns the release decision, with clear severity/impact framing, and let them make the release-vs-delay call — it's not solely your call, but it is your job to surface it loudly and immediately.

"What do you do when a developer says 'works on my machine'?" Provide exact environment details (browser/OS/build version), ask what their environment differs by, and offer to pair/screen-share to reproduce live — this phrase almost always means an environment or data difference, not that you're wrong.

"What do you do when requirements conflict or are ambiguous?" Don't guess and don't silently pick one interpretation — flag it explicitly to the PM/BA/team, ideally before you've built test cases around a wrong assumption, and document the clarification once you get it (in the ticket, not just verbally) so it doesn't get re-litigated later.

"How do you prioritize testing when time is limited?" Apply risk-based testing (Part 7.9) explicitly: highest business impact + highest likelihood of failure first; communicate clearly to the team what you did NOT get to test, rather than silently under-testing and letting people assume full coverage.

Interview questions — Part 20

  1. Walk through a time (real or hypothetical) you disagreed with a developer about whether something was a bug.
  2. How would you handle discovering a critical bug 2 hours before a scheduled release?
  3. What's your process when acceptance criteria are missing or contradictory?

QA Metrics

Should Know
Estimated time: 2 hours
Metric Formula/meaning Why it matters
Defect density Defects ÷ size (e.g., per 1000 lines of code, or per module) Identifies which modules are riskiest
Defect leakage Defects found in production ÷ total defects found (including pre-release) Measures how well testing caught issues before release
Test coverage % of requirements/code covered by test cases Identifies untested areas
Pass/fail rate % of executed test cases that passed vs failed Snapshot of current build health
Defect severity distribution Breakdown of bugs by severity level Shows overall build risk/quality at a glance
Reopen rate % of "fixed" bugs that had to be reopened Signals fix quality / dev-QA communication issues
Test execution progress % of planned test cases executed so far vs. remaining Tracks whether testing will finish on schedule

These are asked about conceptually far more often than you'll be expected to calculate them from scratch at entry level — know what each measures and why a team would track it, more than memorizing exact formulas.

Interview questions — Part 21

  1. What does a high defect leakage rate suggest about a QA process?
  2. Why might a team care about reopen rate specifically, separate from just the raw bug count?
  3. If test execution progress shows only 60% complete with 2 days left in the sprint, what would you do?

Interview Question Bank, Mock Written Exam, and Mock Interviews

Must Master
Estimated time: 15 hours

This is your final consolidation phase — everything above compressed into rapid-recall and exam-condition practice.

22.1 How to use this section

Don't just read the questions and nod. For each theory question, actually say your answer out loud or write it down before checking your understanding against the relevant Part above. For the mock exam, actually time yourself.


22.2 QA Theory Question Bank (50 questions)

Fundamentals

  1. What is the difference between QA and QC?
  2. What is the difference between verification and validation?
  3. Define error, defect, bug, and failure.
  4. What is the difference between a test scenario and a test case?
  5. What is a test suite vs a test plan?
  6. What's the difference between manual and automation testing, and when would you choose each?
  7. What is black-box vs white-box vs grey-box testing?
  8. What is positive vs negative testing?
  9. What is static vs dynamic testing?
  10. What is the difference between functional and non-functional testing?

Types of testing

  1. Differentiate smoke, sanity, and regression testing.
  2. What's the difference between retesting and regression testing?
  3. What is exploratory testing, and how is it different from ad-hoc testing?
  4. What is the difference between system testing and integration testing?
  5. What's the difference between UAT and system testing?
  6. What is compatibility testing, and what does it typically cover?
  7. What is the difference between localization and internationalization testing?
  8. What is load testing vs stress testing vs spike testing?
  9. What is recovery testing, with an example?
  10. What is usability testing, and how would you evaluate it?

Test design techniques

  1. Explain Equivalence Partitioning with an example.
  2. Explain Boundary Value Analysis with an example.
  3. Why are EP and BVA usually used together?
  4. When would you use decision table testing?
  5. What is state transition testing, and what kind of bug is it best at catching?
  6. What is pairwise testing, and why is it useful?
  7. What is risk-based testing, and how would you apply it under time pressure?
  8. What is error guessing, and why is it still valuable despite being informal?

Process

  1. Explain SDLC and QA's role at each phase.
  2. Explain STLC phase by phase.
  3. What is shift-left testing, and why does it save cost?
  4. What's the difference between Definition of Ready and Definition of Done?
  5. What are entry and exit criteria for test execution?
  6. What is a user story, and what is an acceptance criterion?

Bug reporting

  1. What's the difference between severity and priority? Give an example where they don't match.
  2. Walk through the full defect lifecycle.
  3. What makes a bug report "good" vs "bad"?
  4. What's the difference between "Rejected" and "Duplicate" as bug statuses?

SQL/DB

  1. What's the difference between WHERE and HAVING?
  2. Explain INNER JOIN vs LEFT JOIN.
  3. How would you find duplicate records in a table?
  4. How would you verify referential integrity as a QA engineer?

API

  1. What's the difference between PUT and PATCH?
  2. What does idempotent mean?
  3. What's the difference between 401 and 403?

General judgment

  1. How do you prioritize testing when time is limited?
  2. What would you do if requirements are ambiguous or missing?
  3. How do you handle a developer saying "works on my machine"?
  4. How would you test a feature you've never seen before, in general terms (describe your framework)?
  5. What does "done" mean to you as a QA engineer on a feature?

22.3 Scenario Questions (20 questions)

Use the framework from Part 9.2. These are deliberately varied — practice picking the framework apart differently each time rather than memorizing one script.

  1. How would you test a "forgot password" feature?
  2. How would you test a shopping cart's quantity selector?
  3. How would you test a file upload feature that only accepts PDFs under 5MB?
  4. How would you test a login page's "remember me" checkbox?
  5. How would you test a search feature with autocomplete?
  6. How would you test a payment gateway integration?
  7. How would you test a notification/alert system?
  8. How would you test a multi-step signup wizard (3 steps, back/next navigation)?
  9. How would you test a "forgot password" link's expiry?
  10. How would you test an admin panel's user-role permission system?
  11. How would you test a coupon code with a minimum order value requirement?
  12. How would you test a date range filter on a report?
  13. How would you test an infinite-scroll social media feed?
  14. How would you test a "delete account" feature with a confirmation step?
  15. How would you test a rate-limited login (account lockout after N attempts)?
  16. How would you test a currency converter feature?
  17. How would you test an image upload with automatic thumbnail generation?
  18. How would you test a two-factor authentication (2FA) flow?
  19. How would you test a "export to CSV" feature on a large dataset?
  20. How would you test a real-time chat message delivery feature?

22.4 SQL Questions (20 questions)

Beyond the 40 practice problems in Part 12.11, these are conceptual/verbal SQL questions common in interviews:

  1. What's the difference between DELETE and TRUNCATE?
  2. What's a primary key vs a foreign key?
  3. What does a self-join do, and give a real use case.
  4. Write a query (verbally or on paper) to find users with no orders.
  5. What's the difference between UNION and UNION ALL?
  6. What's an index, and why does it speed up queries?
  7. What's the difference between a subquery and a JOIN — when would you prefer one?
  8. How would you find the second-highest value in a column?
  9. What does NULL mean in SQL, and why can't you compare it with =?
  10. What's the difference between COUNT(*) and COUNT(column_name)?
  11. How would you check for orphaned foreign key records?
  12. What's normalization, in plain terms?
  13. How would you find duplicate rows in a table?
  14. What's the difference between INNER JOIN and OUTER JOIN (LEFT/RIGHT/FULL)?
  15. What does GROUP BY actually do, step by step?
  16. Why should you run a SELECT before a destructive UPDATE/DELETE?
  17. What's a transaction, and why does it matter for financial data integrity?
  18. How would you verify a migration didn't lose any data?
  19. What's the difference between VARCHAR and CHAR?
  20. How would you find the total revenue per month from an orders table?

22.5 Linux Questions (15 questions)

  1. How would you view the last 50 lines of a log file?
  2. How would you search a log file for the word "ERROR"?
  3. What's the difference between > and >> redirection?
  4. How would you count how many lines in a file contain a specific word?
  5. What does chmod +x script.sh do?
  6. How would you find all .log files in a directory tree?
  7. What does ps aux show you?
  8. How would you kill a hung process?
  9. What's the difference between cat and less?
  10. How would you follow a log file live as new lines are written?
  11. What does a pipe (|) do?
  12. How would you check disk space usage? (df -h)
  13. What's an environment variable, and how would you set one temporarily?
  14. How would you use curl to test a GET endpoint?
  15. Why might a QA engineer need SSH access to a staging server?

22.6 API Testing Questions (15 questions)

  1. What's the difference between GET and POST?
  2. What does a 404 mean vs a 500?
  3. What's the difference between authentication and authorization in API testing?
  4. How would you test an API endpoint for negative cases?
  5. What's schema validation, and why does it matter?
  6. How would you test pagination on a GET endpoint?
  7. What's the difference between a query parameter and a path parameter?
  8. How would you test that an API correctly rate-limits requests?
  9. What's a Bearer token, and where does it go in a request?
  10. How would you chain requests in Postman (e.g., login then use the token)?
  11. Why might you test an API directly instead of only through the UI?
  12. What does idempotent mean, and which methods are idempotent?
  13. How would you test a file upload API's negative cases?
  14. What's the difference between 401 and 403?
  15. How would you validate that a POST request's response body matches what was sent?

22.7 Python Questions (15 questions)

  1. What's the difference between a list and a tuple?
  2. How do you handle an exception in Python?
  3. What does a dictionary look like, and how do you safely access a key that might not exist?
  4. Write a function that checks if a string is a palindrome.
  5. What's the difference between == and is?
  6. How would you read a JSON file and access a nested field?
  7. What does self mean in a Python class method?
  8. What's the difference between a function and a method?
  9. How would you make a GET request and check the status code using requests?
  10. What does list slicing do — give an example.
  11. What's a list comprehension? Give a simple example.
  12. How do you loop over both keys and values of a dictionary?
  13. What's inheritance, and why is it useful?
  14. How would you handle a request that might time out?
  15. What's the difference between append() and extend() on a list?

22.8 Light DSA/Coding Questions (10 questions)

  1. Write a function to reverse a string.
  2. Write a function to check if a string is a palindrome.
  3. Write a function to find duplicates in a list.
  4. Implement binary search.
  5. Write FizzBuzz.
  6. Find the first non-repeating character in a string.
  7. Given two lists, find their intersection.
  8. Write a function to count vowels in a string.
  9. Given an array, find the maximum difference between two elements where the larger comes after the smaller (Best Time to Buy/Sell Stock pattern).
  10. Explain (don't necessarily code) how you'd check if two strings are anagrams of each other.

22.9 HR / Behavioral Questions (15 questions)

  1. Tell me about yourself.
  2. Why do you want to work in QA?
  3. Why should we hire you over other fresh graduates?
  4. Describe a time you found a significant bug — walk me through it. (If you lack real job experience, use a personal project or this guide's exercises — describe a real bug you found while practicing, e.g., in Part 8's scenario work.)
  5. Describe a time you disagreed with someone and how you handled it.
  6. How do you handle repetitive/tedious work? (Regression testing is genuinely repetitive — they're probing for realistic expectations.)
  7. How do you handle tight deadlines?
  8. What are your strengths and weaknesses?
  9. Where do you see yourself in 2-3 years? (Be thoughtful here — see the note below.)
  10. How do you stay updated on QA/testing trends?
  11. Describe your ideal work environment.
  12. How do you handle receiving critical feedback on your work?
  13. What do you know about our company?
  14. Do you have any questions for us?
  15. Why did you choose this career path?
A note on Q9 ("where do you see yourself in 2-3 years") given your actual plan

You don't need to hide your interest in backend development — but frame it honestly and professionally rather than either lying ("I want to be a QA lead forever") or bluntly stating "I'm using this as a stepping stone" (which reads as a flight risk). A strong, honest middle answer: "I want to build a strong foundation in quality and testing first, and I'm also naturally curious about the engineering side of things — long-term I could see myself growing into a role that combines both testing rigor and hands-on development, but right now my focus is becoming genuinely excellent at this role." This is true, doesn't overcommit, and doesn't raise a red flag.


22.10 General BD-Style Mock Written Exam

In plain English

This is a realistic simulation based on commonly-reported patterns in BD SQA written tests broadly (not a leaked or company-specific exam). Time yourself: 90 minutes total, no notes, as close to real exam conditions as you can manage.

Section A — QA Theory (10 questions, 15 minutes, short answers)

  1. Differentiate severity and priority with an example.
  2. Differentiate smoke and sanity testing.
  3. What is Boundary Value Analysis? Give an example.
  4. What is the difference between verification and validation?
  5. Explain the defect lifecycle briefly.
  6. What is Equivalence Partitioning?
  7. What is regression testing, and when is it performed?
  8. What is the difference between a test case and a test scenario?
  9. What is exploratory testing?
  10. What is the difference between STLC and SDLC?

Section B — Test Case Writing (20 minutes) Write complete, professional test cases (using the structure from Part 8.1) for the following feature: "A 'Change Password' form requires the user to enter their current password, a new password (8-20 characters, at least 1 number), and confirm the new password. On success, show a confirmation message and log the user out of all other sessions." Write at least 6 test cases covering positive, negative, and boundary cases.

Section C — Bug Report Writing (10 minutes) You observe: when changing your password to one that's exactly 20 characters, the form silently fails with no error message and the password is not changed. Write a complete professional bug report for this.

Section D — SQL (20 minutes, 6 questions) Given the users/orders schema from Part 12:

  1. Write a query to find all users who registered in 2025.
  2. Write a query to find the total revenue per user, only for users who spent over ৳3000.
  3. Write a query to find users with no orders.
  4. Write a query to find duplicate emails in the users table.
  5. Write a query to find the top 3 highest-spending users.
  6. Explain, in one sentence, the difference between WHERE and HAVING (you'll have used both above).

Section E — Linux (10 minutes, 4 questions)

  1. Write a command to find all .log files under /var/log.
  2. Write a command to show the last 100 lines of app.log.
  3. Write a command to count how many lines contain "ERROR" in app.log.
  4. Write a command to give a script execute permission.

Section F — Logic/Coding (15 minutes, 2 questions)

  1. Write a function (Python or pseudocode) to check whether a string is a palindrome.
  2. Write a function to find the first non-repeating character in a string.

22.11 Mock Exam — Answer Key

Section A

  1. Severity = technical impact of the defect; Priority = business urgency to fix. Example: a homepage typo is Low severity, High priority.
  2. Smoke = broad, shallow check that a new build is stable enough to test further. Sanity = narrow, focused check after a specific fix.
  3. BVA tests values at the edges of valid ranges (min, just below min, just above min, max, just below max, just above max) since bugs cluster at boundaries. Example: age field 18-60 → test 17, 18, 19, 59, 60, 61.
  4. Verification = "are we building it right?" (static, document/spec review). Validation = "are we building the right thing?" (dynamic, executing the software).
  5. New → Assigned → Open → Fixed → Retest → Closed (or Reopened if retest fails); alternate paths: Rejected, Duplicate, Won't Fix.
  6. EP divides inputs into partitions where all values should behave the same; test one representative value per partition to reduce redundant testing.
  7. Regression testing re-runs existing tests to confirm previously working functionality still works after a code change; performed after any change, especially before release.
  8. A test scenario is a high-level "what to test" (one line); a test case has detailed steps, data, and expected results. One scenario often expands into multiple test cases.
  9. Exploratory testing is simultaneous learning, test design, and execution — structured and purposeful, guided by tester experience, distinct from unstructured "ad-hoc" testing.
  10. SDLC covers the whole software development process (requirements through maintenance); STLC is the testing-specific subset of activities (requirement analysis through test closure), which runs in parallel with/within the SDLC.

Section B (sample strong test cases — yours don't need to match exactly, but should hit these categories)

  • TC1 (Positive): Valid current password, valid new password (8-20 chars, has a number), matching confirmation → success message shown, other sessions logged out.
  • TC2 (Negative): Incorrect current password entered → error shown, password NOT changed.
  • TC3 (Negative): New password and confirm password don't match → error shown, password NOT changed.
  • TC4 (Negative): New password has no number → validation error shown.
  • TC5 (Boundary): New password exactly 8 characters with a number → accepted (min boundary).
  • TC6 (Boundary): New password exactly 20 characters with a number → accepted (max boundary) — this is the exact case that exposes the bug in Section C.
  • TC7 (Boundary): New password 21 characters → rejected with validation error.
  • TC8 (Security): After password change, verify old password no longer works for login.

Section C (sample strong bug report)

Title

Change Password form fails silently (no error, no success) when new password is exactly 20 characters
Environment: [fill with your actual test environment]
Preconditions: Logged in as a valid user
Steps to Reproduce: 1) Go to Change Password form. 2) Enter correct current password. 3) Enter a new password exactly 20 characters long, containing at least 1 number. 4) Enter the same value in Confirm Password. 5) Submit.
Expected Result: Password is changed successfully; confirmation message shown; other sessions logged out.
Actual Result: No confirmation message appears, no error message appears, and the password is not actually changed (verified by attempting login with the new password, which fails).
Severity: Major (a valid boundary-length password should be accepted; this silently breaks the feature with no user feedback)
Priority: High
Reproducibility: Always

Section D

1. SELECT * FROM users WHERE YEAR(created_at) = 2025;
2. SELECT user_id, SUM(amount) AS total FROM orders GROUP BY user_id HAVING SUM(amount) > 3000;
3. SELECT u.name FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.id IS NULL;
4. SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
5. SELECT user_id, SUM(amount) AS total FROM orders GROUP BY user_id ORDER BY total DESC LIMIT 3;
6. WHERE filters individual rows before grouping; HAVING filters groups after aggregation — you can't use an aggregate function like SUM() inside WHERE.

Section E

1. find /var/log -name "*.log"
2. tail -n 100 app.log
3. grep -c "ERROR" app.log
4. chmod +x script.sh

Section F

1. def is_palindrome(s):
       s = s.lower().replace(" ", "")
       return s == s[::-1]

2. def first_unique_char(s):
       from collections import Counter
       counts = Counter(s)
       for i, ch in enumerate(s):
           if counts[ch] == 1:
               return i
       return -1
Scoring guide

90%+ = excellent, apply with confidence. 70-89% = solid, review your weak sections above before applying. Below 70% = go back to the relevant Parts before moving to job applications — this exam mirrors real conditions closely enough that a low score here predicts a rough real written test.


22.12 Mock Technical Interview 1 (theory + SQL leaning)

In plain English

Realistic simulation — practice out loud, ideally recorded, ideally with a friend reading questions to you.

  1. Tell me about yourself and your QA background. (prep a 60-90 second answer)
  2. Walk me through STLC.
  3. What's the difference between severity and priority? Give me an example where they'd differ.
  4. How would you test a login page? (use the Part 9 framework live)
  5. Write a SQL query to find all users who have placed more than 2 orders.
  6. What's the difference between INNER JOIN and LEFT JOIN?
  7. How would you test an API endpoint that creates a new order?
  8. What is Boundary Value Analysis, and can you apply it to a "quantity" field that accepts 1-10?
  9. Describe a bug you found (in your own practice/portfolio work) and how you reported it.
  10. Do you have any questions for us?
What each question is really testing

Q1 is communication/structure. Q2-4 are theory fluency and applied thinking. Q5-6 are hard SQL skill checks — hesitation here is heavily penalized since SQL is considered "should be automatic" by many BD interviewers. Q7-8 test whether you can apply test design techniques outside a textbook example. Q9 tests whether you have genuine hands-on practice, not just reading. Q10 tests engagement/seriousness — always have 2-3 real questions ready (e.g., "what does the QA-developer collaboration process look like day to day?", "what testing tools does the team currently use?").

22.13 Mock Technical Interview 2 (scenario + light coding leaning)

  1. How would you test a food delivery app's live order-tracking feature?
  2. How would you test a coupon code system with a minimum order value?
  3. Write a Python function to check if two strings are anagrams.
  4. What's the difference between PUT and PATCH?
  5. How would you prioritize testing if you only had 2 days for a feature that normally needs a week?
  6. Walk me through the defect lifecycle for a bug that gets reopened.
  7. Design a decision table for: a shipping discount applies if (order ≥ ৳1000) OR (user is Premium).
  8. What would you do if a developer said a bug you reported was "not reproducible" on their end?
  9. Write a command to find how many times "timeout" appears in a log file.
  10. What's your experience with automation, and how do you see yourself growing that skill? (practice the honest framing from Part 19.1)

22.14 Mock HR Interview

  1. Tell me about yourself.
  2. Why QA, and why our company specifically? (research the actual company before a real interview — this is the one question you cannot template)
  3. What are your salary expectations? (research realistic BD entry-level QA ranges before answering; give a reasonable range, not a single rigid number, and it's fine to ask about their band first)
  4. How do you handle working under pressure or tight deadlines?
  5. Describe a time you made a mistake — what did you learn?
  6. Where do you see yourself in 2-3 years? (use the framing from 22.9)
  7. How do you handle repetitive tasks like regression testing?
  8. Are you comfortable working in a team with developers who may push back on your bug reports?
  9. Do you have any commitments that would affect your availability (e.g., studies)?
  10. Do you have any questions for us?
What NOT to say, across all mock interviews

don't badmouth a previous team/professor/project; don't say "I don't have any weaknesses"; don't say salary "doesn't matter" (reads as either naive or dishonest); don't say you're only interested in automation/coding if applying for a manual QA role (reads as a flight risk, even if it's honestly your longer-term plan — the framing from 22.9 handles this better than blunt honesty would).

Portfolio Projects & Capstone

Must Master
Estimated time: 12 hours

These live on your GitHub/CV and are what you point to when an interviewer asks "show me something you've actually built," not just "tell me what you know."

23.1 Portfolio Project 1 — Manual QA Documentation Project

Concept

Pick a real, publicly usable website or app (e.g., a demo e-commerce site like Sauce Demo, or a real feature-limited free app) and produce a complete, professional manual QA documentation set for one meaningful feature area (e.g., login + cart + checkout).

Deliverables

  1. A short Test Plan (scope, approach, in/out of scope, entry/exit criteria — 1 page).
  2. 20-30 test cases covering the feature area, using the structure from Part 8.1, spanning positive/negative/boundary/security categories.
  3. 3-5 bug reports for real issues you find (demo sites often have intentional or real bugs — Sauce Demo is specifically designed with known bugs for practice).
  4. A short Test Summary Report: how many executed, pass/fail counts, key risks found.
GitHub structure

manual-qa-project/
├── README.md
├── test-plan.md
├── test-cases.xlsx (or .csv/.md table)
├── bug-reports/
│   ├── BUG-001-cart-quantity-negative.md
│   └── ...
└── test-summary-report.md
README requirements

what site was tested, why, how to read the test cases, a summary of key findings, and — importantly — what you'd test next if you had more time (shows judgment about scope, not just completeness).

What to explain in interviews

walk through your thought process for 2-3 specific test cases (why you chose that boundary, why that negative case matters), and be ready to discuss one bug you found in detail, including its severity/priority reasoning.


23.2 Portfolio Project 2 — API Testing Project (your strongest project — prioritize this one)

Concept

A complete API test collection against a free public API (ReqRes or JSONPlaceholder), demonstrating both Postman skill and Python scripting skill — this dual demonstration is what makes this project stand out relative to typical junior portfolios.

Deliverables

  1. Postman collection (exported .json) — from Part 16.4's mini-project, with positive/negative/boundary folders, environment variables, chained requests, and assertions.
  2. A parallel Python script (using requests, from Part 17.10) that hits the same API and asserts the same core checks — showing you can do this outside Postman too.
  3. A README explaining: what API was tested, what was covered, how to run both the Postman collection and the Python script, and a summary of findings (even a public demo API sometimes has quirks/inconsistencies worth noting).
  4. A simple results log (even just printed output saved to a text file) showing pass/fail counts from a run.
GitHub structure

api-testing-project/
├── README.md
├── postman/
│   ├── collection.json
│   └── environment.json
├── python-tests/
│   ├── test_users_api.py
│   └── requirements.txt
└── results/
    └── sample_run_output.txt
What to explain in interviews

why you chose to test both via Postman and via Python (shows range), one specific negative/boundary case you're proud of, and how you'd extend this to a real authenticated API if given one.

23.3 Why only 2 projects, not 3

The original scope included a 3rd Selenium automation project. Given your priority (fast QA job → Django transition), a shallow/rushed Selenium project would likely hurt more than help — a thin, obviously-templated automation project is a worse signal than no automation project plus two genuinely strong, deeply-understood ones. If you later decide to stay in QA longer than planned, adding a Selenium project is a natural next step, using the awareness foundation from Part 19.1.


23.4 Capstone — Simulated End-to-End QA Cycle

In plain English

Do this in your final week before applying, as a full-dress rehearsal.

Fictional app

"QuickCart" — a small e-commerce web app with: user registration/login, product browsing with category/price filters, a cart, checkout with a mock payment step, and an order history page. Assume a REST API backend and a PostgreSQL-style database with users, products, orders, and order_items tables.

Your task, in order

  1. Requirement analysis: write 3 user stories with acceptance criteria for any 3 of the features above.
  2. Risk identification: list the 3 highest-risk areas of this app and why (hint: payment/checkout involves money — atomicity matters, per Part 8.5's ATM/banking discussion).
  3. Test planning: a short test plan covering scope for this cycle.
  4. Test scenarios: 10 scenarios across the app.
  5. Test cases: expand 5 of those scenarios into full test cases.
  6. Boundary analysis: apply BVA to at least 2 numeric/length-constrained fields (e.g., cart quantity, password length).
  7. Bug reports: write 2 realistic bug reports (invent plausible bugs consistent with the app description).
  8. SQL validation: write 3 SQL queries you'd run to verify data integrity after a checkout (e.g., order total matches sum of order_items, stock decremented correctly, no orphaned order_items).
  9. API testing: design a Postman-style test set (just the list of tests, doesn't need to be executable since this is fictional) for POST /api/orders.
  10. Regression: describe what you'd include in a regression checklist before a release.
  11. Basic performance awareness: name 2 things you'd want load-tested if this app had 10,000 concurrent users (awareness-level, per Part 19.2).
  12. Final QA report: a 1-page summary as if reporting to a QA lead — what's tested, what's risky, your recommendation (ship / don't ship / ship with known issues).

Do this yourself, genuinely, before looking at any model answer approach. This capstone is intentionally close to the shape of a real take-home QA assessment some BD companies use — treating it as a dry run is exactly the point.

Self-check after completing it

did you apply EP/BVA without being told to? Did your bug reports have precise steps and severity/priority reasoning? Did your SQL queries actually target data integrity, not just basic retrieval? Did your final report make an actual judgment call (not just list facts)? If yes to all four, you're genuinely at the "junior-ready" level this guide targets.

Cheat Sheets

Severity vs. Priority

Severity Priority
Answers "How broken is it?" "How fast do we fix it?"
Set by QA Business/Product (often)
Independent Yes — can be High/Low in any combination

Defect Lifecycle

New → Assigned → Open → Fixed → Retest → Closed (or Reopened → Assigned if retest fails); side paths: Rejected, Duplicate, Won't Fix.

SDLC vs STLC

  • SDLC: Requirements → Design → Development → Testing → Deployment → Maintenance.
  • STLC: Requirement Analysis → Test Planning → Test Case Development → Environment Setup → Test Execution → Test Closure.

Testing Types Quick Table

Smoke Sanity Regression Retest
Broad, shallow, new build Narrow, deeper, after small fix Broad, after any change Specific bug re-check after fix

Test Design Techniques

Technique Use when
EP Reduce redundant tests across input ranges
BVA Catch off-by-one bugs at edges
Decision Table Multiple combined business rules
State Transition Behavior depends on current state
Pairwise Many independent variables combine
Risk-Based Limited time, need to prioritize

HTTP Status Codes

2xx Success 3xx Redirect 4xx Client Error 5xx Server Error
200 OK, 201 Created 301, 304 400, 401, 403, 404, 409, 422, 429 500, 502, 503

SQL Quick Reference

SELECT col FROM table WHERE cond ORDER BY col LIMIT n;
SELECT col, COUNT(*) FROM table GROUP BY col HAVING COUNT(*) > n;
SELECT a.*, b.* FROM a INNER JOIN b ON a.id = b.a_id;
SELECT a.* FROM a LEFT JOIN b ON a.id = b.a_id WHERE b.id IS NULL;  -- "no matching b" pattern

Linux Quick Reference

pwd; ls -la; cd path; mkdir dir; touch file
cp src dst; mv src dst; rm -r dir
cat file; less file; head -n 10 file; tail -f file
grep "text" file; find . -name "*.log"
chmod +x file; ps aux; kill -9 pid
curl -X GET url; command1 | command2; cmd > file; cmd >> file

Git Quick Reference

git init / clone <url>
git status / add . / commit -m "msg"
git push / pull / fetch
git branch <name> / switch <name> / merge <name>

HTTP/API Quick Reference

Method Idempotent Use
GET Yes Retrieve
POST No Create
PUT Yes Full replace
PATCH No Partial update
DELETE Yes Remove

Python Quick Reference

d = {"k": "v"}; d.get("k", "default")
[x for x in items if condition]           # list comprehension
try: ... except Exception as e: ... finally: ...
class Foo:
    def __init__(self, x): self.x = x

Agile/Scrum Quick Reference

Backlog → Sprint Planning → Sprint (Daily Standups) → Sprint Review → Retrospective, repeating. DoR = criteria before work starts; DoD = criteria before work is "complete."


Resource Links (curated, not spammed)

Resource Topic Essential/Optional What to use it for
SQLZoo SQL Essential Interactive SELECT/JOIN/aggregate practice
Postman Learning Center API testing Essential Official docs, walk through collections/environments/tests
ReqRes / JSONPlaceholder API testing practice Essential Free public APIs for your Portfolio Project 2
LeetCode DSA Essential (light use) The 18-problem list in Part 18.3
GitHub Skills Git Essential if new to Git Free interactive lessons
MDN Web Docs HTTP/web fundamentals Optional Reference for HTTP status codes, headers
Python official docs Python Optional/reference Look up exact syntax when needed, not a start-to-finish read
PostgreSQL docs SQL/DB Optional/reference Same DB you'll likely use with Django later
NeetCode.io DSA Optional Video explanations if a LeetCode pattern doesn't click
Playwright official docs (Python) Automation (Part A) Essential for Part A Clear, example-heavy — the "Writing tests" and "Locators" pages map directly onto A.3-A.5
Selenium official docs Automation awareness Optional, later Only if a specific job posting requires hands-on Selenium — see A.8
Django official docs/tutorial Backend transition Essential — for Phase 2, not now Start here in Part 26's Django track

Job-Readiness Checklist & Scoring

26.1 Measurable checklist (check honestly — this isn't a reading-completion tracker)

  • [ ] Can explain SDLC and STLC phase-by-phase, unaided
  • [ ] Can write a 10+ step professional test case from a vague requirement
  • [ ] Can apply EP + BVA to a new, unfamiliar input field within 2 minutes
  • [ ] Can write a professional bug report from a rough description, including correct severity/priority reasoning
  • [ ] Can write moderately complex SQL (multi-table JOIN + GROUP BY + HAVING) from scratch, no lookup
  • [ ] Can navigate Linux commands (find, grep, tail, chmod, pipes) without hesitation
  • [ ] Can execute basic Git workflow (branch, commit, push, PR) unaided
  • [ ] Can design and run a Postman collection with positive/negative/boundary tests against a real API
  • [ ] Can read and write basic-to-intermediate Python (functions, classes, JSON, requests)
  • [ ] Has solved at least 12 of the 18 curated DSA problems
  • [ ] Can answer "how would you test X" live, using the structured framework, on an object never seen before
  • [ ] Completed the mock written exam (Part 22.10) at 70%+ within the 90-minute time limit
  • [ ] Completed both mock technical interviews and the mock HR interview out loud (recorded or with a partner)
  • [ ] Has 2 complete portfolio projects on GitHub with proper README files
  • [ ] Completed the capstone project (Part 23.4) independently before checking the self-check criteria

26.2 Scoring

Score Level
0-49% Beginner — keep working through the guide systematically
50-69% Developing — identify your weakest 2-3 checklist items and focus there
70-84% Junior-ready — start applying, keep sharpening weak spots in parallel
85-94% Strong candidate — apply broadly and confidently
95-100% Highly prepared — you're ready for stronger companies too

Don't wait for 95-100% to start applying. Job searching and interview cycles take weeks in BD; at 70%+ you should already be applying while continuing to sharpen the remaining items — the interview process itself is also valuable practice.


What Happens After You Get Hired: The Django Transition Plan

In plain English

This is the part that makes this whole guide make sense as a strategy, not just a QA course. Read this now, but really revisit it once you have the job.

27.1 The core idea

You'll be working full-time as a QA. The realistic hour budget for learning Django alongside a full-time job is roughly 1-2 hours/day on weekdays, more on weekends — call it 10-14 hours/week, similar or slightly less than your current pace since you'll also be adjusting to a new job. At that pace, a focused Django curriculum (roughly 150-180 hours, since backend dev requires more hands-on building than QA theory) takes ~12-16 weeks, comfortably inside your 4-5 month target.

27.2 What you already won't need to re-learn

Because of how this guide was built, you walk into the Django phase already knowing: Python fundamentals through OOP, SQL (deeply — directly maps to Django's ORM concepts), Git workflow, HTTP/REST/API concepts (you'll now be building the APIs you used to test), and JSON. This is a genuinely significant head start most Django beginners don't have — lean into it rather than re-studying these from a "backend dev" book from scratch.

27.3 Rough shape of the Django phase (for when you get there — not now)

  1. Django fundamentals (~25h): project/app structure, URLs, views, templates, settings.
  2. Models & ORM (~25h): this is where your SQL knowledge pays off directly — you'll recognize what the ORM is doing under the hood, which most beginners don't.
  3. Django REST Framework (DRF) (~30h): building the APIs — again, your Part 15-16 knowledge means you already know what a good API should look like from the consumer side, which is a real advantage when designing one.
  4. Authentication & permissions (~20h): directly connects to Part 2.8 and Part 19.3's security awareness.
  5. Admin, forms, deployment basics (~25h).
  6. Testing your own Django code (~15h): pytest/Django test framework — full circle, you'll be writing the automated tests you spent this whole guide learning to design manually.
  7. A real portfolio project (~30-40h): a small but complete Django + DRF app (e.g., a task tracker or small e-commerce backend) — this becomes your backend-dev portfolio piece.

27.4 Practical advice for the transition period itself

  • Don't mention your backend ambitions loudly at your new QA job in the first few months — build trust and do the QA job well first. It's fine (even good) to mention genuine technical curiosity if it comes up naturally, but you don't want to be perceived as already halfway out the door.
  • Being a good QA who understands the backend deeply is not wasted effort even from a pure career-strategy view — QA engineers who can read/write basic backend code and SQL are more valuable, better paid, and it's a completely reasonable, explainable internal growth story if you ever do want to formally move to a hybrid or backend role at the same company, rather than only external job-hopping.
  • When you do start applying for backend roles, your QA experience is a genuine asset, not something to downplay — "I understand what breaks software and how to test rigorously" is a real differentiator for a junior backend dev, and you should say so explicitly in those interviews.

This is the last part of the guide. Good luck — start September 25.

Drill Deck — Self-Check Flashcards

Must Master
Recall drills, not reading

This deck pulls exactly the facts Part 1.3 of the guide itself flags as "memorize — know cold, recall instantly": severity/priority, the defect lifecycle, SDLC/STLC order, HTTP status codes, core terminology, and the highest-yield facts from the new Automation and CS Fundamentals modules. Nothing here is new content — it's the guide's own facts, in a format built for spaced repetition instead of re-reading.

0
mastered
0
total cards
0
this session
Loading drill deck…