惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
C
Cisco Blogs
The Hacker News
The Hacker News
T
Tor Project blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The GitHub Blog
The GitHub Blog
A
Arctic Wolf
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Register - Security
The Register - Security
云风的 BLOG
云风的 BLOG
Simon Willison's Weblog
Simon Willison's Weblog
P
Palo Alto Networks Blog
Vercel News
Vercel News
C
CERT Recently Published Vulnerability Notes
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
M
MIT News - Artificial intelligence
I
Intezer
aimingoo的专栏
aimingoo的专栏
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LINUX DO - 热门话题
Microsoft Security Blog
Microsoft Security Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
P
Proofpoint News Feed
P
Proofpoint News Feed
B
Blog
T
Threat Research - Cisco Blogs
博客园 - 叶小钗
Recorded Future
Recorded Future
Last Week in AI
Last Week in AI
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
PCI Perspectives
PCI Perspectives
Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
Application and Cybersecurity Blog
Application and Cybersecurity Blog
MyScale Blog
MyScale Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Schneier on Security
Schneier on Security
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
H
Help Net Security
博客园 - 聂微东
H
Hackread – Cybersecurity News, Data Breaches, AI and More
G
GRAHAM CLULEY

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
AI-Powered Test Coverage Gap Analysis: How I Use Claude Code + gstack to Generate Test Cases
Demi Jiang · 2026-04-24 · via DEV Community

Every QA engineer knows the feeling: you're staring at a test suite that covers the happy path, maybe a few edge cases, and you have a nagging suspicion there's a whole category of scenarios nobody's thought to test. Writing those missing tests from scratch is slow, tedious, and mentally expensive. You're essentially doing product archaeology — reverse-engineering what the app actually does so you can describe it in test form.

I found a way to automate that archaeology. In a single session, I used Claude Code and a tool called gstack to navigate our live staging app, compare what it actually does against our existing Notion test cases, and generate 24 new BDD-formatted test cases — all exported directly back into Notion. Here's the exact workflow, including the prompts I used and the lessons I learned the hard way.


1. The Problem: Test Coverage Gaps Are Hard to Find Manually

Manual gap analysis is a two-step cognitive problem. First you have to deeply understand what the application does — every mode, every edge case, every permission flow. Then you have to hold that in your head while scanning a test case database and noticing what's missing. Neither step is easy. Both together are exhausting.

For any non-trivial feature, you'll have test cases for the happy path and maybe a few known edge cases. But what about different input types? State transitions that only happen under specific conditions? Browser-specific behaviors? Permission flows? You often don't know what's missing until something breaks in production.

The approach I'd been using — read the test suite, open the app, click around, write notes — doesn't scale. What I needed was a way to have the analysis done for me, with the application as the source of truth rather than my memory of it.


2. The Tools: Claude Code, Notion MCP, and gstack

Before diving into the workflow, here's what each tool actually does.

Claude Code is Anthropic's CLI for Claude. You run it from your terminal or VS Code and interact with it conversationally. It can execute bash commands, read and write files, call external APIs, and — crucially for this workflow — use MCP servers to connect to external tools.

Notion MCP is a Model Context Protocol server that lets Claude read and write Notion pages directly. Once configured, you can tell Claude to fetch a Notion page, read its content, and write new pages back — all from a single conversation.

gstack is an open-source tool that gives Claude a headless browser. It exposes three skills:

Skill What it does Fixes bugs?
/browse Navigate a URL, interact with the UI, take screenshots, verify specific flows No — exploration only
/qa-only Systematic QA sweep of the whole app — structured report, health score, repro steps, screenshots No — report only
/qa Same as /qa-only, plus iteratively patches bugs in source code, commits each fix, re-verifies Yes — fixes and commits

For this workflow I used /browse — I wanted exploration and screenshots, not code changes.


3. Setup: Getting Everything Connected

Install Claude Code from the Anthropic CLI docs. You can use it from the terminal or the VS Code extension. I used both — VS Code for reviewing output, terminal for running prompts.

Configure Notion MCP by editing ~/.claude.json:

{
  "mcpServers": {
    "notion": {
      "type": "http",
      "url": "https://mcp.notion.com/mcp"
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

You'll also need to authorize the Notion integration from your Notion workspace settings and give it access to the relevant pages. Claude will automatically pick up the MCP config on next launch.

Install gstack following the instructions in its repo. Once installed, the /browse, /qa-only, and /qa skills become available inside Claude Code sessions.

⚠️ Set your permission mode. By default, Claude Code asks for approval before running commands or making changes. For this kind of exploratory session, constant approval prompts break your flow. Set the permission mode to acceptEdits so Claude can run freely. Be aware of what this means — you're giving it latitude to make changes, so use it in a sandboxed or read-only context where possible.

Why this matters for QA: The setup cost here is low — maybe 20 minutes including Notion authorization. The payoff is a reusable pipeline. Once it's configured, every future gap analysis session starts from step one with no additional setup.


4. The Workflow: Six Prompts, One Session

Here's the complete workflow:

┌─────────────────────────────────────────────────────────────┐
│                    GAP ANALYSIS WORKFLOW                     │
└─────────────────────────────────────────────────────────────┘

  [Notion DB]          [Live App]           [Notion DB]
      │                    │                     │
      ▼                    ▼                     │
  ┌────────┐         ┌──────────┐                │
  │ Step 1 │         │ Step 2   │                │
  │  Read  │         │ Explore  │                │
  │existing│         │  app via │                │
  │  TCs   │         │  gstack  │                │
  └────┬───┘         └────┬─────┘                │
       │                  │                      │
       └────────┬──────────┘                     │
                ▼                                │
           ┌────────┐                            │
           │ Step 3 │                            │
           │Compare │                            │
           │& find  │                            │
           │  gaps  │                            │
           └────┬───┘                            │
                ▼                                │
           ┌────────┐                            │
           │ Step 4 │                            │
           │ Draft  │                            │
           │  new   │                            │
           │  TCs   │                            │
           └────┬───┘                            │
                ▼                                │
           ┌────────┐                            │
           │ Step 5 │                            │
           │Refine  │                            │
           │to BDD  │                            │
           │format  │                            │
           └────┬───┘                            │
                ▼                                ▼
           ┌────────┐                       ┌────────┐
           │ Step 6 │──────────────────────▶│ New TC │
           │ Export │                       │ pages  │
           │to Notion│                      │in DB   │
           └────────┘                       └────────┘

Enter fullscreen mode Exit fullscreen mode

Step 1 — Read Existing Test Cases from Notion

Fetch this Notion page and list all existing test cases with their names
and a one-line summary of what each one covers:
[your Notion test case database URL]

Enter fullscreen mode Exit fullscreen mode

Claude fetches the Notion database, reads each page, and produces a structured list: test case name, what it covers. This becomes the baseline for the gap analysis.

💡 Include the full URL in your prompt every time. Don't say "the Notion page from earlier" or "the test database we discussed." Across tool calls and session boundaries, Claude needs explicit references. Paste the full URL in every prompt that references a Notion page.

Step 2 — Explore the App and Understand What It Does

Browse [your staging app URL]
Login with username [test-account] password [password]
Put the entire login and exploration in one bash script so the browser
session stays alive.
Take screenshots of each part of [the feature] and summarise how it works.

Enter fullscreen mode Exit fullscreen mode

This is where gstack does the heavy lifting. Claude uses the /browse skill to launch a headless browser, log in, navigate through every state of the feature, take screenshots, and come back with a written summary of how it all works.

⚠️ Put login and exploration in a single bash script. This is the most important gotcha in the whole workflow. The gstack browser server restarts between separate bash calls, which kills all browser state — including your login session. If you run login in one call and exploration in the next, Claude will be looking at a logged-out app. Combine everything into one script.

What you get back is a detailed summary of every state the feature can be in: what controls are visible, what actions are available, what happens when you submit or cancel, and screenshots of each screen. Claude understands the feature better after two minutes of headless browsing than you could communicate with a paragraph of description.

Why this matters for QA: The app is the source of truth, not documentation or memory. When Claude explores the live app, it sees what users see — including states that might not be documented anywhere.

Step 3 — Compare Against Existing Tests and Find Gaps

Compare the feature you just explored against the existing test cases listed earlier.
Identify gaps — features or scenarios with no test coverage.
Group by area (e.g. different input types, error states, permissions,
edge cases, browser-specific behaviour).

Enter fullscreen mode Exit fullscreen mode

Claude now has both sides: what the app does (from exploration) and what's already tested (from Notion). It produces a gap analysis grouped by area, surfacing scenarios that hadn't been explicitly tested — different input variations, specific error and timeout states, permission-related flows, and behavior under degraded conditions.

This took about 30 seconds.

Step 4 — Draft New Test Cases (Without Writing to Notion Yet)

Please create new test case entries for each gap you identified.
Do NOT write directly to Notion yet — show me the drafts first.

Enter fullscreen mode Exit fullscreen mode

⚠️ Always review before writing to Notion. Notion changes cannot be reverted through Claude. If you let it write directly and the output is wrong — wrong format, wrong numbering, duplicate entries — you're cleaning up manually. The "show me the drafts first" step is non-negotiable.

Claude generates a draft for each gap: a title, a brief description, and rough test steps. At this point the format isn't quite right yet, but the content is there.

Step 5 — Refine to Match Your BDD Format

Can you follow the same format I have here:
[URL of an existing well-formatted test case as a reference]

Rewrite all the draft test cases using that exact format:
Feature block with user story, Background, Scenario with Given/When/Then steps,
Execution Steps checklist, and Notes/Bug Link section.
Number them starting from [next available number].
Still do NOT write to Notion yet.

Enter fullscreen mode Exit fullscreen mode

I pointed Claude at an existing test case as the template and asked it to rewrite all drafts to match — Feature block, Background, Scenario, Given/When/Then, Execution Steps checklist, Notes/Bug Link. I also specified the starting test case number so the new ones numbered sequentially from where the existing ones left off.

This step is worth taking seriously. A test case that's technically correct but formatted wrong creates work for whoever has to use it. Getting the format right before export means the output is immediately usable.

Step 6 — Export to Notion

Write all the new test cases to Notion.
Create each one as a new page inside [your database name]
using the same format as the existing entries.

Enter fullscreen mode Exit fullscreen mode

Claude uses the Notion MCP to create each test case as a new page in the database, including the full BDD content block and page properties: Case Type, Priority, Status.

Why this matters for QA: The output lands directly in the tool your team already uses. No copy-pasting, no reformatting, no "I'll add this to Notion later." It's there.


5. The Prompts as a Reusable Template

Here's the complete sequence you can adapt for your own app and test database:

# Step 1 — Read existing test cases
Fetch this Notion page and list all existing test cases with their names
and a one-line summary of what each one covers:
[your Notion test case database URL]

# Step 2 — Explore the app
Browse [your staging app URL]
Login with username [test-account] password [password]
Put the entire login and exploration in one bash script so the browser
session stays alive.
Take screenshots of each part of [the feature] and summarise how it works.

# Step 3 — Gap analysis
Compare the feature you just explored against the existing test cases listed earlier.
Identify gaps — features or scenarios with no test coverage.
Group by area.

# Step 4 — Draft
Please create new test case entries for each gap you identified.
Do NOT write directly to Notion yet — show me the drafts first.

# Step 5 — Format
Can you follow the same format I have here:
[URL of an existing well-formatted test case]
Rewrite all the draft test cases using that exact format.
Number them starting from [TC-XX].
Still do NOT write to Notion yet.

# Step 6 — Export
Write all the new test cases to Notion.
Create each one as a new page inside [your database]
using the same format as the existing entries.

Enter fullscreen mode Exit fullscreen mode


6. Gotchas and Lessons Learned

These aren't theoretical — each one cost me time before I figured it out.

1. One bash script for login + exploration. The gstack browser server restarts between separate bash invocations. Combine login and exploration into a single script.

2. Always use explicit URLs. Vague references like "the page from before" break across tool calls and context boundaries. Include the full URL in every prompt that references a Notion page.

3. Review drafts before writing to Notion. Notion write operations through Claude are not reversible via Claude. The "show me first" step is cheap insurance.

4. Set acceptEdits permission mode for exploration sessions. Constant approval prompts fragment the session. Set it for exploration, but be aware of what you're enabling.

5. Save reusable prompts as custom skills. Claude Code supports custom skills — markdown files in ~/.claude/skills/. If you run gap analyses regularly, turn the prompt sequence into a skill so you invoke it with one command instead of retyping a paragraph.

6. Use a dedicated test account. Your credentials go into a prompt that Claude executes. Don't use your personal account.


7. Results

One session. Here's what came out of it:

  • 24 new test cases generated in a single session
  • All formatted correctly: Feature block, Background, Scenario, Given/When/Then, Execution Steps checklist, Notes section
  • All written as new pages in the Notion database with correct properties (Case Type, Priority, Status)
  • Coverage gaps closed across multiple areas that hadn't been explicitly tested before

Before this session, gap analysis for a feature this size would have taken me half a day. The session itself took about 45 minutes, most of which was reviewing the drafts at steps 4 and 5. The test cases needed minor tweaks — a few Given steps needed more context, one When step was slightly off — but the heavy lifting was done. I was editing, not authoring from scratch.


8. What Else You Can Do With This Approach

The six-step workflow is one combination. The underlying capability is more flexible.

Requirements-first: Instead of exploring the app, feed Claude your requirements doc or spec. "Here are the acceptance criteria. Here are the existing test cases. What scenarios aren't covered?" This works well for features that aren't built yet.

Code-first: Point Claude at the codebase and ask it to surface untested paths. "Here's the source code for this feature. Here are the existing test cases. What code paths have no test coverage?" This gets you into edge cases that are invisible from the UI.

All three combined: The most complete analysis uses all three inputs simultaneously — what the spec says the app should do, what the app actually does, and what the code does under the hood.

Scheduled gap analysis: Once the workflow is stable, run it on a cadence — every sprint, every release. A fresh gap analysis against a growing test suite catches regression in coverage: features that expanded but whose tests didn't.


Conclusion

Test coverage gaps exist because comparing "what the app does" against "what we've tested" is cognitively expensive. AI is good at exactly that kind of comparison when you give it the right inputs.

The workflow I described gives it those inputs systematically: read the existing tests, explore the live app, find the delta, draft the missing coverage, format it correctly, write it back. Each step is mechanical. The judgment calls — are these test cases accurate? are the priorities right? — still belong to you. But the archaeology is automated.

24 test cases in one session. That's the headline. The more important number is how many more sessions like this I can run without burning out on the manual version.


References