The Testing Academy · AI for QA

Seven AI Skills
Every QA Should Actually Learn

Seven short tutorials, in bullet points, with diagrams for every concept. Prep for interviews with NotebookLM, tell a prompt from a skill from an agent, learn RAG from scratch, drive the Playwright Agent CLI, understand why LLM evaluation is now a QA job, work safely in Cursor, and build your own skill directory you can reuse forever.

NotebookLM prep Prompt vs skill vs agent RAG basics Playwright CLI LLM evaluation Cursor Skill directory

NotebookLM is Google's source-grounded research notebook, powered by Gemini: it answers only from the sources you upload and cites them back. For interview prep that means answers built from your own resume, the real job description, and your project notes, not a chatbot's best guess.

What NotebookLM is and why grounding wins

Your sourcesJD, resume, notesNotebookLMone notebook per targetStudio outputscards, quiz, mind mapYou reviseand self-test
Every answer cites your own material, not the model's memory

Build your interview notebook

  1. Create one notebook per interview target. One company, one notebook: a focused source set keeps every answer about that role.
  2. Load QA-specific sources. Add the job description, the company engineering blog, your own resume, your project notes, and the STLC or testing docs you keep forgetting.
  3. Interrogate it in chat. Ask "which of my projects best matches the automation requirement in this JD" and follow the citations back to your own notes.
  4. Generate flashcards and a quiz. Flashcards for definitions (severity vs priority, regression vs retesting), then a quiz to self-test cold before the call.
  5. Generate a Mind Map to see gaps. Thin branches are the topics your sources barely cover: revise those first.
  6. Finish with an Audio Overview for commute revision. You get 3 per day on the free tier, so generate it after your source list is final: Deep Dive for full coverage, The Brief for a fast refresher.
Add JD and resumeChat withcitationsFlashcards andquizMind Map showsgapsAudio on thecommute
One notebook per interview target, five moves from sources to revision
Keep it honest. NotebookLM will not invent experience you do not have: use it to recall and structure what you actually did, never to fake projects, because every claim gets a follow-up question in the room.
Free tier limitWhat you get
Notebooks100 per account
Sources50 per notebook
Chat queries50 per day
Audio Overviews3 per day
Video Overviews and Deep ResearchLimited

Answering only from your own documents is the same idea RAG is built on: when you are ready to apply it to test generation, read the RAG tutorial for QA.

A prompt is what you type, a skill is what you save, an AI agent is the system that uses both. Knowing which rung you are on decides whether your AI testing work is a one-off or an asset your whole team reuses.

The ladder: prompt -> skill -> agent

Prompttyped each timeSkillsaved and versionedAgentplans, tools, loops
Each rung reuses the one below it

Promote a prompt into a skill

  1. Catch the repeat. The third time you type the same test-case prompt, stop: anything retyped is a skill candidate.
  2. Create the folder. Make a directory with a SKILL.md inside: YAML frontmatter on top, instructions below.
  3. Write the description for matching. The agent loads a skill only when the description matches the request, so name the exact situations it should fire in.
  4. Move the prompt body into the Markdown section. Your proven wording becomes the instructions the agent follows.
  5. Commit it to git. Now it is version controlled: reviewable in a pull request and shareable with the whole team.
  6. Let the agent drive. On a matching request the agent plans, calls tools, observes results, and loops until the goal is met, with your skill guiding it.
---
name: qa-test-case-writer
description: Generate test cases from a user story or requirement.
  Use when asked to write, expand, or review test cases.
---

Write test cases in Given/When/Then form.
Always cover happy path, negative, and boundary cases.
Plandecide the next moveCall toolsrun, read, editObserve resultswhat actually happenedGoal met?stop when yesnot yet, plan again
The agent loop, powered by your prompts and skills
Description is the trigger. A skill loads only when its description matches the request, so write it with the words a teammate would actually type: "write test cases", "review test cases", not clever prose.
ComparePromptSkillAI agent
Where it livesYour head or a notes fileA folder with SKILL.md, in gitThe system running the loop
ReuseZero guarantee, retyped each timeReusable, shareable, version controlledReuses prompts and skills below it
When it runsOnly when you type itWhen its description matches the requestPlans and loops until the goal is met

That is the short version: for worked examples of all three rungs, read the full breakdown, then start your own library with the skill masterclass.

RAG stops you from hoping the model memorised your product: it retrieves chunks from your own documents and pastes them into the prompt as context. For a tester, that is the difference between a test case you can trace to a spec and a confident guess you cannot.

What RAG actually is

Ingest docsspecs, bugsChunksplit into passagesEmbedtext to vectorsVector storesearchable bymeaningRetrievetop matching chunks
The answer is generated only from retrieved chunks, so every claim has a source

Build your first QA RAG, step by step

  1. Collect your sources. Gather the documents that define what correct looks like: specs, requirements, past bug reports. This is the ingest stage.
  2. Chunk them. Split each document into passages: small enough to be specific, big enough to keep their meaning intact.
  3. Embed every chunk. Run each chunk through an embedding model to get a vector of numbers. Similar meanings land close together in that vector space.
  4. Store the vectors. Load them into a vector database so they can be searched by similarity later.
  5. Ask and retrieve. Embed your question the same way, then retrieve the top matching chunks for it.
  6. Generate with receipts. Paste the retrieved chunks into the prompt and instruct the model to answer only from them, citing which chunk supports each claim.
SPEC CHUNK (retrieved from checkout-spec, section 4.2):
"An invalid promo code shows error PROMO-401 and
leaves the cart total unchanged."

QA QUESTION:
"What should happen when a user applies an invalid promo code?"

GROUNDED ANSWER:
Show error PROMO-401 and keep the cart total unchanged.
Source: checkout-spec, section 4.2.

DERIVED TEST CASE:
1. Add any item to the cart
2. Apply an invalid promo code
3. Assert error PROMO-401 is displayed
4. Assert the cart total did not change
Without RAGmodel guesses from memoryno citation to your spechallucination is invisibleWith RAGanswers from your chunksevery claim traceablegaps become visibleVS
Without RAG you get confidence, with RAG you get evidence
Trust rule. If the answer cites no chunk, it is unsupported. Treat an uncited claim from your RAG assistant like an untested code path: do not build a test case on it until you find the source it came from.

Go deeper with the QA-focused walkthrough at /ai/rag-tutorial-for-qa, then level up with the advanced build (Langflow, BGE-M3, Chroma, reranking) at /masterclass/advanced-rag.

The Playwright Agent CLI puts a real browser at the end of your terminal, built so an AI agent can drive it without drowning in raw HTML. Sessions, network inspection, route mocking, and tracing all live behind one binary: playwright-cli.

Why agents love this CLI

Raw DOM dumpthe whole page as textthousands of wasted tokensagent hunts for elementsRef-based snapshotstructure plus element refsact on a ref directlycheap and fast runsVS
The CLI hands the agent refs, not the whole page

Hands-on: your first session

  1. Install once. Run npm install -g @playwright/cli. This provides the playwright-cli binary.
  2. Check your setup. Print the resolved config with playwright-cli config so surprises surface now, not mid-run.
  3. Open a named session. Start a headed, isolated session against the practice cart: playwright-cli -s=cart open https://app.thetestingacademy.com/playwright/ttacart/ --headed.
  4. Watch the wire. Inspect what the page is calling with playwright-cli network, then mock or block the API layer with playwright-cli route "**/api/**".
  5. Record the evidence. Run playwright-cli tracing-start, drive the flow, then save it with playwright-cli tracing-stop trace.zip.
  6. Review and extend. Open the dashboard with playwright-cli show, and hand your agent the toolkit with playwright-cli install --skills.
npm install -g @playwright/cli
playwright-cli config
playwright-cli -s=cart open https://app.thetestingacademy.com/playwright/ttacart/ --headed
playwright-cli network
playwright-cli route "**/api/**"
playwright-cli tracing-start
# drive the flow in the browser
playwright-cli tracing-stop trace.zip
playwright-cli show
playwright-cli install --skills
tracing-startbegin recordingDrive the flowreproduce the bugtracing-stopsave trace.zipshowopen the dashboardfix, then run it again
The debug loop: record, replay, fix, repeat
Tracing is not retroactive. The trace only contains what happened after playwright-cli tracing-start. If the bug already happened, start tracing first, reproduce the flow again, then run playwright-cli tracing-stop trace.zip to capture it.

Every command above comes straight from the full walkthrough at /masterclass/playwright-cli: start there when you are ready to wire the CLI into a real agent workflow.

Your product just shipped a feature that writes its own output. assertEquals cannot grade a paragraph, so if you want to be the tester who signs off AI features, you need a new kind of assertion: the metric.

Why assertEquals cannot grade a paragraph

Classic testassert a == bone expected valueequality checks charactersLLM evaluationscore 0.87 vs 0.80a threshold you owna metric measures meaningVS
Equality grades characters, a metric measures a property against your threshold

The judge loop: your first eval

  1. Capture a real test case. Save the input, the retrieved context if the feature uses RAG, and the exact output the model produced.
  2. Pick one metric and its direction. Quality metrics like answer relevancy or faithfulness need a floor; safety metrics like hallucination or PII leakage need a ceiling.
  3. Choose a judge that is not the model under test. LLM-as-judge means a second, trusted model does the grading. The grader and the graded are never the same model, no exceptions.
  4. Score and collect the reason. The judge returns a score from 0 to 1 plus a written reason, so a failure tells you why it failed, not just that it failed.
  5. Assert against your threshold. DeepEval is pytest-native, so a metric that misses its threshold fails the build like any red test. PromptFoo and TruLens are the other two tools to know.
  6. Rerun on every change. New prompt, new model, new context source: run the suite again. That is regression testing for a feature that writes its own output.
Model under testwrites the answerJudge modela different modelScore plus reason0 to 1, in writingCompare thresholdfloor or ceilingPass or failthe build gate
The grader and the graded are never the same model
Metric familyExamplesThreshold acts asPass rule
Quality (higher is better)answer relevancy, faithfulness, contextual precision, contextual recall, contextual relevancy, custom G-Eval rubrics like correctnessFloorscore >= threshold
Safety (lower is better)hallucination, bias, toxicity, PII leakageCeilingscore <= threshold
Start with two metrics. Faithfulness with a floor and hallucination with a ceiling catch most early failures. Keep every threshold in version control: a sign-off you cannot diff is not a sign-off.

Evaluation is the only way to regression-test a feature that grades differently every run, and the tester who owns the metrics and thresholds is the one who signs off the AI feature. The full pytest setup, metric by metric, is in the DeepEval masterclass.

Cursor is an AI-first code editor, and for QA its value is bounded, reviewable agent work on your test repo. The discipline is short: rules first, one small task, deterministic verification before you accept a single diff.

The workflow: constrain before you trust

Project rules firstconventions written onceOne small taskpredictable diffAgent proposesa diff you readRun the suitegreen is the gatered? re-scope and go again
Green accepts the diff, red re-scopes the task, repeat mistakes become new rules

One bounded task, end to end

  1. Write project rules. Capture repo conventions as rules the agent must follow: selector strategy, folder layout, files that are off limits.
  2. Scope one small task. "Add a spec for the empty cart state" beats "improve coverage". If you cannot predict the shape of the diff, shrink the task.
  3. Pick the least-autonomous agent mode that works. Bounded agent modes exist so you choose the leash length: the goal is a proposed diff you review, not silent edits.
  4. Feed context deliberately. Use MCP when the task needs tools or data beyond the repo, and target your Playwright assets so the output lands in code your suite can check.
  5. Verify before accepting. Read the diff, then run the suite. Green is the acceptance gate. Red means reject or re-scope, never "accept and fix later".
  6. Add the second net. Use CLI review to inspect the work, let Bugbot run an automated review pass, and fold any repeated mistake into a new rule.
Cursor, in the editoragent proposes a diffyou read it line by linebest for scoped changesTerminal agentscripted headless runsgood for batch worksame code, no editorVS
Different surfaces, same gate: the suite must pass before you accept
PieceWhat it does for a tester
Project rulesStanding constraints applied to every task: your conventions in, your forbidden paths out
Bounded agent modesCap how much the agent may change on its own, so the output is a proposed diff, not a surprise merge
Playwright assetsPoint the agent at real test code, specs, page objects, fixtures, so your existing suite can verify its work
MCPConnects the agent to tools and data beyond the repo, so context comes from real systems instead of guesses
CLI reviewInspect the agent's work from the command line before anything lands
BugbotAutomated review pass over changes: a second reader, never a substitute for running the suite
Golden rule. If you cannot verify a diff by running the suite, the task was scoped too big: split it and go again. Never accept on the agent's word alone.

The full setup, from privacy-aware configuration to Bugbot, is in the Cursor masterclass, with the field lessons collected in the follow-up.

A skill directory is your personal library of SKILL.md folders: versioned in git, discovered by your agent, loaded only when a request matches. Prompts scattered across notes files die with the session; a directory gets reviewed, shared, and pulled like code.

A versioned library, not a pile of prompts

Always in contextname plus description, about 100 tokensOn matchthe SKILL.md body loadsOn demandreferences/ and scripts/ load
Progressive disclosure: dozens of skills cost almost nothing until one matches

Build and ship your first skill

  1. Create the folder. In your test repo run mkdir -p .claude/skills/flaky-test-triage: one folder per skill, named after the job it does.
  2. Write the frontmatter. Add a SKILL.md whose description carries the exact trigger phrases teammates type, like "flaky test" or "quarantine this spec". The agent matches requests against this text, so a vague description never fires.
  3. Keep the body small. Below the frontmatter, write short Markdown steps with exact commands and expected output. The body only loads on a match, and a tight body keeps the loaded context sharp.
  4. Split out heavy parts only when needed. Move long checklists into references/ and helper code into scripts/. They load only when a step points at them.
  5. Commit it. Run git add .claude/skills/ && git commit: the skill now has history, blame, and a reviewable diff.
  6. Let the team pull it. Teammates run git pull and their agent discovers the new skill automatically. Shipping a capability becomes a one-line changelog entry.
.claude/skills/
└── flaky-test-triage/
    ├── SKILL.md
    ├── references/
    │   └── quarantine-checklist.md
    └── scripts/
        └── rerun-failed.sh

# SKILL.md
---
name: flaky-test-triage
description: Triage a flaky Playwright test. Use when the user
  says "flaky test", "quarantine this spec", "passes on retry",
  or pastes an intermittent CI failure.
---

## Steps
1. Re-run the failing spec alone, then with the full suite.
2. Compare the failing trace against the last green run.
3. Quarantine with an owner and a ticket, never silently.
Create the folderWrite thedescriptionCommit to gitTeammates pullAgents discoverit
Distribution is just version control: one commit turns a private trick into a team capability
AgentDiscovery locationsWhat that means
Claude Code~/.claude/skills/ (personal) and .claude/skills/ (repo)Global library plus per-repo skills
GitHub Copilot.github/skills/ (repo) and ~/.copilot/skills/ (personal)Same pattern, Copilot's own paths
VS Code Copilotalso reads .claude/skills/One committed folder serves both agents
Hermes~/.hermes/skills/Your library travels across agents
Claude Code~/.claude/skills/ personal.claude/skills/ in the repoVS Code Copilot.github/skills/ and ~/.copilot/skills/also reads .claude/skills/VS
The interop win: one committed folder can serve both agents
Write the description like a matching rule. The description is the only part the agent always sees, so front-load the phrases a teammate would actually type and name the artifacts involved (spec, trace, CI log). If a skill never fires, fix the description before touching the body.

Do not start from zero: our ready-made 36-skill QA suite covers the STLC end to end and drops straight into your directory. Grab it at /masterclass/skill-masterclass.