فرض کنید Regression Suite تیم شما ۹۰ دقیقه طول می‌کشد، زمان Pull Request فقط ۳۰ دقیقه است و همه می‌گویند «تست‌های مهم‌تر را اجرا کنیم». مشکل از همین واژهٔ مهم‌تر شروع می‌شود: برای Product، تراکنش ناموفق مهم است؛ برای عملیات، دوباره‌برداشت‌شدن پول؛ برای پشتیبانی، رسید اشتباه؛ و برای توسعه‌دهنده، بخشی که همین امروز تغییر کرده است. اگر این تفاوت‌ها به یک قرارداد قابل‌اجرا تبدیل نشوند، «تست مبتنی بر ریسک» فقط نام تازه‌ای برای انتخاب سلیقه‌ای چند Test Case خواهد بود.

پیاده‌سازی تست مبتنی بر ریسک یعنی Risk را از یک جدول جلسه‌ای به جریان کاری زنده تبدیل کنیم: تغییر را بشناسیم، Evidence لازم را تعیین کنیم، تست مناسب را با بودجهٔ مشخص اجرا کنیم، Unknown را پنهان نکنیم و نتیجهٔ Production را دوباره به مدل برگردانیم. این راهنما برای تیمی نوشته شده که محصول و Test Suite موجود دارد و می‌خواهد RBT را ابتدا در یک Pilot، سپس در CI/CD و در نهایت در چند تیم مستقر کند.

RBT در مرحلهٔ اجرا دقیقاً چه چیزی را تغییر می‌دهد؟

در راهنمای مفهومی تست مبتنی بر ریسک دربارهٔ Risk Statement، احتمال، پیامد، ریسک ذاتی/فعلی/باقی‌مانده و Risk→Test صحبت کرده‌ایم. این مقاله آن مفاهیم را تکرار نمی‌کند؛ موضوع اینجا Operating Model استقرار است.

پس از استقرار، این پنج تصمیم باید نسبت به قبل متفاوت باشند:

  • چه چیزی وارد برنامهٔ تست شود؟ بر اساس Failure Mechanism و پیامد، نه فقط متن Requirement.
  • کدام تست زودتر اجرا شود؟ بر اساس ریسک تغییر، Evidence موجود، سن Evidence و هزینهٔ Feedback؛ نه فقط Priority دستی یا سابقهٔ Fail.
  • کجا عمیق‌تر تست کنیم؟ جایی که عدم‌قطعیت، پیامد یا ضعف کنترل بیشتر است.
  • چه زمانی متوقف شویم؟ وقتی Evidence لازم برای تصمیم به دست آمده، یا یک Critical Gate شکست خورده است؛ نه وقتی صرفاً درصد Pass جذاب شده.
  • چگونه یاد بگیریم؟ Incident و دادهٔ Production باید وزن‌ها، Dependency Map، Oracle و Suite را تغییر دهند.

طبق سرفصل جاری ISTQB CTAL-TM 3.0، RBT فقط اولویت‌بندی اجرا نیست؛ شناسایی و ارزیابی ریسک، کاهش آن با تست مناسب، پایش مداوم و سنجش موفقیت را در بر می‌گیرد. استاندارد ISO/IEC/IEEE 29119-2:2021 نیز فرایندهای تست را برای حاکمیت، مدیریت و اجرا در چرخه‌های عمر گوناگون قابل‌اعمال می‌داند. این دو منبع نسخهٔ واحدی برای همهٔ تیم‌ها تجویز نمی‌کنند؛ فرایند باید متناسب با Context طراحی شود.

RBT چه چیزی نیست؟

  • حذف تست‌های کم‌ریسک برای همیشه نیست؛ Depth و Frequency آن‌ها می‌تواند کمتر شود.
  • برچسب High/Medium/Low روی Ticket بدون Evidence Contract نیست.
  • فرمول احتمال × پیامد، حقیقت آماری یا مجوز جمع‌کردن مقیاس‌های ترتیبی نیست.
  • بهینه‌سازی زمان Pipeline به هر قیمت نیست؛ Selection ممکن است Fault مرتبط را جا بیندازد.
  • انتقال مالکیت کیفیت به QA نیست؛ Risk Owner و Release Decision Owner باید نام داشته باشند.
  • جایگزین تحلیل امنیت، Performance، Accessibility، Privacy یا Human Evaluation نیست.

مدل عملیاتی: حلقهٔ Change تا Learning

یک استقرار قابل‌دوام را می‌توان با این حلقه اداره کرد:

Change / Incident / Dependency update
        ↓
Risk delta and uncertainty
        ↓
Evidence question and test boundary
        ↓
Selection + execution + result semantics
        ↓
Gate / exception / release decision
        ↓
Production outcome and calibration
        ↺

«Risk delta» یعنی تغییر این Release چه چیزی را در وضعیت ریسک قبلی جابه‌جا کرده است. لازم نیست در هر Commit کل Risk Register را از نو بسازید؛ اما باید بتوانید بگویید کدام Component، جریان کاربر، Dependency، داده، کنترل یا فرض تغییر کرده و چه Evidence قبلی منقضی شده است.

شش Artifact حداقلی

  1. Pilot Charter: محدوده، Decision horizon، Owner، زمان، سقف هزینه و معیار توقف.
  2. Risk Backlog: Risk Statement، Impact، Likelihood/Uncertainty، Owner و وضعیت Treatment.
  3. Evidence Map: Risk→Question→Boundary→Oracle→Coverage→Artifact.
  4. Suite Inventory: مدت، ثبات، Fidelity، داده، Dependency، مالک و تصمیم نگهداری هر تست.
  5. Selection Manifest: چرا یک Test برای این Build انتخاب یا حذف شده است.
  6. Calibration Log: چه Incident یا Missای باعث تغییر مدل، کنترل یا Suite شد.

نقش‌ها و حق تصمیم

نقش مسئولیت در RBT چیزی که نباید مبهم بماند
Product/Business Outcome، پیامد مشتری/مالی و Trade-off چه کسی Residual Risk را می‌پذیرد؟
Developer/Architect Change Impact، Dependency و Testability کدام فرض فنی و کدام ناحیه تغییر کرده؟
QA/QE تسهیل تحلیل، طراحی Evidence، Challenge مستقل و گزارش Unknown چه Evidenceای برای توصیه کافی است؟
Security/Data/SRE Risk تخصصی، Guardrail و Evidence مستقل چه Gateای قابل Override نیست؟
Release Decision Owner Release/Hold/Conditional Release Exception را چه کسی، تا چه تاریخ و با چه Rollbackای می‌پذیرد؟

برای طراحی دقیق‌تر Accountability و Stop Authority، از مدل مالکیت مشترک کیفیت استفاده کنید. «همه مسئول کیفیت‌اند» فقط وقتی مفید است که مسئول هر تصمیم نیز مشخص باشد.

گام صفر: آمادگی تیم را بسنجید

RBT روی داده و گفت‌وگوی ناقص هم قابل‌شروع است، اما روی Pipeline غیرقابل‌اعتماد یا Suite بی‌هویت به‌سرعت به انتخاب تصادفی تبدیل می‌شود. پیش از Pilot، این حداقل‌ها را بررسی کنید:

  • هر Build و Test Run یک شناسه و Artifact قابل‌ردیابی دارد.
  • Test Result میان Passed، Failed، Blocked، Not-run، Invalid و Quarantined فرق می‌گذارد.
  • مالک محصول می‌تواند حداقل سه پیامد مهم برای مشتری یا کسب‌وکار را نام ببرد.
  • تغییر کد/Config/Schema/Feature Flag/Dependency قابل‌شناسایی است.
  • تست‌های ناپایدار از Product Failure جدا می‌شوند و Retry، Fail را پاک نمی‌کند.
  • برای خطرهای Critical، Smoke/Probe یا Evidence جایگزین وجود دارد.

اگر Pipeline گاهی بدون اجرای تست سبز می‌شود، Report خالی را Success می‌گیرد یا تست‌ها دادهٔ مشترک دارند، اول مشکل را با چارچوب نجات Test Suite مهار کنید. RBT نمی‌تواند Evidence خراب را با امتیاز ریسک سالم کند.

سه وضعیت توقف پیش از Pilot

  1. هیچ Business Owner حاضر نیست پیامد یا Residual Risk را بررسی کند.
  2. تیم نمی‌تواند بگوید آیا یک Test واقعاً اجرا شده و با کدام نسخه بوده است.
  3. هدف مدیریت فقط کاهش تعداد تست یا Compute Cost است و Fault Escape/Unknown جزو معیارها نیست.

در این وضعیت‌ها ابتدا مسئلهٔ حاکمیت یا Evidence را حل کنید. «RBT برای سریع‌ترشدن» هدف ناقصی است؛ هدف درست، تخصیص شفاف تلاش برای تصمیم بهتر تحت محدودیت است.

گام اول: Pilot مناسب انتخاب کنید

شروع هم‌زمان در کل سازمان معمولاً Taxonomy، جلسات و Dashboard تولید می‌کند، نه یادگیری. Pilot خوب یک Value Stream واقعی دارد: از Change تا Outcome و Incident آن قابل‌مشاهده است.

معیار انتخاب Pilot

معیار نشانهٔ مناسب نشانهٔ نامناسب
اهمیت پیامد واقعی اما قابل‌کنترل اولین تجربه روی Safety-critical سراسری
مرز یک Journey یا سرویس با Owner روشن «همهٔ محصول»
تغییر Release منظم و دادهٔ کافی سامانهٔ راکد یا بازنویسی کامل
Evidence Suite و Production signal حداقلی هیچ Run identity یا Incident data
همکاری Product، Dev، QA و Ops در دسترس تحلیل فقط در تیم QA

نمونهٔ مناسب برای یک فروشگاه ایرانی: Journey پرداخت و بازپرداخت در یک Product Team، با دو PSP، Ledger داخلی و Notification service. محدوده کوچک است، اما Failureهایی مثل Duplicate Charge، Timeout-after-commit، اختلاف ریال/تومان و Reconciliation ناموفق پیامد قابل‌فهم دارند.

Pilot Charter آمادهٔ کپی

Outcome: پرداخت موفق یا شکستِ قابل‌بازیابی بدون دوباره‌برداشت
Scope: checkout-api → PSP adapter → ledger → notification
Decision horizon: هر Pull Request + release روزانه
Baseline window: چهار هفته قبل از Pilot
Constraints: PR feedback ≤ 30 min؛ nightly full suite ≤ 120 min
Critical rules: Evidence معتبر برای duplicate، timeout state و restore
Owner: Product Manager پرداخت
Facilitator: QA Lead
Release decision: Engineering Manager شیفت
Pilot duration: 30 روز
Stop conditions: Critical escape، افزایش Unknown، یا Selection غیرقابل‌توضیح
Success: Evidence زودتر بدون افزایش Critical escape یا پنهان‌کردن Not-run

خط مبنا را قبل از تغییر ثبت کنید

بدون Baseline، هر بهبودی داستانی می‌شود. برای چهار هفتهٔ قبل این داده‌ها را نگه دارید:

  • زمان تا اولین Evidence قابل‌اقدام، نه فقط کل Pipeline Duration؛
  • درصد Buildهایی که Test Run و Report معتبر دارند؛
  • Critical/High Riskهایی که Evidence معتبر و تازه دارند؛
  • Failed، Invalid، Flaky، Quarantined و Not-run با مخرج؛
  • Escaped Defect و Incident بر اساس پیامد و Risk؛
  • زمان تحلیل Failure و زمان بازیابی Build؛
  • هزینهٔ Compute فقط در کنار Outcome و Escape.

گام دوم: Workshop را به Risk Backlog تبدیل کنید

Workshop خروجی نیست؛ یک روش برای ساختن Backlog قابل‌پیگیری است. جلسهٔ ۶۰ تا ۹۰ دقیقه‌ای را با Product، Developer، QA، Operations/Support و در صورت نیاز Security/Data برگزار کنید. پیش از جلسه، Incidentها، Change history، Support ticketها، معماری، Constraintهای مقرراتی و Production signal را آماده کنید.

دستور جلسهٔ پیشنهادی

  1. ۱۰ دقیقه: Outcome و Decision horizon را هم‌تراز کنید.
  2. ۱۵ دقیقه: تغییرها، Dependencyها و فرض‌های این Release را مرور کنید.
  3. ۲۰ دقیقه: با الگوی Condition→Event→Impact، Failureها را مستقل بنویسید.
  4. ۱۵ دقیقه: Impact، Likelihood evidence و Uncertainty را جدا بحث کنید.
  5. ۱۵ دقیقه: Control، Evidence Question و Owner را تعیین کنید.
  6. ۱۰ دقیقه: Critical rule، Unknownها و زمان بازبینی را ثبت کنید.

در Refinement، پرسش‌های تستر باید Failure condition و فرض‌های پنهان را آشکار کند؛ بانک سؤال تحلیل نیازمندی‌ها برای این مرحله مکمل خوبی است.

Schema حداقلی Risk Backlog

risk_id: PAY-R04
statement: اگر PSP پس از Commit داخلی Timeout بدهد، Retry می‌تواند Charge دوم بسازد
impact: 5 — زیان مالی و شکایت مشتری
likelihood_band: 3
likelihood_evidence: 7 timeout در 30 روز؛ 2 مورد وضعیت نامعلوم
uncertainty: medium — رفتار PSP دوم کامل شبیه‌سازی نشده
inherent_risk: critical
controls: idempotency-key, unique constraint, reconciliation job
residual_risk: high
evidence_question: آیا Retry هم‌زمان فقط یک Charge و یک Ledger entry می‌سازد؟
owner: payments-product-owner
review_trigger: adapter/config/schema/PSP change or incident
status: needs-evidence

Risk Backlog را می‌توان در Jira، Azure Boards یا ابزار Test Management نگه داشت، اما فیلدها باید Queryپذیر و Versioned باشند. Tag آزاد مثل high-risk کافی نیست. Risk ID باید به Ticket، Test، Run، Defect، Exception و Incident متصل شود.

Unknown را یک وضعیت واقعی بدانید

«داده نداریم» معادل Low likelihood نیست. اگر PSP جدید، Migration یا Dependency بدون Observability دارید، Uncertainty را ثبت کنید و برایش Discovery task، Probe، Contract test یا محدودیت Rollout بسازید. گاهی پاسخ درست، تست بیشتر نیست؛ Canary، Feature Flag، Rate limit یا Manual approval است. چارچوب ISO 31000 نیز مدیریت ریسک را به تصمیم‌گیری و پایش پیوند می‌دهد؛ تست فقط یکی از Treatmentهاست.

گام سوم: Suite موجود را به Evidence Map وصل کنید

به‌جای نوشتن تست‌های تازه از صفر، ابتدا موجودی فعلی را بسازید. برای هر Test، این فیلدها را استخراج یا دستی نمونه‌برداری کنید:

فیلد پرسش
Test ID/Owner چه کسی خرابی یا کهنگی آن را پاسخ می‌دهد؟
Risk/Evidence question کدام تصمیم را تغذیه می‌کند؟
Failure mechanism Concurrency، Serialization، Auth، Restore یا چیز دیگر؟
Boundary/Fidelity Unit، Component، Contract، Integration یا System؛ کدام Dependency واقعی است؟
Oracle فقط Response را می‌بیند یا State، Side effect و Invariant را هم؟
Duration/Resource زمان، CPU، محیط یا هزینهٔ بیرونی چقدر است؟
Health Failure قابل‌اعتماد، Flake، Retry و سن آخرین Run چیست؟
Change relation به Component، API، Schema، Config و Journey چگونه وصل است؟

سپس برای هر تست یکی از تصمیم‌های Keep، Split، Move، Add fidelity، Rewrite، Quarantine یا Delete را ثبت کنید. راهنمای طراحی سبد تست کمک می‌کند Boundary را بر اساس Failure Mechanism انتخاب کنید، نه بر اساس نسبت ثابت Unit/Integration/E2E.

نمونهٔ نگاشت Risk به Evidence

Risk Evidence question Boundary Oracle Lane
Duplicate charge ۲۰ درخواست هم‌زمان چند Charge می‌سازد؟ API + DB integration Response + unique state + ledger count PR critical
IRR/toman mismatch مبلغ canonical و نمایشی در همهٔ مرزها یکی است؟ Unit + contract Integer invariant + schema PR fast
Timeout after commit پس از Timeout، وضعیت قابل‌بازیابی و Retry امن است؟ Component fault injection PSP stub + state probe PR critical
Restore corruption Backup برگشتی با PSP و Ledger reconcile می‌شود؟ Restore rehearsal Reconciliation invariant nightly/weekly gate
Receipt accessibility رسید با Screen reader قابل‌فهم است؟ System + human Automated checks + expert review release evidence

پوشش Test Case با پوشش ریسک یکی نیست

ممکن است ۵۰ Test Case یک Validation ساده را تکرار کنند و یک Test ده‌دقیقه‌ای تنها Evidence مربوط به Restore باشد. بنابراین Test count را وزن ندهید؛ Evidence question و Failure mechanism را پوشش دهید. برای هر Risk این حالت‌ها را ثبت کنید:

  • Valid-Passed: Evidence معتبر است و Failure موردنظر دیده نشد.
  • Valid-Failed: Evidence معتبر Failure را نشان می‌دهد.
  • Blocked/Invalid: اجرا شده اما قابلیت نتیجه‌گیری ندارد.
  • Not-run/Expired: Evidence جاری وجود ندارد.
  • Partial: فقط بخشی از Mechanism یا Fidelity لازم پوشش داده شده.

گام چهارم: Risk delta را وارد Delivery Workflow کنید

اگر Risk analysis یک جلسهٔ فصلی باشد، با اولین تغییر معماری منقضی می‌شود. آن را در نقاط تصمیم موجود جاسازی کنید، نه اینکه Ceremony تازه‌ای برای همهٔ کارها بسازید.

در Refinement

  • Outcome و پیامد Failure چیست؟
  • کدام Actor، داده، Tenant، پول، زمان یا Dependency تحت‌تأثیر است؟
  • کدام فرض قابل‌آزمون نیست و به Observability یا Spike نیاز دارد؟
  • Risk جدید است، تغییر کرده یا Evidence قبلی را منقضی می‌کند؟

در Pull Request

Developer فقط فایل‌های تغییرکرده را ندهد؛ Impact hint هم ثبت کند:

change:
  components: [checkout-api, psp-adapter]
  schemas: [payment_attempt]
  configs: [retry-policy]
  journeys: [pay, retry, refund]
  dependencies: [psp-a, notification]
  risk_hints: [PAY-R01, PAY-R04]
  uncertainty: "PSP-B timeout contract not observed in production"

این Manifest «حقیقت نهایی» نیست؛ ورودی Selection است. Dependency graph، Code coverage، Contract ownership، تاریخچهٔ تغییر و نظر Reviewer باید آن را Challenge کنند.

در Daily/Planning

به‌جای گزارش «۷۰٪ تست‌ها انجام شد»، بگویید: «دو Risk بحرانی Evidence معتبر دارند؛ Restore هنوز Expired است؛ PSP-B Unknown مانده؛ و Release نیازمند Rehearsal یا Exception نام‌دار است.» این زبان تصمیم ایجاد می‌کند.

در Retrospective و Incident Review

هر Escape را فقط به «تست کم بود» تقلیل ندهید. بپرسید:

  1. Risk اصلاً شناخته شده بود؟
  2. Dependency یا Change impact اشتباه بود؟
  3. Evidence question درست اما Boundary/Fidelity/Oracle ضعیف بود؟
  4. Test انتخاب نشد، اجرا نشد، Invalid شد یا نتیجه نادیده گرفته شد؟
  5. Gate یا Exception چه رفتاری داشت؟
  6. چه تغییر سیستمی از تکرار جلوگیری می‌کند؟

گام پنجم: عمق، گستره و بودجه را تخصیص دهید

RBT فقط ترتیب Test Case نیست. Risk بالاتر می‌تواند چند اهرم را تغییر دهد:

  • شروع زودتر Static review یا Example mapping؛
  • تکنیک عمیق‌تر مثل Boundary analysis، State transition، Pairwise یا Fault injection؛
  • Fidelity بیشتر برای Dependency یا محیط؛
  • Oracle مستقل‌تر و مشاهدهٔ State/Side effect؛
  • تکرار روی داده، Concurrency یا Platformهای بیشتر؛
  • Reviewer یا Specialist اضافه؛
  • Frequency بالاتر در PR، Nightly یا Release؛
  • Canary، Observability و Rollback سخت‌گیرانه‌تر.

Depth-first یا Breadth-first؟

Depth-first ابتدا Evidence عمیق Critical riskها را کامل می‌کند؛ برای Payment، Safety، Security یا Migration مناسب است. Breadth-first ابتدا یک Probe کم‌هزینه روی Riskهای متعدد می‌زند؛ برای کشف سریع دامنهٔ Failure در تغییر بزرگ مفید است. مدل ترکیبی معمولاً بهتر است: Critical ruleها را غیرقابل‌مذاکره نگه دارید، سپس از بودجهٔ باقی‌مانده برای Breadth استفاده کنید.

بودجه را به Gate تبدیل نکنید

«۳۰ دقیقه تمام شد» یعنی Constraint به انتها رسیده، نه اینکه Evidence کافی است. اگر پوشش همهٔ Critical riskها در سقف بودجه شدنی نیست، خروجی Selection باید Infeasible باشد. گزینه‌ها عبارت‌اند از:

  • بودجه یا Parallelism را افزایش دهید؛
  • تست را به Boundary کوچک‌تر اما Mechanism-preserving منتقل کنید؛
  • Scope تغییر را کوچک کنید؛
  • Evidence جایگزین معتبر بسازید؛
  • Release را Hold یا Exception محدود و زمان‌دار ثبت کنید.

گام ششم: انتخاب تست مبتنی بر ریسک را در CI پیاده کنید

Pipeline باید بتواند برای هر Build توضیح دهد: چه چیزی تغییر کرد، چه Riskهایی Impacted شدند، چه تست‌هایی واجد شرایط بودند، چرا هر تست انتخاب/حذف شد، کدام Evidence تولید شد و چه fallbackای باقی ماند. جزئیات معماری Lane و Gate را در راهنمای Continuous Testing در CI/CD ببینید.

ورودی‌های Selection

  • Changed component/API/schema/config/flag/dependency؛
  • Risk level، Uncertainty و Critical rule؛
  • Risk→Test/Control mapping؛
  • آخرین Evidence معتبر و Age آن؛
  • Test duration، health، resource و environment؛
  • تاریخچهٔ Failure/Incident به‌عنوان یک Signal، نه تنها معیار؛
  • Budget و Deadline هر Lane.

قواعد ایمن عملی

  1. Smoke و Critical controlهای Impacted همیشه اجرا شوند.
  2. تست Invalid یا Quarantined، پوشش محسوب نشود؛ Alternative evidence لازم است.
  3. Deletion/minimization دائمی فقط با Review؛ Selection یک Build، حذف Test نیست.
  4. اگر Change impact نامعلوم یا Mapping کهنه است، انتخاب گسترده‌تر یا Full suite اجرا شود.
  5. Full regression با Cadence مشخص—مثلاً Nightly/Weekly/Release—باقی بماند.
  6. نتیجهٔ fallback با subset مقایسه شود تا Miss و Drift دیده شود.
  7. Security/Compliance/Restore/Accessibility Gateهای مستقل در یک میانگین حل نشوند.

مطالعات Regression Test Selection نشان می‌دهند سود و ریسک روش به Context وابسته است. مطالعهٔ کلاسیک Rothermel و Harrold دربارهٔ Safe Regression Test Selection تأکید می‌کند هزینه و فایده در شرایط مختلف تغییر می‌کند. یک مطالعهٔ صنعتی ۲۰۲۴ Fraunhofer/Vaadin نیز انتخاب بر اساس Side-effect را در CI ارزیابی کرده است. این شواهد مجوز ادعای «الگوریتم ما هیچ Faultی را جا نمی‌اندازد» نیست؛ واژهٔ Safe تعریف و شروط فنی دقیق می‌خواهد.

شبه‌کد Selection قابل‌توضیح

impacted = map(change_manifest, dependency_graph, risk_backlog)
mandatory = tests covering impacted critical controls

if mapping_is_stale or impact_is_unknown:
    mode = EXPANDED_OR_FULL
else:
    candidates = tests linked to impacted risks
    selected = mandatory + optimize(candidates, evidence_value, age, health, cost)

if any impacted critical control has no valid evidence:
    gate = HOLD_OR_EXCEPTION

emit selection_manifest(change, impacted, selected, excluded, reasons, model_version)
schedule full_fallback(cadence)
compare subset_to_fallback_and_calibrate()

Algorithm باید Version داشته باشد. اگر Weight، Dependency edge یا Critical rule عوض شد، بتوانید Selection قبلی را بازسازی کنید. «هوش مصنوعی گفت این تست‌ها مهم‌اند» بدون Feature، Model version، Confidence، Override و Audit trail برای Release evidence کافی نیست.

آزمایش بازتولیدپذیر: سرعت در برابر Evidence ریسک

برای ملموس‌شدن Trade-off، یک دادهٔ کاملاً ساختگی ساختیم: ۹ Control با وزن مجموع ۱۰۲، ۱۲ تست با زمان‌های ۱ تا ۱۰ دقیقه و پنج Defect کاشته‌شده. اعداد نه Benchmark صنعت‌اند و نه اثبات کیفیت RBT؛ فقط رفتار قرارداد Selection و Gate را نشان می‌دهند.

سناریوی A: مدل پیش از Calibration

تغییر Payment/Ledger پنج Control با مجموع وزن ۸۲ را Impacted می‌داند. سقف PR برابر ۳۰ دقیقه است.

روش تست‌ها زمان Evidence وزن‌دار Defectهای کاشته‌شدهٔ دیده‌شده
Fastest-first T01 تا T08 ۲۴ دقیقه ۲۶ از ۸۲ D2
Risk→Evidence selection T02، T03، T09، T10، T11 ۲۹ دقیقه ۸۲ از ۸۲ D1، D2، D3، D4

Fastest-first تعداد بیشتری Test اجرا کرد، اما Duplicate charge، Timeout-after-commit و Restore را ندید. نتیجه فقط نشان می‌دهد در این دادهٔ طراحی‌شده، Test count و سرعت معیار مناسبی برای Evidence نبودند.

سناریوی B: Full fallback نقطهٔ کور را آشکار می‌کند

Dependency Map، اتصال Payment→Notification را جا انداخته بود. در نتیجه T12 انتخاب نشد و D5—Notification retry تکراری—فقط در Full nightly دیده شد. Calibration این کارها را انجام داد:

  • Dependency edge جدید ثبت شد؛
  • وزن C9 از ۵ به ۲۰ رسید؛
  • C9 به Critical تبدیل شد؛
  • Mapping و Selection model نسخهٔ جدید گرفتند.
سقف Evidence Critical جاافتاده خروجی Gate
۳۰ دقیقه ۸۷ از ۱۰۲ C4: Restore/Reconciliation Infeasible / Hold
۴۰ دقیقه ۱۰۲ از ۱۰۲ هیچ Evidence-complete

نکتهٔ اصلی: مدل Risk-based هم به‌علت Mapping کهنه Failure را جا انداخت. Full fallback یک اتلاف کور نبود؛ حسگر Drift بود. بعد از Calibration، محدودیت ۳۰ دقیقه با همهٔ Critical ruleها ناسازگار شد و سیستم به‌درستی Hold داد. عدد ۸۷٪ نباید C4 جاافتاده را سبز کند.

خروجی خلاصه و روش بازتولید
A — same 30-minute compute budget
fastest-first: 24 min; evidence 26/82; detected [D2]
risk selection: 29 min; evidence 82/82; detected [D1,D2,D3,D4]

B — after nightly fallback and calibration
budget 30: evidence 87/102; missing critical [C4]; HOLD
budget 40: evidence 102/102; missing critical []; EVIDENCE-COMPLETE

الگوریتم همهٔ subsetهای واجد شرایط را زیر Budget بررسی و ترکیبی را انتخاب کرد که بیشترین وزن Evidence یکتا را پوشش می‌داد؛ در تساوی، زمان کمتر انتخاب شد. Critical completeness جدا از امتیاز سنجیده شد. Seeded defectها و Mapping عمداً طراحی شده‌اند، بنابراین خروجی صرفاً تست یک Decision model است.

گام هفتم: Evidence، Gate و Exception را قرارداد کنید

Risk score تصمیم انتشار نیست. برای هر Critical Risk باید قرارداد شفاف داشته باشید:

Gate PAY-CRITICAL
scope: changed payment and ledger paths
requires:
  - PAY-R01 duplicate-charge evidence = valid-passed
  - PAY-R04 timeout-after-commit evidence = valid-passed
  - PAY-R07 restore/reconciliation evidence age ≤ 7 days
rejects:
  - missing report
  - invalid environment manifest
  - retry-pass counted as first-pass
  - quarantined test without alternative evidence
on_fail: HOLD
exception: named owner + rationale + expiry + blast-radius + monitoring + rollback

Gateها باید با سند استراتژی تست هم‌راستا باشند: Strategy تعیین می‌کند برای این Decision horizon چه Evidence، Coverage، Fidelity و Authority لازم است؛ Selection فقط اجرای آن قرارداد را برای Change جاری بهینه می‌کند.

Result semantics را مخلوط نکنید

وضعیت معنا برای Risk رفتار Gate
Passed Failure تحت شرایط آزموده دیده نشد فقط اگر Run معتبر و Evidence تازه باشد
Failed Oracle واگرایی معتبر دید Critical معمولاً Hold
Blocked پیش‌نیاز اجازهٔ اجرا نداد Unknown؛ Pass نیست
Invalid Environment/Data/Tool نتیجه را بی‌اعتبار کرد Unknown؛ تکرار یا Evidence جایگزین
Not-run Evidence تولید نشده Unknown با علت صریح
Quarantined سیگنال قابل‌اعتماد نیست Coverage نیست؛ Owner و Expiry لازم

Exception یک دکمهٔ سبز نیست

Exception حداقل باید Risk، علت، Alternative evidence، Blast radius، Feature flag، Observability، Rollback trigger، Owner و Expiry داشته باشد. Exception منقضی‌شده خودکار بسته نشود؛ باید Release را متوقف یا دوباره تصویب کند.

خروجی برای ذی‌نفع را در قالب گزارش تست و تصمیم انتشار بسازید. Dashboard عملیاتی، Completion report و Release memo کار یکسانی ندارند.

گام هشتم: Calibration را بخشی از سیستم کنید

Risk model یک فرضیهٔ نسخه‌دار دربارهٔ آینده است. با هر Incident، Near miss، Change جدید و Evidence متفاوت باید آن را بازبینی کرد. سرفصل CTAL-TM ۳.۰ پیشنهاد می‌کند موفقیت RBT با پرسش‌هایی مثل مشارکت درست ذی‌نفعان، کشف زودهنگام Defectهای مهم، توضیح نتیجه به زبان ریسک و پایین‌تر بودن ریسک تست‌های Skipشده بررسی شود؛ این‌ها را به Review دوره‌ای تبدیل کنید.

سه حلقهٔ Calibration

  1. هر Build: Mapping confidence، Missing evidence، Selection reason و Invalidها.
  2. هفتگی/Release: subset در برابر Full fallback، Riskهای تازه، تست‌های کم‌ارزش و Age.
  3. ماهانه/Incident: Escapes، پیامد واقعی، Dependency drift، Threshold و تصمیم‌های Exception.

Metricهای Adoption، Effectiveness و Health را جدا کنید

خانواده Metric سالم Metric مستعد بازی
Adoption درصد Changeهای درون Scope با Risk delta مرورشده تعداد Risk tag
Evidence Critical risk با Evidence معتبر/تازه ÷ Critical impacted تعداد Test case
Feedback زمان تا اولین Failure قابل‌اقدام بر Risk class فقط کل Pipeline time
Effectiveness High-impact defect کشف‌شده پیش از Release و محل کشف Defect count خام
Escape Incident/Defect جاافتاده بر Risk و پیامد صفرکردن ظاهری Bug با تغییر Severity
Model health Miss در مقایسهٔ subset با fallback؛ Mapping age درصد Selection کوچک‌تر
Test health Invalid/Flaky/Quarantine age با مخرج Pass rate بدون تفکیک
Cost Compute و نگهداری در کنار Evidence/Outcome صرفه‌جویی دقیقه به‌تنهایی

راهنمای Test Automation در DORA بر Suiteهای سریع و قابل‌اعتماد در Delivery pipeline و Feedback پیوسته تأکید می‌کند؛ راهنمای CI در DORA نیز زمان Feedback و بازیابی Build را قابل‌اندازه‌گیری می‌داند. از این منابع نتیجه نگیرید که کم‌شدن زمان به‌تنهایی کیفیت را ثابت می‌کند؛ Stability، Evidence و Outcome را کنار Flow ببینید.

از Error Budget چه یاد بگیریم؟

در سامانهٔ Online، Signalهای Production می‌توانند شدت کنترل را تغییر دهند. سیاست Error Budget در Google SRE Reliability و سرعت تغییر را به یک سیاست مشترک وصل می‌کند. برای RBT می‌توان قانونی مشابه اما Context-specific داشت: اگر Budget خدمت مصرف شده یا Incident بحرانی باز است، Regression depth، Canary time یا Approval سخت‌گیرانه‌تر شود. Error budget جایگزین Risk analysis نیست و برای همهٔ Quality attributeها Oracle کافی نیست.

برنامهٔ ۳۰روزهٔ استقرار

روزهای ۱ تا ۵: محدوده و Baseline

  • یک Value Stream و Decision Owner انتخاب کنید.
  • Pilot Charter و Stop condition را امضا کنید.
  • چهار هفته دادهٔ Run، Incident، Escape و Pipeline را استخراج کنید.
  • Result semantics و Run identity را اصلاح کنید.

روزهای ۶ تا ۱۰: Risk و Evidence

  • Workshop چندنقشی برگزار کنید.
  • ۵ تا ۱۲ Risk واقعی، نه صدها Tag، ثبت کنید.
  • Critical rule، Uncertainty، Owner و Review trigger را تعیین کنید.
  • Risk→Evidence question را کامل کنید.

روزهای ۱۱ تا ۱۵: Suite mapping

  • Test inventory و Duration/Health/Fidelity بسازید.
  • Keep/Split/Move/Rewrite/Quarantine/Delete را تصمیم بگیرید.
  • Gapهای Oracle، Data، Dependency و Restore را Backlog کنید.
  • Critical evidence را ابتدا پایدار کنید.

روزهای ۱۶ تا ۲۰: Shadow mode

  • Selection را اجرا کنید اما Full suite را حذف نکنید.
  • Subset پیشنهادی را با نتیجهٔ Full مقایسه کنید.
  • Miss، False alarm، Mapping gap و Cost را ثبت کنید.
  • هیچ Gate خودکاری را فقط با یک هفته داده فعال نکنید.

روزهای ۲۱ تا ۲۵: Gate محدود

  • Critical ruleهای واضح را در یک Lane فعال کنید.
  • Selection Manifest و Explainability را Artifact کنید.
  • Expanded/full fallback و Triggerهای آن را تست کنید.
  • Exception و rollback drill اجرا کنید.

روزهای ۲۶ تا ۳۰: Calibration و تصمیم Scale

  • Metricها را در برابر Baseline و Stop condition مرور کنید.
  • هر Miss را تا Risk/Mapping/Boundary/Oracle/Gate طبقه‌بندی کنید.
  • Risk، Weight، Dependency و Test mapping را Version کنید.
  • تصمیم Continue/Adjust/Stop/Scale را با Owner نام‌دار ثبت کنید.

از یک Pilot به چند تیم چگونه Scale کنیم؟

Scale یعنی استانداردکردن قراردادهای مشترک و حفظ اختیار Context؛ نه کپی‌کردن ماتریس یک تیم برای همه.

هستهٔ مشترک سازمان

  • تعریف Resultها، Risk ID، Evidence manifest و Exception؛
  • حداقل Security/Privacy/Compliance/Recovery gate؛
  • Run identity، Retention و دسترسی Artifact؛
  • Metric dictionary و قواعد ضد Goodhart؛
  • Tooling برای Dependency، Selection، Audit و fallback؛
  • Community of Practice برای Calibration.

Overlay هر محصول

  • Outcome و Riskهای Context-specific؛
  • Impact scale و Critical rule متناسب با دامنه؛
  • PSP، Carrier، Device، Browser، Data residency یا مقررات مرتبط؛
  • Feedback budget و Cadence؛
  • Named owners و Release authority.

یک Platform Team می‌تواند Schema، Plugin، Dashboard و Pipeline primitive را فراهم کند، اما نباید Risk را به‌جای تیم محصول حدس بزند. QA Chapter نیز Facilitation و Independent challenge را تقویت می‌کند، نه اینکه Risk Backlog همهٔ تیم‌ها را مالک شود.

مدل بلوغ چهارمرحله‌ای

مرحله رفتار قابل‌مشاهده حرکت بعدی
۱. Explicit Risk/Owner/Evidence دستی اما شفاف Result و Mapping را قابل‌پرس‌وجو کنید
۲. Repeatable Pilot، Baseline، Review و fallback منظم Selection Manifest و Drift metric
۳. Executable Risk delta و Gate در CI اجرا می‌شود Calibration خودکار با Human review
۴. Adaptive Production signal شدت کنترل را تنظیم می‌کند پایش Bias، Model risk و cross-team learning

مرحلهٔ بالاتر لزوماً بهتر نیست. یک تیم کوچک با Release هفتگی ممکن است مدل دستی و Repeatable سالم‌تری از مدل ML پیچیده و غیرقابل‌توضیح داشته باشد.

مثال ایرانی: Checkout در روز کمپین

یک Marketplace ایرانی پیش از کمپین پایان ماه قصد تغییر Retry policy و Schema جدول payment_attempt را دارد. PSP-A پایدار است، PSP-B گاهی پس از ثبت تراکنش Timeout می‌دهد و Notification service صف مستقل دارد.

Risk delta

  • تغییر Retry، Risk دوباره‌برداشت را بالا می‌برد.
  • تغییر Schema، Restore و Reconciliation را منقضی می‌کند.
  • مبلغ canonical باید ریال بماند؛ تومان فقط Presentation است.
  • اعداد فارسی/عربی/لاتین باید پیش از Validation Canonical شوند.
  • تاریخ Settlement با UTC ذخیره و با Asia/Tehran نمایش داده شود.
  • Dependency اولیه، Notification را جا انداخته و پس از fallback اصلاح می‌شود.

Evidence plan

  1. Unit/property tests برای تبدیل Amount و Digit.
  2. API+DB concurrency برای Idempotency و unique invariant.
  3. PSP fault virtualization برای Timeout-before/after-commit.
  4. Contract test برای Payload و State mapping هر PSP.
  5. Restore rehearsal و Reconciliation با snapshot نسخه‌دار.
  6. System journey برای رسید، وضعیت و Retry کاربر.
  7. Canary محدود با Duplicate-charge alert و Kill switch.

تصمیم Release

اگر API و fault-injection پاس شوند اما Restore evidence پس از تغییر Schema قدیمی باشد، Pass rate کلی مهم نیست: Release باید Hold شود یا Scope تغییر کم شود. اگر Rehearsal معتبر، Critical evidence کامل و Notification monitoring فعال باشد، Release Decision Owner می‌تواند rollout مرحله‌ای را با Trigger روشن تصویب کند. تست توصیه می‌سازد؛ Authority نام‌دار تصمیم می‌گیرد.

ضدالگوهای رایج در اجرای RBT

  1. همه‌چیز High است: Scale تعریف نشده یا Trade-off سیاسی است؛ Critical rule و ظرفیت محدود را آشکار کنید.
  2. QA به‌تنهایی Risk می‌نویسد: پیامد کسب‌وکار و Dependency ناقص می‌ماند؛ Workshop چندنقشی کنید.
  3. Risk score بدون Evidence: امتیاز را به Question، Oracle و Artifact وصل کنید.
  4. تعداد تست = پوشش: پوشش را بر Risk/Evidence و Mechanism بسنجید.
  5. History-only selection: Feature جدید سابقه ندارد؛ Change impact و Uncertainty را اضافه کنید.
  6. Code-change-only selection: Config، Data، Schema، Flag و Dependency جا می‌ماند.
  7. حذف Full suite در روز اول: حسگر Drift را از بین می‌برد؛ Shadow mode و fallback داشته باشید.
  8. جمع Critical در میانگین: یک Restore جاافتاده پشت ۹۰٪ پنهان می‌شود؛ hard rule جدا بسازید.
  9. Invalid = Pass: Evidence نامعتبر Unknown است.
  10. Retry درمان Flake: اولین نتیجه را حفظ و علت را مالک‌دار کنید.
  11. Automation = RBT: Exploratory، Human، Production و Review evidence هم لازم‌اند.
  12. Tool-first rollout: ابتدا قرارداد و Pilot، سپس Plugin و Dashboard.
  13. یک ماتریس برای همه: Core مشترک و Product overlay جدا بسازید.
  14. صرفه‌جویی به‌عنوان موفقیت: Cost را کنار Evidence، Escape و Outcome گزارش کنید.
  15. مدل بدون Version: Selection گذشته بازتولید نمی‌شود؛ Manifest و calibration log نگه دارید.

چک‌لیست آمادگی برای Go-live

  • □ Pilot scope، Outcome و Decision horizon مشخص است.
  • □ Risk Owner و Release Decision Owner نام دارند.
  • □ Baseline پیش از تغییر ثبت شده است.
  • □ Risk Statementها Condition→Event→Impact دارند.
  • □ Uncertainty و Unknown از Low جداست.
  • □ هر Critical Risk یک Evidence question دارد.
  • □ Testها Risk، Boundary، Oracle، Owner و Duration دارند.
  • □ Invalid/Blocked/Not-run/Quarantined معادل Pass نیست.
  • □ Change manifest کد، Schema، Config، Flag و Dependency را می‌بیند.
  • □ Selection reason برای هر Build ذخیره می‌شود.
  • □ Critical completeness بیرون از امتیاز میانگین Gate دارد.
  • □ اگر Mapping نامطمئن باشد Expanded/full mode فعال می‌شود.
  • □ Full fallback Cadence و Owner دارد.
  • □ subset با fallback برای Miss مقایسه می‌شود.
  • □ Exception، Expiry، Monitoring و Rollback دارد.
  • □ Metricهای Adoption/Effectiveness/Health/Cost جدا هستند.
  • □ Incident می‌تواند Dependency، Weight، Oracle یا Suite را تغییر دهد.
  • □ داده و Artifact حاوی PII/Token پاک‌سازی و دسترسی‌گذاری شده‌اند.
  • □ Pilot Stop condition واقعاً قابل‌فعال‌شدن است.
  • □ تصمیم Scale با Evidence ثبت می‌شود، نه با رضایت جلسه.

پرسش‌های متداول

پیاده‌سازی تست مبتنی بر ریسک را از کجا شروع کنیم؟

از یک Value Stream محدود و یک تصمیم واقعی شروع کنید، نه از خرید ابزار یا امتیازدهی کل Backlog. Baseline بگیرید، ۵ تا ۱۲ Risk مهم بسازید، آن‌ها را به Evidence و Test موجود وصل کنید و ۳۰ روز در Shadow mode با Full suite مقایسه کنید.

آیا RBT یعنی تست‌های Low-risk را اجرا نکنیم؟

خیر. ممکن است Frequency، Depth یا Lane آن‌ها تغییر کند. Full fallback، Sampling یا Production monitoring می‌تواند باقی بماند. حذف دائمی Test تصمیم جداگانه‌ای است و به Evidence، هزینه، هم‌پوشانی و Risk appetite نیاز دارد.

چگونه Risk-based Test Selection را در CI ایمن کنیم؟

Critical ruleهای مستقل، Change/Dependency mapping نسخه‌دار، Selection manifest قابل‌توضیح، Unknown→Expanded/full mode، Full fallback منظم و مقایسهٔ subset با fallback لازم‌اند. بدون این Guardrailها، Selection سریع است اما قابل‌اعتماد نیست.

موفقیت RBT را با چه شاخصی بسنجیم؟

یک KPI کافی نیست. زمان تا Evidence قابل‌اقدام، Critical risk با Evidence معتبر، Miss در fallback، Escaped impact، Mapping age، Invalid/Flaky و Compute cost را کنار هم ببینید. Test count و Pass rate به‌تنهایی گمراه‌کننده‌اند.

هر چند وقت یک‌بار Riskها را بازبینی کنیم؟

Trigger-based بهتر از تقویم تنهاست: تغییر معماری/Dependency/Schema/Config، Incident، Exception، Evidence منقضی یا Release مهم باید Review را فعال کند. علاوه بر آن، مرور سبک در هر Iteration و Calibration عمیق ماهانه یا پس از Incident مناسب است.

جمع‌بندی

RBT زمانی اجرا شده است که یک تیم بتواند مسیر Change→Risk delta→Evidence→Gate→Decision→Learning را برای هر Release بازسازی کند. یک Matrix زیبا یا Pipeline کوتاه‌تر کافی نیست. Pilot کوچک، Risk Backlog زنده، Suite نگاشت‌شده، Selection قابل‌توضیح، Critical rule مستقل، Full fallback و Calibration مبتنی بر Production ستون‌های این سیستم‌اند.

از یک Journey شروع کنید، در Shadow mode حق اشتباه مدل را اندازه بگیرید و فقط وقتی Scale کنید که Evidence زودتر شده باشد بدون اینکه Unknown، Invalid یا Escape پشت درصدها پنهان شود.

منابع و مطالعهٔ بیشتر

دیدگاهتان را بنویسید