{"id":3001,"date":"2025-08-03T10:12:35","date_gmt":"2025-08-03T09:12:35","guid":{"rendered":"https:\/\/contentlabstudy.com\/soft\/?p=3001"},"modified":"2026-09-24T21:16:47","modified_gmt":"2026-09-24T20:16:47","slug":"behavior-driven-development-bdd","status":"publish","type":"post","link":"https:\/\/contentlabstudy.com\/soft\/behavior-driven-development-bdd\/","title":{"rendered":"Behavior-Driven Development (BDD)"},"content":{"rendered":"<p><strong>Behavior-driven development<\/strong> is TDD with a shared language for <em>behavior<\/em>: Given\u2013When\u2013Then examples that business and engineering can both read. The automation is optional but valuable; a Gherkin file nobody runs is a wiki. BDD is not \u201cwe bought Cucumber.\u201d<\/p>\n<h2>The useful core<\/h2>\n<ul>\n<li><strong>Example mapping<\/strong> (or a three-amigos chat): one rule, several examples, one question you still cannot answer \u2014 that question is the work.<\/li>\n<li><strong>Ubiquitous language<\/strong> for the slice, same words in the ticket, the test title, and the code. This is the overlap with <a href=\"\/soft\/domain-driven-design-principles\/\">DDD<\/a>.<\/li>\n<li><strong>Given\u2013When\u2013Then:<\/strong> context, action, observable outcome. No UI clicks in the When if the behavior is \u201cfunds moved.\u201d<\/li>\n<\/ul>\n<pre><code>Given an account with balance 40 USD\nWhen the holder transfers 20 USD to a valid payee\nThen the balance is 20 USD and a TransferCompleted event is recorded\n<\/code><\/pre>\n<p>That example should fail for the same reason in an API test or a domain unit test. If it only exists as a Selenium click-path, you coupled the rule to the DOM.<\/p>\n<pre><code>sealed class Account\n{\n    public decimal Balance { get; private set; }\n    public List&lt;string&gt; Events { get; } = new();\n    public static Account FromBalance(decimal balance) =&gt; new() { Balance = balance };\n\n    public void Transfer(decimal amount, string payee)\n    {\n        if (amount &gt; Balance)\n            throw new InvalidOperationException(\"insufficient\");\n        Balance -= amount;\n        Events.Add(\"TransferCompleted\");\n    }\n}\n\nstatic void TransferOf20From40Leaves20AndRecordsTheEvent()\n{\n    var account = Account.FromBalance(40m);\n    account.Transfer(20m, \"payee-1\");\n    if (account.Balance != 20m || account.Events[^1] != \"TransferCompleted\")\n        throw new Exception(\"the example failed\");\n}<\/code><\/pre>\n<h2>When BDD pays<\/h2>\n<p>Ambiguous product rules, many stakeholders, acceptance that must survive a rewrite of the UI. When it does not: a one-line bugfix, a spike, a system with no human to share the language.<\/p>\n<h2>What breaks it<\/h2>\n<p>The step clicks a CSS class. That is an end-to-end script. Run the Given\/When\/Then above against <code>Account.Transfer<\/code> or the API.<\/p>\n<pre><code>When I click div.btn-primary\nThen I should see the word success<\/code><\/pre>\n<h2>Pitfalls<\/h2>\n<ul>\n<li>Step soup: <code>When I click div.btn-primary<\/code> \u2014 that is an E2E script in costume.<\/li>\n<li>Duplicating the same rule in Gherkin and in a unit test that both break together.<\/li>\n<li>BDD as a QA-only afterthought once the code is frozen.<\/li>\n<\/ul>\n<p>Inner loop: <a href=\"\/soft\/tdd-test-driven-development\/\">TDD<\/a>. Outer journeys: <a href=\"\/soft\/e2e-test-frameworks\/\">E2E<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Behavior-driven development is TDD with a shared language for behavior: Given\u2013When\u2013Then examples that business and engineering can both read. The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"0","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[3],"tags":[],"class_list":["post-3001","post","type-post","status-publish","format-standard","hentry","category-software-development"],"_links":{"self":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts\/3001","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/comments?post=3001"}],"version-history":[{"count":5,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts\/3001\/revisions"}],"predecessor-version":[{"id":3258,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts\/3001\/revisions\/3258"}],"wp:attachment":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/media?parent=3001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/categories?post=3001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/tags?post=3001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}