ممکن است داشبورد CI عدد «۱۰۰٪ Code Coverage» را سبز نشان دهد و همان کد در تولید مبلغ تخفیف را اشتباه محاسبه کند. چرا؟ چون پوشش میگوید کدام ساختارها هنگام اجرای تست لمس شدهاند؛ نمیگوید انتظارها درست بودهاند، همه ترکیبهای مهم بررسی شدهاند یا نیازمندیای جا نیفتاده است. تست جعبه سفید (White-Box Testing) زمانی ارزشمند است که شناخت کد را به طراحی تست هدفمند تبدیل کنیم، نه اینکه فقط یک درصد را بالا ببریم.
پاسخ کوتاه: تست جعبه سفید رویکردی است که در آن ساختار داخلی، منطق، جریان کنترل و جریان داده نرمافزار برای طراحی تست شناخته شدهاند. تکنیکهای رایج آن شامل Statement Coverage، Branch Coverage، Condition Coverage، MC/DC، تست مسیر، حلقه و جریان داده است. خروجی مطلوب، شواهد متناسب با ریسک درباره مسیرهای پیادهسازی است؛ نه ادعای «بدون باگ بودن» کد.
نکته کلیدی: ۱۰۰٪ Branch Coverage از ۱۰۰٪ Statement Coverage قویتر است، اما هیچکدام بهتنهایی صحت منطق، کیفیت assertion، نبود نیازمندی فراموششده یا پوشش همه مسیرها را تضمین نمیکنند.
تست جعبه سفید چیست؟
در White-Box Testing، طراح تست به کد، معماری یا مدل داخلی دسترسی دارد و از این اطلاعات برای انتخاب ورودی، مسیر و اوراکل تست استفاده میکند. این رویکرد با نامهای Structural Testing، Clear/Glass Box Testing و Code-Based Testing نیز شناخته میشود.
موضوع فقط «دیدن کد» نیست. تست باید بر اساس یک ساختار داخلی طراحی شود: شاخههای تصمیم، مسیرهای کنترل، تعریف و استفاده متغیرها، مدیریت خطا، مرز حلقهها، قرارداد میان مؤلفهها یا سیاست مجوز. خواندن کد بدون ساختن شاهد قابلاجرا، Code Review است؛ اجرای تست بدون استفاده از دانش داخلی ممکن است Black-Box باشد.
منبع رسمی ISTQB CTFL v4.0.1، Statement Testing و Branch Testing را بهعنوان تکنیکهای جعبه سفید توضیح میدهد و تاکید میکند که شناخت کل پیادهسازی، کشف نقص را حتی در صورت مشخصات مبهم تسهیل میکند؛ در مقابل، قابلیتِ اصلاً پیادهنشده ممکن است با نگاه صرفاً ساختاری کشف نشود.
تفاوت تست جعبه سفید، سیاه و خاکستری
| رویکرد | مبنای طراحی | پرسش نمونه | نقطه کور رایج |
|---|---|---|---|
| جعبه سفید | کد، ساختار و جریان داخلی | آیا هر شاخه مجوز و مسیر خطا اجرا شده است؟ | قابلیت فراموششده یا انتظار اشتباه |
| جعبه سیاه | نیازمندی، ورودی و خروجی بیرونی | آیا تخفیف در مرز سقف درست محاسبه میشود؟ | مسیر داخلی پوششنداده و کد مرده |
| جعبه خاکستری | دانش محدود معماری/داده | آیا کش یا صف باعث ناسازگاری مشاهدهشده میشود؟ | تصویر ناقص از داخل و احتمال فرض اشتباه |
این رویکردها رقیب نیستند. برای یک تابع تخفیف، تست جعبه سیاه مرز مبلغ و قانون کسبوکار را از دید نیازمندی میسنجد؛ تست جعبه سفید شاخههای کد و ترکیب شرطها را بررسی میکند. راهنمای تست جعبه سیاه و تکنیکهای آن نیمه بیرونی این استراتژی را پوشش میدهد.
آیا تست جعبه سفید همان تحلیل استاتیک است؟
خیر. «جعبه سفید» درباره مبنای طراحی تست و دسترسی به ساختار داخلی است؛ «استاتیک» یعنی محصول بدون اجرای کد ارزیابی میشود. تست جعبه سفید اغلب پویاست، اما شناخت ساختار در dry run یا بازبینی مدل جریان نیز استفاده میشود. برای تفاوت Review، Static Analysis و تست پویا، مقاله تست استاتیک چیست را ببینید.
تست جعبه سفید کجا و توسط چه کسی انجام میشود؟
- تست واحد و مؤلفه: رایجترین محل؛ توسعهدهنده روی تابع، کلاس یا ماژول کنترل مستقیم دارد.
- تست یکپارچهسازی: مسیر خطا، retry، تراکنش و قرارداد میان مؤلفهها با دانش معماری بررسی میشود. راهنمای تست یکپارچهسازی این سطح را توضیح میدهد.
- تست API و سرویس: با آگاهی از شاخههای مجوز، cache، feature flag یا ذخیرهسازی داده طراحی میشود.
- امنیت: مسیرهای حساس ورودی، کنترل دسترسی، مدیریت secret و خطا با تحلیل کد و آزمون پویا ترکیب میشوند.
- مهاجرت و پردازش داده: مسیر تبدیل، rollback، idempotency و حالتهای داده ناقص بررسی میشوند.
توسعهدهندگان معمولاً بخش بزرگی از تست جعبه سفید واحد را مینویسند. SDET، QA فنی، متخصص امنیت و مهندس داده نیز بر اساس دامنه مشارکت میکنند. استقلال ذهنی مهم است: نویسنده کد میتواند تست عالی بنویسد، اما ممکن است همان فرض اشتباه پیادهسازی را در assertion هم تکرار کند؛ Pair Review و تست جعبه سیاه مکمل این ریسکاند.
مثال کد: محاسبه هزینه ارسال
این تابع ساده را در نظر بگیرید. هزینه پایه ۵۰ هزار تومان است؛ سفارش یک میلیون تومان یا بیشتر یا کاربر VIP، ارسال عادی رایگان دارد؛ ارسال سریع ۸۰ هزار تومان به مبلغ فعلی اضافه میکند.
function shippingFee(total, vip, express) {
let fee = 50000;
if (total >= 1000000 || vip) {
fee = 0;
}
if (express) {
fee += 80000;
}
return fee;
}
با همین مثال میتوان دید یک مجموعه تست چگونه در معیارهای مختلف نمره متفاوت میگیرد:
| تست | total | vip | express | خروجی مورد انتظار |
|---|---|---|---|---|
| T1 | ۱٬۲۰۰٬۰۰۰ | false | true | ۸۰٬۰۰۰ |
| T2 | ۵۰۰٬۰۰۰ | false | false | ۵۰٬۰۰۰ |
| T3 | ۵۰۰٬۰۰۰ | true | false | ۰ |
T1 همه دستورهای اجرایی داخل دو if را لمس میکند، اما خروجی False هیچ تصمیمی را نمیآزماید. T1+T2 خروجی True و False هر دو تصمیم را پوشش میدهند؛ بااینحال نقش مستقل شرط vip هنوز بدون T3 روشن نیست. این تفاوت هسته تکنیکهای پوشش است.
۱. پوشش دستور (Statement Coverage)
هدف این است که هر دستور اجرایی حداقل یک بار اجرا شود.
فرمول: تعداد دستورهای اجراشده ÷ کل دستورهای اجرایی × ۱۰۰
در مثال، T1 دستور مقداردهی اولیه، هر دو بدنه if و return را اجرا میکند و ممکن است ابزار پوشش دستور را کامل نشان دهد. اما حالت سفارش عادی، کاربر غیرVIP و ارسال غیرسریع هنوز بررسی نشده است. بنابراین Statement Coverage برای کشف کد هرگز اجرانشده مفید است، ولی درباره خروجیهای تصمیم و صحت شرطها اطلاعات کافی نمیدهد.
۲. پوشش شاخه (Branch Coverage)
در Branch Testing، مورد پوشش هر انتقال کنترل در Control Flow Graph است. برای تصمیمهای شرطی، خروجیهای True و False شاخههای مهماند؛ switch/case و ادامه یا خروج حلقه نیز شاخه ایجاد میکنند.
فرمول: تعداد شاخههای اجراشده ÷ کل شاخهها × ۱۰۰
مجموعه T1+T2 خروجی True و False هر دو if را اجرا میکند. طبق تعریف رسمی ISTQB، پوشش ۱۰۰٪ شاخه، پوشش ۱۰۰٪ دستور را نیز دربر میگیرد؛ برعکس آن درست نیست. بااینحال ممکن است خطایی فقط در توالی خاص چند تصمیم یا در مقدار دادهای خاص ظاهر شود و Branch Coverage آن را تضمین نکند.
۳. پوشش شرط (Condition Coverage)
یک تصمیم میتواند از چند شرط اتمیک ساخته شود. در عبارت زیر دو شرط داریم:
A = total >= 1000000
B = vip
Decision = A || B
Condition Coverage میخواهد هر شرط اتمیک حداقل یک بار True و یک بار False شود. T1 مقدار A را True میکند و بهعلت short-circuit ممکن است B اصلاً ارزیابی نشود. T2 هر دو را False و T3 مقدار A=False و B=True را میسازد.
پوشش شرط و پوشش تصمیم یکدیگر را لزوماً تضمین نمیکنند. مجموعه تست میتواند هر شرط را True/False کند، اما خروجی کلی تصمیم فقط یک مقدار بگیرد؛ یا هر دو خروجی تصمیم را بگیرد، ولی یکی از شرطهای داخلی هرگز مستقلاً تغییر نکند. ابزار پوشش و semantics زبان را در short-circuit جدی بگیرید.
۴. پوشش تصمیم/شرط
Decision/Condition Coverage هر دو الزام را کنار هم میگذارد: هر شرط اتمیک True و False شود و خود تصمیم هم خروجی True و False داشته باشد. این معیار از هرکدام بهتنهایی قویتر است، اما هنوز اثبات نمیکند هر شرط مستقلاً نتیجه تصمیم را تغییر داده یا تمام ترکیبهای ممکن اجرا شدهاند.
۵. پوشش چندشرطی و MC/DC
Multiple Condition Coverage
MCC همه ترکیبهای شدنی True/False شرایط اتمیک یک تصمیم را هدف میگیرد. برای n شرط، فضای نظری میتواند تا ۲n ترکیب رشد کند؛ بعضی ترکیبها بهدلیل محدودیت دامنه غیرممکناند. این رشد نمایی MCC را برای تصمیمهای بزرگ پرهزینه میکند و خودِ بزرگی عبارت میتواند نشانه نیاز به سادهسازی طراحی باشد.
Modified Condition/Decision Coverage
MC/DC بهدنبال جفت تستهایی است که نشان دهند تغییر هر شرط، با ثابت نگهداشتن اثر سایر شرطها، نتیجه تصمیم را مستقلاً تغییر میدهد. برای A || B، این سه ترکیب نقش مستقل هر دو شرط را نشان میدهند:
| A | B | A || B | کاربرد |
|---|---|---|---|
| true | false | true | با حالت بعد، اثر مستقل A |
| false | false | false | خط مبنای هر دو جفت |
| false | true | true | با حالت قبل، اثر مستقل B |
MC/DC معمولاً با تستهای کمتری از MCC استقلال شرطها را نشان میدهد، اما طراحی درست آن در عبارتهای دارای coupling، short-circuit یا شرطهای غیرقابلکنترل نیازمند دقت است. سطح پوشش لازم باید از ریسک و الزام حوزه محصول بیاید، نه علاقه به یک مخفف پیچیده.
۶. تست مسیر و Basis Path Testing
Path Testing توالیهای اجرایی از ورود تا خروج را بررسی میکند. در کد دارای چند تصمیم، تعداد مسیرها بهسرعت زیاد میشود؛ حلقهها میتوانند فضای مسیر را عملاً نامحدود کنند. بههمین دلیل «تمام مسیرها» برای اکثر برنامههای واقعی هدف عملی نیست.
Basis Path Testing از Control Flow Graph و پیچیدگی سیکلوماتیک برای شناسایی مجموعهای از مسیرهای مستقل استفاده میکند. فرمول عمومی آن V(G)=E−N+2P است؛ E تعداد یالها، N تعداد گرهها و P تعداد مؤلفههای متصل گراف است. در ساختارهای ساده تکورودی، «تعداد نقاط تصمیم + ۱» تقریب تقریبی رایجی است.
پیچیدگی سیکلوماتیک یک سیگنال درباره پیچیدگی جریان کنترل است، نه نمره کیفیت و نه تضمین تعداد دقیق تستهای کافی. تابعی با عدد بالا میتواند هم سختتر فهمیده شود و هم فضای تست بزرگتری داشته باشد؛ شاید بهترین اقدام، Refactor پیش از افزودن دهها تست باشد.
۷. تست حلقه
برای حلقه، مرزهای مرتبط با قرارداد را انتخاب کنید:
- صفر تکرار، اگر ورودی خالی مجاز است
- یک تکرار برای رفتار پایه
- دو تکرار برای آشکار شدن وابستگی بین دورها
- تعداد معمول و حجم بزرگ واقعبینانه
- حد مجاز و درست قبل/بعد از آن
- خروج زودهنگام، break/continue و استثنا داخل حلقه
الگوی n−۱، n و n+۱ فقط وقتی معنا دارد که n مرز واقعی و قابلدسترسی باشد. تولید ورودی عظیم بدون ارتباط با محدودیت حافظه، زمان یا نیازمندی صرفاً تست را کند میکند.
۸. تست جریان داده (Data Flow Testing)
Data Flow Testing مسیر تعریف و استفاده متغیرها را بررسی میکند. سؤالهای نمونه:
- آیا مقدار پیش از مقداردهی خوانده میشود؟
- آیا متغیر تعریف شده ولی هرگز استفاده نمیشود؟
- آیا مقدار در یک شاخه overwrite و در شاخه دیگر قدیمی میماند؟
- آیا منبع حساس پس از مصرف پاک یا آزاد میشود؟
- آیا یک مقدار در مسیر async یا concurrent از چرخه عمر معتبر خارج میشود؟
جفتهای Define–Use مسیرهایی را هدف میگیرند که یک تعریف به استفاده محاسباتی یا شرطی میرسد. تحلیل استاتیک میتواند کاندیداها را بیابد و تست پویا رفتار واقعی را تأیید کند. مقاله تحلیل استاتیک کد برای تسترها ابزار و نوع یافتههای این مرحله را تکمیل میکند.
مقایسه تکنیکهای پوشش جعبه سفید
| تکنیک | چه چیزی را میسنجد؟ | چه چیزی را تضمین نمیکند؟ | کاربرد عملی |
|---|---|---|---|
| Statement | اجرای دستورها | خروجی همه تصمیمها | کشف کد اجرانشده |
| Branch | شاخههای جریان کنترل | ترکیب و مسیرهای خاص | حد پایه قویتر برای منطق تصمیم |
| Condition | True/False هر شرط اتمیک | خروجی هر تصمیم | عبارتهای بولی مرکب |
| Decision/Condition | شرطها و خروجی تصمیم | استقلال اثر هر شرط | پوشش ترکیبی متعادل |
| MCC | ترکیبهای شدنی شرطها | همه مسیرهای کل برنامه | منطق بسیار حساس و کوچک |
| MC/DC | اثر مستقل هر شرط بر تصمیم | همه ترکیبها و همه مسیرها | تصمیمهای حساس با کنترل هزینه |
| Path/Basis | توالیها یا مسیرهای مستقل | فضای نامحدود حلقه و داده | توابع پرریسک با جریان پیچیده |
| Data Flow | تعریف و استفاده داده | تمام رفتار کسبوکار | state، مقداردهی و چرخه عمر داده |
چرا پوشش کد بالا مساوی کیفیت بالا نیست؟
این تست از نظر اجرا پوشش میسازد اما تقریباً هیچ رفتاری را بررسی نمیکند:
test("shipping fee", () => {
shippingFee(1200000, false, true);
// assertion ندارد
});
حتی assertion ضعیف مانند «خروجی null نیست» میتواند کد معیوب را سبز نگه دارد. Code Coverage این موارد را نمیسنجد:
- درستی اوراکل و assertion
- نیازمندیای که اصلاً پیادهسازی نشده
- مقادیر مرزی و ترکیب داده
- خطای همزمانی، زمان و سرویس بیرونی
- کیفیت تجربه کاربر
- ریسک امنیتی خارج از مسیر اجراشده
- قابلیت نگهداری خود تست
پس از رسیدن به پوشش مناسب، Mutation Testing میتواند کیفیت حساسیت تست را بسنجد: ابزار تغییرهای کوچک مانند عوضکردن عملگر مقایسه میسازد؛ اگر تست همچنان Pass بماند، Mutant زنده نشان میدهد assertion یا داده شاید ضعف دارد. راهنمای تست جهش (Mutation Testing) این روش را عمیقتر توضیح میدهد.
مقاله چرا پوشش ۱۰۰٪ میتواند گمراهکننده باشد نیز خطاهای مدیریتی استفاده از این عدد را بررسی میکند.
مزایا و محدودیتهای تست جعبه سفید
| مزیت | محدودیت متناظر |
|---|---|
| کشف شاخه و کد اجرانشده | ممکن است نیازمندی جاافتاده را نبیند |
| بازخورد سریع در سطح واحد | تست وابسته به جزئیات پیادهسازی شکننده میشود |
| اندازهگیری عینی ساختار پوششیافته | عدد بهراحتی با assertion ضعیف بازی میشود |
| کمک به تحلیل منطق و داده | فضای مسیر و ترکیبها میتواند بسیار بزرگ شود |
| مکانیابی سریعتر شکست | نیازمند مهارت فنی و نگهداری مداوم است |
| پشتیبانی از Refactor امن | تست بیشازحد داخلی، Refactor سالم را هم میشکند |
کدام تکنیک را انتخاب کنیم؟
از ریسک شروع کنید، نه از بیشترین درصد:
- محاسبه مالی: Branch + Condition/MC/DC برای قواعد حساس، همراه تست مرزی جعبه سیاه و Mutation.
- کنترل دسترسی: مسیرهای Allow/Deny، نقشها، پیشفرض امن و خطاهای وابستگی.
- CRUD ساده: Statement/Branch مناسب همراه تست قرارداد و اعتبارسنجی.
- Parser یا Rule Engine: Data Flow، مسیرهای خطا، fuzzing و ترکیبهای منتخب.
- کد دارای حلقه و retry: مرز حلقه، خروج، timeout، backoff و idempotency.
- کد Legacy: ابتدا Characterization Test و پوشش خط مبنا، سپس Refactor مرحلهای.
در محصولات پرریسک، الزام قراردادی یا استاندارد حوزه ممکن است معیار مشخصی تعیین کند. در سایر پروژهها، هدف پوشش را بر اساس احتمال/پیامد و هزینه تست مستند کنید. مقاله تست مبتنی بر ریسک چارچوب اولویتبندی را ارائه میدهد.
فرآیند عملی تست جعبه سفید
- هدف و سطح را تعیین کنید. تابع، مؤلفه، مسیر امنیتی یا مهاجرت داده؟
- کد و قرارداد را با هم بخوانید. فقط آنچه پیاده شده مبنای انتظار نباشد.
- ریسک و ساختار را مدل کنید. تصمیمها، حلقهها، مسیر خطا و Define–Useهای حساس را مشخص کنید.
- معیار پوشش مناسب انتخاب کنید. Statement، Branch، MC/DC یا ترکیبی؛ دلیل انتخاب را ثبت کنید.
- تست کمینه و خوانا طراحی کنید. هر تست رفتار و دلیل مشخص داشته باشد.
- Assertion معنادار بنویسید. خروجی، state، side effect و عدم وقوع اثر نامطلوب را بررسی کنید.
- پوشش را اجرا و شکاف را تحلیل کنید. خط قرمز داشبورد را کورکورانه پر نکنید؛ علت شکاف را بفهمید.
- تستهای مکمل اجرا کنید. Black-Box، static analysis، mutation، integration و exploratory.
- در CI نگه دارید. تغییر پوشش، Flaky Test و زمان اجرا را پایش کنید؛ استثناها مرور شوند.
ابزارهای تست جعبه سفید
ابزار را بر اساس زبان و سؤال انتخاب کنید. نمونهها رتبهبندی نیستند:
| نیاز | دسته ابزار | نمونه شناختهشده |
|---|---|---|
| اجرای تست واحد | Test Framework | JUnit، pytest، Jest |
| پوشش کد | Coverage Instrumentation | JaCoCo، coverage.py، Istanbul/nyc |
| تحلیل استاتیک | Lint/SAST/Quality Analysis | SonarQube، ESLint، PMD |
| تست جهش | Mutation Tool | PIT، Stryker، mutmut |
| مشاهده اجرا | Debugger/Profiler/Trace | ابزار IDE و runtime |
قبل از افزودن ابزار، هزینه اجرا، پشتیبانی زبان، سازگاری با build، دقت اندازهگیری، گزارش شاخه/شرط و امنیت ارسال کد به سرویس بیرونی را بررسی کنید. یک gate سراسری برای کل repository میتواند فایلهای بحرانی و کماهمیت را میانگین بگیرد؛ هدف ماژولهای حساس را جدا تعریف کنید.
اشتباهات رایج در White-Box Testing
- تبدیل درصد پوشش به KPI فردی: رفتار بازیکردن عدد و تست کمارزش ایجاد میکند.
- Mock کردن همهچیز: تست از رفتار واقعی مؤلفه جدا میشود.
- تست جزئیات خصوصی: هر Refactor سالم مجموعه را میشکند.
- نادیده گرفتن مسیر خطا: فقط happy path سبز میماند.
- Assertion مبهم یا غایب: اجرا هست، بررسی رفتار نیست.
- اعتماد به یک معیار: Statement، Branch یا MC/DC هیچکدام کل کیفیت را نشان نمیدهند.
- نوشتن تست بعد از دیدن پیادهسازی، بدون قرارداد: همان اشتباه کد در انتظار تکرار میشود.
- هدف ۱۰۰٪ برای کد تولیدشده/دفاعی بدون تحلیل: هزینه بالا و ارزش کم میسازد.
- نادیده گرفتن تست Flaky: Retry تا سبز شدن اعتماد به مجموعه را از بین میبرد.
چکلیست تست جعبه سفید
- هدف تست و واحد داخلی مورد بررسی روشن است.
- انتظار از قرارداد/نیازمندی و نه فقط کد گرفته شده است.
- تصمیمها، مسیرهای خطا، حلقهها و داده حساس مدل شدهاند.
- معیار پوشش بر اساس ریسک انتخاب شده است.
- True و False شاخههای مهم اجرا میشوند.
- برای عبارتهای مرکب، اثر شرطها بررسی شده است.
- Assertion خروجی و side effect را معنادار میسنجد.
- شکاف پوشش تحلیل و استثنا مستند شده است.
- Black-Box، Integration و تحلیل استاتیک مکملاند.
- مجموعه در CI سریع، پایدار و دارای مالک است.
سؤالات متداول تست جعبه سفید
آیا ۱۰۰٪ Branch Coverage یعنی کد بدون باگ است؟
خیر. یعنی همه شاخههای قابلاندازهگیری اجرا شدهاند. داده، توالی مسیرها، assertion، نیازمندی جاافتاده، همزمانی و رفتار بیرونی همچنان میتوانند نقص داشته باشند.
تفاوت Statement و Branch Coverage چیست؟
Statement اجرای دستورها را میسنجد؛ Branch انتقالهای جریان کنترل و خروجی تصمیمها را. ۱۰۰٪ Branch Coverage طبق ISTQB، Statement Coverage کامل را نیز پوشش میدهد، اما برعکس نیست.
آیا فقط توسعهدهنده تست جعبه سفید مینویسد؟
خیر. توسعهدهنده رایجترین مجری تست واحد است، اما SDET، QA فنی، امنیت و مهندس داده نیز میتوانند با دسترسی و دانش داخلی تست طراحی کنند. Pairing و بازبینی به کاهش سوگیری کمک میکند.
MC/DC با پوشش چندشرطی چه تفاوتی دارد؟
MCC تمام ترکیبهای شدنی شرطها را هدف میگیرد؛ MC/DC با جفت تستها نشان میدهد هر شرط مستقلاً نتیجه تصمیم را تغییر میدهد و معمولاً به تستهای کمتری نیاز دارد. هیچکدام همه مسیرهای سیستم را تضمین نمیکنند.
بهترین درصد Code Coverage چقدر است؟
عدد جهانی وجود ندارد. هدف باید بر اساس ریسک، نوع کد، کیفیت assertion و هزینه نگهداری تعیین شود. روند افت پوشش و شکاف ماژولهای بحرانی معمولاً از یک میانگین سراسری مهمتر است.
جمعبندی
تست جعبه سفید دیدی میدهد که از بیرون سیستم به دست نمیآید: کدام شاخه، شرط، مسیر یا جریان داده واقعاً آزموده شده است. از Statement Coverage برای خط مبنا شروع کنید، Branch را برای تصمیمها بسنجید و در منطق حساس سراغ Condition، MC/DC، مسیر و Mutation بروید. درصد پوشش را سرنخ طراحی تست بدانید، نه مدرک کیفیت؛ بهترین استراتژی، دانش داخل کد را با انتظار مستقل، تست جعبه سیاه و تحلیل ریسک ترکیب میکند.

