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

推荐订阅源

O
OpenAI News
I
Intezer
C
CERT Recently Published Vulnerability Notes
V
Vulnerabilities – Threatpost
S
Securelist
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
P
Palo Alto Networks Blog
P
Privacy & Cybersecurity Law Blog
T
Tenable Blog
T
Threatpost
Latest news
Latest news
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
罗磊的独立博客
云风的 BLOG
云风的 BLOG
L
LangChain Blog
博客园 - 【当耐特】
P
Privacy International News Feed
The GitHub Blog
The GitHub Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
www.infosecurity-magazine.com
www.infosecurity-magazine.com
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
量子位
Security Archives - TechRepublic
Security Archives - TechRepublic
爱范儿
爱范儿
S
Security @ Cisco Blogs
Martin Fowler
Martin Fowler
博客园_首页
SecWiki News
SecWiki News
Spread Privacy
Spread Privacy
I
InfoQ
博客园 - 司徒正美
T
Tor Project blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Help Net Security
L
LINUX DO - 最新话题
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Vercel News
Vercel News
Y
Y Combinator Blog
D
DataBreaches.Net
T
Threat Research - Cisco Blogs
Stack Overflow Blog
Stack Overflow Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
M
MIT News - Artificial intelligence
Recorded Future
Recorded Future
博客园 - 叶小钗

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
3 Things Nobody Tells You About BDD Before Your Cucumber Suite Becomes a Maintenance Nightmare
Anand Pawar · 2026-06-21 · via DEV Community

You have six years of automation experience and a Cucumber suite that takes forty minutes to run, and you still can't tell me what a single feature file actually tests without reading three layers of glue code.

I've been there. You're the senior automation engineer on a team that adopted BDD because "business stakeholders need to read the tests." Except those stakeholders stopped reading them after sprint two. Now you're maintaining a suite where every scenario is a small novel, every step definition calls three other step definitions, and the person who wrote the original framework left the company eighteen months ago.

Here's what nobody tells you about BDD before your Cucumber suite becomes a maintenance nightmare.

Thing One: Gherkin Is Not a Programming Language, But You're Treating It Like One

Your feature files look like this:

Scenario: User completes checkout with valid payment
  Given the user is logged in with email "test@example.com" and password "Password123!"
  And the user has 3 items in their cart
  And the user's shipping address is "123 Main St, Springfield, IL 62701"
  And the user's billing address matches their shipping address
  When the user selects "Credit Card" as payment method
  And the user enters card number "4111111111111111"
  And the user enters expiry date "12/28"
  And the user enters CVV "123"
  And the user clicks "Place Order"
  Then the order confirmation page is displayed
  And the order number is shown
  And the user receives an email confirmation

This is not BDD. This is a test script written in a markup language that happens to parse into Cucumber.

The original promise of BDD was that scenarios describe behavior, not implementation. But somewhere along the way, teams started treating Gherkin as a readable scripting language. Every parameter gets inlined. Every step becomes a concrete action. The feature file becomes a play-by-play of the UI interaction.

The result? When the checkout flow changes — and it will — you have to update every scenario that touches checkout. Not the step definitions. The feature files themselves. Because the business logic is embedded in the Gherkin, not abstracted behind it.

Here's what a better version looks like:

Scenario: User completes checkout with valid payment
  Given the user has items ready to purchase
  When the user pays with a valid credit card
  Then the order is confirmed

That's it. Three lines. The "how" lives in the step definition. The "what" lives in the feature file. When the payment provider changes, you update one step definition, not twenty scenarios.

Your step definition file should be the place where complexity lives. Your feature files should be so simple that a product manager could read them in a standup and nod along. If your Gherkin looks like a test script, you've already lost.

Thing Two: Your Step Definitions Are a Dependency Graph, Not a Library

Here's the pattern I see in every struggling Cucumber suite:

// step_definitions/checkout_steps.ts
import { Given, When, Then } from '@cucumber/cucumber';
import { loginAsUser } from './auth_steps';
import { addItemsToCart } from './cart_steps';
import { fillShippingAddress } from './shipping_steps';

Given('the user has items ready to purchase', async function () {
  await loginAsUser.call(this, 'test@example.com', 'Password123!');
  await addItemsToCart.call(this, 3);
  await fillShippingAddress.call(this, '123 Main St');
});

This is a dependency graph masquerading as a test framework. Every step definition imports other step definitions. The call order matters. The shared this context accumulates state across steps. If one step fails, the entire scenario is poisoned, and you can't tell whether the failure is in the step that failed or in the accumulated state from the three steps before it.

The counterargument: "But we need to reuse steps across scenarios. That's the whole point of BDD."

I agree with reuse. I disagree with how you're doing it.

The fix is to separate your page objects or service clients from your step definitions entirely. Your step definitions should be thin wrappers that call a shared domain layer. Not other step definitions.

// domain/checkout.ts
export class CheckoutFlow {
  constructor(private page: Page) {}

  async prepareItemsForPurchase(): Promise<void> {
    await this.page.goto('/login');
    await this.page.fill('#email', 'test@example.com');
    await this.page.fill('#password', 'Password123!');
    await this.page.click('#login-button');
    await this.page.waitForURL('/dashboard');
    // ... add items, set address
  }

  async payWithCreditCard(): Promise<void> {
    await this.page.click('#credit-card-option');
    await this.page.fill('#card-number', '4111111111111111');
    await this.page.click('#place-order');
  }
}

// step_definitions/checkout_steps.ts
import { CheckoutFlow } from '../domain/checkout';

Given('the user has items ready to purchase', async function () {
  this.checkout = new CheckoutFlow(this.page);
  await this.checkout.prepareItemsForPurchase();
});

When('the user pays with a valid credit card', async function () {
  await this.checkout.payWithCreditCard();
});

Now your step definitions are stateless. They don't import each other. They don't share mutable context. Each step creates or calls a domain object that encapsulates the behavior. If a step fails, the failure is isolated to that step's domain operation.

Your step definition file becomes a routing table, not a tangled web of imports. You can delete a step definition without worrying about breaking three other scenarios that depend on it.

Thing Three: Your Cucumber Suite Is a Documentation Project That You're Treating as a Test Project

This is the one nobody wants to say out loud.

BDD was never primarily about testing. It was about communication. The original vision was that scenarios would serve as living documentation — a shared language between developers, testers, and business stakeholders. The tests were a side effect.

But somewhere in the last decade, teams started measuring BDD success by test coverage. "We have 500 Cucumber scenarios." "Our BDD suite runs in CI." "We achieved 90% Gherkin coverage."

None of those metrics tell you whether your scenarios are readable. None of them tell you whether a new team member can open a feature file and understand what the system does without running the tests.

Here's the uncomfortable truth: if your Cucumber suite is a maintenance nightmare, it's because you optimized for the wrong thing. You optimized for test execution speed, for step reuse, for parameterization. You forgot to optimize for reading.

I learned this the hard way. I had a suite with beautiful step definitions. Clean abstractions. Zero duplication. But when a product manager asked me what the checkout flow looked like, I had to open three feature files and trace through five scenario outlines to explain it. The documentation was technically there, but it was useless.

The fix is brutal but simple: every time you add a scenario, ask yourself whether someone who has never seen your codebase can understand it in under thirty seconds. If the answer is no, rewrite the scenario. Not the step definition. The scenario.

Your feature files should be the first thing a new engineer reads when they join your team. Not the README. Not the wiki. The feature files. If they can't understand the system from those files alone, your BDD suite has failed its primary purpose.

What to Do Tomorrow

Pick one feature file. The worst one. The one with the most steps, the most parameters, the most inline data.

Rewrite it to three to five lines per scenario. Move every concrete value into a step definition or a test data factory. Delete every step definition that imports another step definition. Replace them with domain objects.

Run the suite. If it passes, you've just made your documentation better and your tests more maintainable in one move.

Then do it again for the next file.

A Question for You

Your Cucumber suite runs in CI. It passes. Your team is shipping. But if you had to explain the system's behavior to a new hire using only your feature files, could you do it in under five minutes?

If the answer is no, you know where to start.