[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71MSFZZA51HGXZAM3CCCH7P":3,"skill-same:01M71MSFZZA51HGXZAM3CCCH7P":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":14,"repositoryHtmlUrl":53,"repositoryHomepageUrl":6,"ownerHtmlUrl":54,"ownerBlogUrl":55,"ownerDescription":56,"updatedAt":57,"install":58,"resources":70},"01M71MSFZZA51HGXZAM3CCCH7P","principle-test-behavior-not-implementation",null,"Apply when you write, change, or keep a test. Call the code the way its users do and assert the result they observe against a literal expected value. If the test would still pass when every imported function returns undefined, rewrite the assertion or delete the test.","bbishdotdev\u002Fai-tools","bbishdotdev","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F5323528?v=4","01M71MHYW2Q0DVZA22Q79M8KER","Brenden Bishop","01M71MHYWSMQWFPGA8CBJYQANH",0,"MIT","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Fprinciple-test-behavior-not-implementation\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"principle test behavior not implementation","behavior","implementation","test","rewrite","when","apply","value","expected value","expected","true","you","keep","users","imported","call","do","Literal","observe","code","2026-11-10 10:56:23",false,"---\nname: principle-test-behavior-not-implementation\ndescription: \"Apply when you write, change, or keep a test. Call the code the way its users do and assert the result they observe against a literal expected value. If the test would still pass when every imported function returns undefined, rewrite the assertion or delete the test.\"\ndisable-model-invocation: true\n---\n\n# Test Behavior, Not Implementation\n\nA test calls the code the way its users do and asserts the result they observe against a literal expected value. A test that asserts which calls the code made, or restates a constant the code contains, does neither.\n\nThe check: before you keep a test, ask whether it would still pass if every function it imports returned `undefined`. If yes, it observes no behavior and cannot fail for a defect. Rewrite the assertion or delete the test.\n\n**Why:** A test that cannot fail for a defect costs CI time and review attention and catches nothing. A constant pin also fails when someone edits the constant or the prompt it restates, so it prevents that edit.\n\n**Five shapes that still pass when every imported function returns `undefined`:**\n\n- **Weak or no assertion.** No `expect`, or only `toBeDefined`, `toBeTruthy`, `not.toThrow`, `toBeInstanceOf`, `toBeGreaterThan(0)`.\n- **Mock or absence only.** Only `toHaveBeenCalled`, `not.toHaveBeenCalled`, `toBeUndefined`, `toEqual([])`, `toHaveLength(0)`, `not.toBe(wrongValue)`.\n- **Self-referential.** The expected value comes from the code under test: `expect(f(a)).toBe(f(a))`, `expect(parsed.url).toBe(buildUrl(...))`.\n- **Constant pin.** The assertion restates a hand-maintained constant, config default, table row, or prompt string: `expect(LIMITS.maxTools).toBe(8)`, `expect(PROMPT).toContain(\"You are\")`.\n- **Fixture asserts fixture.** The assertion reads data the test built or a value computed in `beforeEach`, and the subject never runs inside the body.\n\n**The fix:** call the subject inside the test body with one concrete input and assert the literal output or the observable effect, `expect(slugify(\"Hello, World!\")).toBe(\"hello-world\")`. For an absence, assert the presence on the other input in the same test. For a constant, test the mechanism that reads it with one input instead of restating the value. For a mock, assert the payload it received or the state after the call, not that it was called. When no such assertion exists, delete the test.\n\n**Keep** a test of a relation across a table's rows (a key present in two tables, a parent that exists), and a compile-time check in a `*.test-d.ts` file.\n","# Test Behavior, Not Implementation\n\nA test calls the code the way its users do and asserts the result they observe against a literal expected value. A test that asserts which calls the code made, or restates a constant the code contains, does neither.\n\nThe check: before you keep a test, ask whether it would still pass if every function it imports returned `undefined`. If yes, it observes no behavior and cannot fail for a defect. Rewrite the assertion or delete the test.\n\n**Why:** A test that cannot fail for a defect costs CI time and review attention and catches nothing. A constant pin also fails when someone edits the constant or the prompt it restates, so it prevents that edit.\n\n**Five shapes that still pass when every imported function returns `undefined`:**\n\n- **Weak or no assertion.** No `expect`, or only `toBeDefined`, `toBeTruthy`, `not.toThrow`, `toBeInstanceOf`, `toBeGreaterThan(0)`.\n- **Mock or absence only.** Only `toHaveBeenCalled`, `not.toHaveBeenCalled`, `toBeUndefined`, `toEqual([])`, `toHaveLength(0)`, `not.toBe(wrongValue)`.\n- **Self-referential.** The expected value comes from the code under test: `expect(f(a)).toBe(f(a))`, `expect(parsed.url).toBe(buildUrl(...))`.\n- **Constant pin.** The assertion restates a hand-maintained constant, config default, table row, or prompt string: `expect(LIMITS.maxTools).toBe(8)`, `expect(PROMPT).toContain(\"You are\")`.\n- **Fixture asserts fixture.** The assertion reads data the test built or a value computed in `beforeEach`, and the subject never runs inside the body.\n\n**The fix:** call the subject inside the test body with one concrete input and assert the literal output or the observable effect, `expect(slugify(\"Hello, World!\")).toBe(\"hello-world\")`. For an absence, assert the presence on the other input in the same test. For a constant, test the mechanism that reads it with one input instead of restating the value. For a mock, assert the payload it received or the state after the call, not that it was called. When no such assertion exists, delete the test.\n\n**Keep** a test of a relation across a table's rows (a key present in two tables, a parent that exists), and a compile-time check in a `*.test-d.ts` file.\n",{"name":5,"description":7,"disable-model-invocation":49},true,"main","e7c8126d1ad4df934236dba12521dcbe7fcd9d74","bstack\u002Fupstream\u002Fpstack\u002Fskills\u002Fprinciple-test-behavior-not-implementation","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools","https:\u002F\u002Fgithub.com\u002Fbbishdotdev","bbish.dev","Husband | Father | Technologist\r\nEngineering leader helping product and delivery teams use AI to build better systems, habits, and tools.","2026-11-11 11:13:39",{"source":8,"skillName":5,"commands":59,"prompt":69,"zipAvailable":49},[60,63,66],{"tool":61,"command":62},"npx","npx skills add bbishdotdev\u002Fai-tools --skill principle-test-behavior-not-implementation",{"tool":64,"command":65},"bunx","bunx skills add bbishdotdev\u002Fai-tools --skill principle-test-behavior-not-implementation",{"tool":67,"command":68},"pnpm","pnpm dlx skills add bbishdotdev\u002Fai-tools --skill principle-test-behavior-not-implementation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Fprinciple-test-behavior-not-implementation\u002FSKILL.md",[],[72,103,113,128,159,182],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":83,"publishedAt":44},"01M71MT5NBY3RY660EA06K9CA1","why","Use for 'why does X work this way', 'why we picked Y', design rationale, regressions, postmortems, or data-backed thresholds. Discovers available MCPs and queries each evidence category (source control, issue tracker, long-form docs, real-time chat, infrastructure observability, error tracking, product analytics warehouse) in parallel, then returns a cited read on decisions and tradeoffs. Use how for runtime behavior.","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Fwhy\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[74,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102],"how","parallel","observability","warehouse","returns","infrastructure","source","analytics","data","issue","read","tracker","product","work","design","product analytics","time","error tracking","error",{"skillNo":104,"name":105,"nameZh":6,"description":106,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":109,"publishedAt":44},"01M71MT4CFF7AK4TRV40P7ZZ30","unslop","Cut AI tells from any writing. Must always apply.","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Funslop\u002FSKILL.md",[],[105,110,34,111,30,112],"cut","ai tells","writing",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":44},"01M71MT37W015EGE0EB82JQYAM","typescript-best-practices","TypeScript best practices. Use when reading or editing any .ts or .tsx file.","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Ftypescript-best-practices\u002FSKILL.md",[],[120,121,122,123,124,29,125,126,34,127],"typescript","typescript best practices","best practices","use","tsx","editing","file","reading",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":143,"publishedAt":44},"01M71MT1092N34HQMGECW170JP","technical-writing","Layered technical-writing standard: Diátaxis structure, Google developer style sentences, STE instruction rules, Global English syntax. Use for \u002Ftechnical-writing or when writing or reviewing docs, RFCs, readmes, PR descriptions, or commit messages.","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Ftechnical-writing\u002FSKILL.md",[134,137,140],{"categoryNo":135,"categoryName":136,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":138,"categoryName":139,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000030","开发工程师",{"categoryNo":141,"categoryName":142,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000036","内容创作者",[144,112,145,146,147,148,149,150,151,152,29,153,154,123,34,155,130,156,157,158],"technical","technical writing","commit messages","google","syntax","style","structure","layered","english","commit","Rules","messages","for","pr","standard",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":168,"publishedAt":44},"01M71MSYRMT7KZPQFY7A2ZHGMB","teach","Explain a body of work plainly so a person actually understands it. Runs the `how` and `why` skills and weaves what they find into one clear explanation. Use for 'teach me this', 'help me really understand X', 'explain this change or subsystem to me'.","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Fteach\u002FSKILL.md",[165],{"categoryNo":166,"categoryName":167,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000039","教师与教育",[161,156,84,169,170,171,97,172,173,174,175,176,123,177,178,34,179,180,74,181],"me","explanation","change","help","one","it","explain","body","teach me","understand","clear","person","find",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":186,"categories":187,"keywords":188,"publishedAt":44},"01M71MSWTVAEVMZAG7SMWFE1FE","tdd","Use only when the user explicitly asks for TDD, a failing test, or a regression test, OR when the bug has an obvious cheap local test target. Skip when the test path is unclear, expensive, integration-heavy, or not requested.","https:\u002F\u002Fgithub.com\u002Fbbishdotdev\u002Fai-tools\u002Fblob\u002Fmain\u002Fbstack\u002Fupstream\u002Fpstack\u002Fskills\u002Ftdd\u002FSKILL.md",[],[184,123,189,190,191,29,192,34,193,194,195,196,197,156,198,27],"path","user","regression test","only","local","failing","bug","integration","regression","target"]