تولیدکننده موارد آزمون که باگهایی را مییابد که تستهای مسیر شاد شما از دست میدهند

Why this prompt matters
Untested edge cases in pricing logic are exactly the kind of bug that reaches production silently and gets discovered when a customer gets charged $0 or a discount stacks incorrectly. A 2024 industry survey found that logic errors in boundary conditions account for a disproportionate share of production incidents precisely because they pass casual manual testing but fail on the exact inputs automated tests are designed to catch.
What we use it for
You just wrote a pricing function for checkout and need a real test suite before it ships, but you have 15 minutes before a deploy window and writing every edge case by hand from scratch would take an hour.
Prompt
Act as a senior QA engineer and test architect with deep experience in [LANGUAGE/FRAMEWORK, e.g. "Python with pytest" or "TypeScript with Jest"]. CONTEXT: Function or feature to test: [PASTE YOUR FUNCTION, CLASS, OR FEATURE DESCRIPTION HERE] What it's supposed to do: [ONE-SENTENCE DESCRIPTION OF THE INTENDED BEHAVIOR] Inputs it receives: [LIST THE PARAMETERS/INPUTS AND THEIR EXPECTED TYPES OR RANGES] Known constraints or business rules: [ANY VALIDATION RULES, RATE LIMITS, OR EDGE CONDITIONS YOU ALREADY KNOW ABOUT] TASK: Generate a comprehensive test suite for this function/feature. Cover four distinct categories of tests: 1. Happy path — normal, expected inputs that should succeed 2. Edge cases — boundary values, empty inputs, maximum/minimum values, unusual-but-valid inputs 3. Error scenarios — invalid inputs, malformed data, and how the function should fail (specific exception types, error codes, or return values) 4. Integration considerations — if this function interacts with external systems (database, API, file system), list what should be mocked and why CONSTRAINTS: - Use the testing framework and idioms specified in the context — do not default to a generic framework - Every test must have a descriptive name that states what it verifies, not just "test1", "test2" - For each test, include a one-line comment explaining WHY that case matters, not just what it checks - Do not generate redundant tests that check the same logical branch twice under different names - Flag any case where you're uncertain about the correct expected behavior rather than guessing silently — mark it with a `# VERIFY:` comment OUTPUT FORMAT: 1. **Test Suite** — complete, runnable test code in the specified framework 2. **Coverage Summary** — a short table listing each test, its category (happy path/edge/error/integration), and what specific risk it catches 3. **Gaps I Couldn't Cover** — a list of scenarios that need clarification from the developer before a test can be written (ambiguous requirements, undocumented behavior, etc.)
Result
Input context: Python function `apply_discount(price: float, discount_pct: float, min_price: float = 0.01) -> float` that applies a percentage discount to a price, but never lets the result drop below `min_price`. Framework: pytest.
1. Test Suite (excerpt):
def test_applies_standard_discount_correctly():
# Verifies the core discount math works for a typical case
assert apply_discount(100.0, 20.0) == 80.0
def test_zero_discount_returns_original_price():
# Edge case: 0% discount should be a no-op, not an error
assert apply_discount(50.0, 0.0) == 50.0
def test_full_discount_respects_minimum_price_floor():
# Edge case: 100% discount would give $0, but min_price floor must apply
assert apply_discount(50.0, 100.0, min_price=1.0) == 1.0
def test_negative_discount_raises_value_error():
# Error case: a negative discount is a business-logic violation, not a valid input
with pytest.raises(ValueError):
apply_discount(50.0, -10.0)
def test_discount_over_100_percent_raises_value_error():
# Error case: discounts above 100% are nonsensical and should be rejected explicitly
with pytest.raises(ValueError):
apply_discount(50.0, 150.0)
def test_negative_price_raises_value_error():
# Error case: negative prices should never reach this function, but defend anyway
with pytest.raises(ValueError):
apply_discount(-10.0, 20.0)
def test_very_small_price_with_discount_stays_above_minimum():
# Edge case: floating point rounding near the min_price boundary
result = apply_discount(0.02, 50.0, min_price=0.01)
assert result >= 0.01
2. Coverage Summary:
| Test | Category | Risk It Catches |
|---|---|---|
| test_applies_standard_discount_correctly | Happy path | Core math is wrong |
| test_zero_discount_returns_original_price | Edge case | Off-by-one logic breaks the no-discount case |
| test_full_discount_respects_minimum_price_floor | Edge case | Price floor silently ignored, allowing $0 sales |
| test_negative_discount_raises_value_error | Error | Invalid input silently accepted, inflating price instead of erroring |
| test_discount_over_100_percent_raises_value_error | Error | Negative resulting price before floor is applied |
| test_negative_price_raises_value_error | Error | Garbage input from an upstream bug propagates silently |
| test_very_small_price_with_discount_stays_above_minimum | Edge case | Floating point rounding pushes result just under the floor |
3. Gaps I Couldn't Cover:
- # VERIFY: Should `discount_pct=100` exactly (not over) be allowed, or does it also need special handling? The spec doesn't say if 100% is a valid edge or an error.
- No information given on whether `price` and `discount_pct` should accept `None` — worth clarifying if this function is called from user input directly.
- Currency rounding behavior (2 decimal places vs raw float) isn't specified — this affects several boundary test assertions and should be confirmed before merging.
بیشتر توسعهدهندگان برای مواردی تست مینویسند که از قبل به آنها فکر کردهاند، که یعنی تستها عمدتاً چیزی را تأیید میکنند که توسعهدهنده از قبل باور داشته، نه اینکه آنچه را از قلم انداخته آشکار کنند. شکاف میان «کد من از تستهایم عبور میکند» و «کد من واقعاً درست است» تقریباً بهطور کامل در مواردی زندگی میکند که هیچکس فکر نکرده آنها را بنویسد. این پرامپت مشخصاً برای شکار در آن شکاف ساخته شده است.
چرا چهار دسته بهجای صرفاً «تست بنویس»
یک پرامپت ساده «برای این تابع تست واحد بنویس» بهطور قابلاعتمادی تستهای مسیر شاد و شاید یک مورد خطای واضح تولید میکند، چون این مسیر کممقاومتترین برای هر نویسندهای است — چه انسان چه مدل. اجبار به چهار دسته صریح — مسیر شاد، موارد مرزی، سناریوهای خطا، ملاحظات یکپارچگی — الگوی جستوجو را تغییر میدهد. موارد مرزی مشخصاً مدل را وادار میکند درباره حدود فکر کند: صفر، منفی، حداکثر، خالی، تهی. سناریوهای خطا آن را وادار میکند فکر کند چه چیزی باید با صدای بلند شکست بخورد نه بهآرامی — جایی که پرهزینهترین باگها تمایل دارند پنهان شوند. ملاحظات یکپارچگی آن دسته از باگ را میگیرد که فقط وقتی ظاهر میشود که وابستگی شبیهسازیشده یک تابع متفاوت از تولید رفتار کند.
چرا این پرامپت روی هر تست یک کامنت «چرا» میخواهد
مجموعه تستی با پنجاه تست و بدون توضیح اینکه هرکدام در برابر چه چیزی محافظت میکند، تقریباً بهاندازه نبود تست دشوار نگهداری است — شش ماه بعد، هیچکس نمیداند یک تست حیاتی است یا زائد. الزام یک توجیه یکخطی روی هر تست، مجموعه را به مستندسازی حالتهای شکست واقعی تابع تبدیل میکند، که هر بار کسی بعداً آن کد را لمس کند و نیاز داشته باشد بداند چه چیزی ممکن است بشکند، سودمند واقع میشود.
چرا «شکافهایی که نتوانستم پوشش دهم» ارزشمندترین بخش است
بیشتر پرامپتهای تولید تست در کد تست متوقف میشوند. این یکی عمداً اینطور نیست، چون یک مدل هوش مصنوعی که برای تابعی که کاملاً درک نمیکند تست تولید میکند، گاهی بهجای علامتگذاری ابهام، رفتار مورد نظر را حدس میزند — و یک حدس غلط که در یک تست موفق پخته شده بدتر از نبود تست است، چون اعتماد کاذب ایجاد میکند. دستورالعمل صریح برای علامتگذاری عدمقطعیت با کامنت `# VERIFY:`، بههمراه بخش خروجی اختصاصی که سؤالات حلنشده را فهرست میکند، حدسزدن خاموش را به فهرستی صریح تبدیل میکند که یک توسعهدهنده میتواند در دو دقیقه پیش از ادغام حل کند.
چگونه آن را تطبیق دهیم
این پرامپت از نظر طراحی مستقل از فریمورک است — فیلد زبان/فریمورک را جایگزین کنید و مدل از pytest، Jest، JUnit، RSpec یا هرچه مشخص کنید استفاده خواهد کرد، به شرطی که آن را صریحاً نام ببرید نه اینکه ضمنی بگذارید. برای کد قدیمی بدون تست موجود، تابع را همراه با هر نقطه فراخوانی که میتوانید بیابید وارد کنید، چون آنها اغلب محدودیتهایی را آشکار میکنند که امضای تابع بهتنهایی نشان نمیدهد.