داشبورد چرخه میگوید «۹۶٪ تستها Passed شدهاند» و مدیر انتشار آمادهٔ Go است؛ اما مخرج این عدد فقط تستهای اجراشده است. یازده سناریوی پرریسک بازپرداخت هنوز Untested، پنج سناریوی درگاه Blocked و نتیجهٔ دو تست بعد از Rerun سبز شده است. عدد درست است، ولی تصویری که ساخته میشود غلط است.
مدیریت چرخه اجرای تست یعنی ساختن یک زنجیرهٔ قابلردیابی از تصمیم تا شواهد: چه چیزی، روی کدام نسخه و پیکربندی، با چه داده و Oracle، توسط چه کسی یا Runner، در چه زمانی اجرا شد؛ نتیجه چه بود؛ مانع یا Anomaly چگونه تعیین تکلیف شد؛ و در پایان چه ریسکهایی باقی ماند. هدف پرکردن نمودار Passed/Failed نیست؛ هدف تولید Evidence قابل اعتماد برای تصمیم بعدی است.
این راهنما Test Run و Test Cycle را از STLC، Test Plan و Pipeline job جدا میکند و یک مدل اجرایی برای Baseline، Entry gate، زمانبندی، وضعیت نتیجه، Triage، Rerun، Flaky test، تغییر دامنه، گزارش روزانه و Closure ارائه میدهد. مثال اصلی، چرخهٔ Candidate یک سامانهٔ پرداخت و بازپرداخت ایرانی است.
خلاصهٔ اجرایی چرخه اجرای تست
- هر Cycle باید یک Decision، محدوده، Risk، Owner و بازهٔ زمانی روشن داشته باشد.
- Test Run را به Build/commit، Configuration، Environment Manifest، Data set و نسخهٔ Case قفل کنید.
- Baseline اولیه را حفظ و هر تغییر دامنه یا نسخه را بهصورت Delta ثبت کنید.
- Entry criteria آمادگی برای شروع است؛ Exit criteria جایگزین قضاوت دربارهٔ ریسک انتشار نیست.
- Passed، Failed، Blocked، Untested، Inconclusive، Retest و Skipped باید قرارداد معنایی مشترک داشته باشند.
- Failed یعنی اختلاف Actual و Expected؛ تا پیش از Triage الزاماً Product defect نیست.
- Rerun نتیجهٔ اول را پاک نمیکند و سبزشدن Retry، Failure قبلی را بیاعتبار نمیسازد.
- Progress، Result distribution، Coverage و Product quality چهار مفهوم جدا هستند.
- Blocked و Untested را پشت Pass rate پنهان نکنید؛ Risk و Age آنها را نشان دهید.
- Closure یعنی تثبیت تاریخچه و تعیین تکلیف کار باز؛ الزاماً Release approval نیست.
Test Run، Test Cycle و Test Plan چه تفاوتی دارند؟
| مفهوم | تعریف عملی | هویت لازم |
|---|---|---|
| Test Case | شرط، ورودی، عمل و Expected result قابل تکرار | Case ID + version |
| Test Suite | مجموعهای سازمانیافته از Caseها؛ ممکن است بارها استفاده شود | Suite/repository version |
| Test | نمونهٔ یک Case که داخل Run ایجاد شده و آمادهٔ دریافت Result است | Run ID + Case ID/version |
| Test Result | رکورد یک Attempt با Status، زمان، Evidence و Context | Result/attempt ID |
| Test Run | اجرای انتخاب مشخصی از Caseها روی یک Build و Configuration | Run ID + immutable context |
| Test Plan | گروهبندی چند Run، معمولاً برای Config/Platformهای متفاوت | Plan ID + run matrix |
| Test Cycle | Timebox مدیریتی شامل یک یا چند Run، Triage، Control و Closure | Cycle ID + decision + baseline |
| Milestone/Release | هدف زمانی یا محصولی که چند Cycle/Plan را کنار هم میگذارد | Milestone/release ID |
| Pipeline job | یک اجرای فنی در CI/CD؛ ممکن است یک یا چند Run را تغذیه کند | Pipeline/job ID + commit SHA |
واژهٔ Test Cycle در همهٔ ابزارها معنای یکسان ندارد؛ بعضی محصولات آن را هممعنای Run و بعضی ظرف چند Run میدانند. نام مهم نیست، اما قرارداد داده مهم است: تیم باید بداند واحد برنامهریزی، واحد نتیجه و واحد بایگانی کداماند.
مرز این مقاله با STLC و فاز اجرای تست
چرخه حیات تست نرمافزار یا STLC کل فعالیتها از Analysis تا Completion را توضیح میدهد. فاز اجرای تست در STLC روی اجرای Case، مقایسهٔ Actual/Expected و ثبت Anomaly متمرکز است. موضوع این مقاله کنترل عملیاتی ظرف اجراست: چگونه چند Run را با هویت نسخهدار، صف کار، Triage، تغییر و تصمیم مدیریت کنیم.
Cycle با Release gate یکی نیست
یک Cycle میتواند برای PR، Nightly regression، Migration rehearsal، Browser matrix یا Release candidate ساخته شود. بستن آن فقط میگوید فعالیت تعریفشده خاتمه یافته و تاریخچه تثبیت شده است؛ تصمیم انتشار باید Evidenceهای دیگر، ریسک کسبوکار، امنیت، عملیات و اختیار صاحب تصمیم را نیز ببیند.
مدل کنترل: Charter تا Closure
چرخهٔ قابل اعتماد یک Loop دارد:
- Charter: سؤال تصمیم و محدوده را تعریف کنید.
- Baseline: Case/Build/Config/Environment/Data/Oracle را ثبت کنید.
- Ready: Entry gate و Smoke/health را اجرا کنید.
- Schedule: تستها را با Risk، dependency و ظرفیت مرتب کنید.
- Execute: هر Attempt را با Context و Evidence ثبت کنید.
- Triage: Anomaly، Blocker و Unknown را مالکدار کنید.
- Control: نسبت به Plan، Risk و زمان واکنش Continue/Pause/Replan بدهید.
- Close: کار باز و Residual risk را تعیین تکلیف و تاریخچه را آرشیو کنید.
این Loop خطی و یکباره نیست. Triage ممکن است Run جدید، Data reset یا تغییر Schedule بسازد؛ نکته آن است که هر تغییر ثبت شود و دادهٔ تاریخی بازنویسی نشود.
قالب Test Cycle Charter
پیش از ایجاد صدها Test، این Charter یکصفحهای را تکمیل کنید:
cycle_id: PAY-RC-1405-07
decision: آیا Build 8421 برای rollout پنجدرصدی بازپرداخت آماده است؟
owner: QA Lead
decision_owner: Release Manager
window: 1405/05/16 09:00 تا 1405/05/17 17:00
in_scope:
- refund create/cancel/retry
- duplicate callback and reconciliation
out_of_scope:
- load above 200 RPS
- settlement file of PSP-B
risk_focus:
- برداشت تکراری
- بازپرداخت بدون ثبت Ledger
- اختلاف ریال/تومان
- callback دیررس یا تکراری
baseline:
case_set: refund-regression@37
build: 8421
commit: 9f31c2a
environment_manifest: stg-pay@sha256:...
data_pack: refund-fa@12
oracle_contract: ledger-rules@8
configurations: [PSP-A/sandbox, PSP-B/sandbox]
entry_gate: READY-REFUND-v4
status_contract: RESULT-STATUS-v2
exit_and_stop: RC-REFUND-v3
change_policy: هر Build یا Config جدید = Run جدید
evidence_retention: 90d؛ بدون Token/PII
Decision را به شکل سؤال بنویسید
«اجرای Regression» Activity است، نه هدف. «آیا رفتار Refund روی Build و دو PSP تعریفشده برای Canary آماده است؟» دامنه، Evidence لازم و صاحب تصمیم را روشن میکند. اگر Cycle هیچ تصمیم یا یادگیری را پشتیبانی نمیکند، احتمالاً Suite از روی عادت اجرا میشود.
Entry، Exit و Stop را جدا کنید
- Entry: آیا اجرای معنیدار میتواند شروع شود؟
- Exit: آیا Evidence برنامهریزیشده بهاندازهٔ توافقشده جمع شده است؟
- Stop: چه شرایطی ادامهٔ اجرا را بیارزش یا خطرناک میکند؟ مانند Build اشتباه، فساد داده یا Side effect واقعی.
- Release criteria: چه ترکیبی از Evidence و Residual risk برای تصمیم انتشار قابلقبول است و چه کسی اختیار آن را دارد؟
Baseline تغییرناپذیر بسازید
نتیجه بدون هویت محیط و نسخه قابل مقایسه نیست. حداقل Baseline هر Run باید این فیلدها را داشته باشد:
| بعد | نمونه | چرا لازم است؟ |
|---|---|---|
| Testware | Case set ۳۷، Case version ۱۲ | Expected result بعداً ممکن است تغییر کند |
| Software | Build ۸۴۲۱، commit SHA، image digest | نام «آخرین Build» مبهم و متغیر است |
| Configuration | Android 15/Chrome 138/PSP-A | Passed در یک Config به دیگری تعمیمپذیر نیست |
| Environment | Manifest hash، Schema ۲۱۴، flags | Drift میتواند Result را عوض کند |
| Data | Data pack ۱۲، seed، namespace | ورودی و State باید بازتولیدپذیر باشد |
| Dependency | PSP sandbox contract v6 | Sandbox یا Virtual service رفتار خاص دارد |
| Oracle | Ledger rule v8 | معیار Pass/Fail نیز نسخه دارد |
| Runner | Playwright ۱.x، browser build، manual actor | تفاوت ابزار/انسان روی Evidence اثر میگذارد |
| Locale/time | fa-IR، Asia/Tehran، Jalali/Gregorian | تاریخ، رقم، جهت و Cutoff مالی حساساند |
برای نسخهگذاری Infrastructure، داده، Dependency و Drift از راهنمای مدیریت محیط تست استفاده کنید. «Staging» بهتنهایی Environment ID نیست.
Build یا Scope عوض شد؛ Run قبلی را ویرایش نکنید
Patch جدید، commit جدید یا Configuration جدید Evidence تازه میخواهد. Run/Attempt جدید را به قبلی Link کنید. Baseline قبلی باید نشان دهد چه چیزی واقعاً اجرا شده بود. اضافهشدن Case اضطراری نیز با زمان، دلیل، درخواستکننده و اثر روی مخرج ثبت شود؛ نمودار تاریخی نباید بیصدا تغییر کند.
Entry gate قابل اجرا طراحی کنید
عبارت «محیط آماده است» قابل آزمون نیست. Gate باید Check و Evidence داشته باشد:
- Artifact موردنظر با digest صحیح Deploy شده است.
- Schema/Config/Feature flag با Manifest تطبیق دارد.
- Health فقط Process up نیست؛ مسیر حیاتی و Dependency لازم پاسخ معتبر میدهند.
- Data pack با Namespace مشخص Seed و قابلیت Reset تأیید شده است.
- Account، Role و Secret آزمایشی معتبر و کماختیارند.
- Test caseهای داخل Baseline Review شده و Expected result قابل مشاهده است.
- Log/metric/trace یا Evidence لازم قابل دسترسی و Clockها همگاماند.
- Blocker شناختهشده با Scope و Workaround ثبت شده است.
- Owner محیط، Triage و تصمیم در Window اجرا در دسترساند.
اگر Gate Fail شد، Run را بهعنوان Product failure قرمز نکنید. Cycle را Not ready/Pause کنید و علت را Environment، Data، Dependency یا Testware ثبت کنید. شروعکردن تست روی بستر خراب فقط صفی از False failure میسازد.
دامنه و ترتیب اجرا را بر اساس ریسک بچینید
همهٔ Caseها ارزش و فوریت یکسان ندارند. اول Risk itemها و Coverage targetها را به Testها Trace کنید؛ سپس Schedule را با این عوامل بسازید:
- Impact و likelihood شکست؛
- تازگی و سطح تغییر کد/Config/Schema؛
- مسیرهای درآمد، امنیت، داده و انطباق؛
- Dependency و ترتیب لازم برای Setup؛
- مدت، ظرفیت Runner و امکان Parallel؛
- توان تشخیص سریع Build یا Environment خراب؛
- هزینهٔ دیررسشدن Signal نسبت به زمان تصمیم.
ترتیب پیشنهادی، قانون جهانی نیست
- Readiness و Smoke برای جلوگیری از اتلاف؛
- Critical path و تستهایی که تصمیم را سریع تغییر میدهند؛
- Changed-area و High-risk regression؛
- Configurationهای پرترافیک یا پراثر؛
- Coverage تکمیلی و Exploratory charter؛
- Long-running، destructive یا costly tests در Window کنترلشده.
گاهی تست Migration باید قبل از UI و گاهی Contract provider پیش از Consumer E2E اجرا شود. Schedule را از Dependency graph و Risk بسازید، نه از شمارهٔ Case.
ظرفیت را با صف کار اشتباه نگیرید
برآورد مجموع ساعتها بهتنهایی Duration را نمیگوید؛ Setup، انتظار Fix، محدودیت PSP، Parallelism و Triage روی تقویم اثر دارند. روشهای تبدیل Effort به Forecast در راهنمای تخمین تست نرمافزار آمده است.
قرارداد وضعیتهای Test Result
| Status | معنای دقیق | Evidence حداقلی |
|---|---|---|
| Untested | برای این Test هنوز Attempt معتبر ثبت نشده | دلیل ندارد؛ اما Age و Risk دیده شود |
| Passed | Observationهای تعریفشده در این Attempt با Expected result منطبقاند | Build/Config + assertion/مشاهده |
| Failed | حداقل یک Actual result با Oracle اختلاف دارد | Expected/Actual + نقطهٔ Failure + Context |
| Blocked | پیششرط بیرونی مانع اجرای معنیدار شده است | Blocker ID + owner + affected scope |
| Inconclusive | Attempt انجام شده ولی Evidence برای Pass/Fail کافی نیست | ابهام، دادهٔ مفقود و اقدام بعدی |
| Retest | کار برای Attempt بعدی لازم است؛ Outcome جدید نیست | Fix/config change + target build |
| Skipped/Not applicable | طبق تصمیم ثبتشده اجرا نمیشود یا به Config مربوط نیست | Reason + approver + Risk disposition |
| Quarantined | Test غیرقابل اعتماد موقتاً از Gate جدا شده است | Issue + owner + expiry + coverage gap |
TestRail بهصورت پیشفرض Passed، Failed، Blocked، Retest و Untested دارد و امکان Status سفارشی نیز فراهم میکند. نامهای سفارشی فقط وقتی مفیدند که Final/non-final بودن، مجوز انتقال، Evidence و اثر آنها بر گزارش تعریف شده باشد.
Passed به معنی «محصول بدون باگ» نیست
Passed فقط ادعای محدود همان Case، نسخه، داده، محیط و Observation است. ممکن است Oracle ناقص باشد، Scope کوچک باشد یا Risk دیگری اصلاً Test نشده باشد. Pass rate را «درصد کیفیت» ننامید.
Failed به معنی «یک باگ قطعی» نیست
Failure یک Anomaly است. علت میتواند Product، Test script، Test data، Environment، Dependency یا Oracle باشد. پس از Triage، اگر Product defect تأیید شد، گزارش مستقل و قابل بازتولید بسازید؛ قالب کامل در راهنمای گزارش باگ حرفهای موجود است.
هر Result چه دادهای داشته باشد؟
result_id / attempt_no
cycle_id / run_id / test_id / case_version
build / commit / configuration / environment_manifest
data_namespace / dependency_label
started_at / finished_at / duration
actor_or_runner / tool_version
status
expected_observation
actual_observation
failed_step_or_assertion
evidence_links
trace_id / correlation_id / log_window
defect_or_blocker_ids
failure_classification
comment / next_action
Evidence باید برای فهم ادعا کافی باشد، نه اینکه از هر Pass یک ویدئوی حجیم تولید شود. برای تست خودکار Assertion، artifact و correlation کافی انتخاب کنید؛ برای تست دستی، Expected/Actual و شواهد نقطهٔ Failure را ثبت کنید. Trace و Log را به Run ID و Attempt وصل کنید تا Request چندسرویسی قابل دنبالکردن باشد.
Evidence امن و کمینه نگه دارید
Screenshot، HAR، Log و Video ممکن است شماره موبایل، کد ملی، Token، Cookie، PAN یا دادهٔ مالی داشته باشند. پیش از Upload آنها را Mask کنید، دسترسی و Retention بدهید و Secret را هرگز در Comment نچسبانید. شواهد آلوده مسئلهٔ امنیتی است، نه مستندسازی بهتر.
اجرای دستی و خودکار را در یک Truth model جمع کنید
پروتکل اجرای دستی
- Test و Baseline را بازبینی کنید؛ از Case خارج از Config اجرا نکنید.
- Precondition و Data namespace را تأیید کنید.
- زمان شروع و نسخه را ثبت کنید.
- Stepها را اجرا، اما Observationهای خارج از Script را نیز نادیده نگیرید.
- در اولین اختلاف، Evidence پایدار بگیرید و از دستکاری داده قبل از Capture پرهیز کنید.
- Status را با قرارداد تیم انتخاب و Next action را ثبت کنید.
- Cleanup و Side effect را تأیید کنید.
قرارداد ورود نتیجهٔ Automation
- Job باید commit SHA، build، configuration، run ID و tool version را ارسال کند.
- Mapping میان Automated test و Case ID پایدار و قابل Version باشد.
- Upload نتیجه idempotent باشد تا Retry شبکه Duplicate result نسازد.
- Partial upload یا crash Runner از Product failure جدا شود.
- stdout خام بهجای Expected/Actual و Artifact ساختاریافته پذیرفته نشود.
- Bulk pass فقط برای Testهایی ثبت شود که واقعاً Assertion آنها اجرا شده است.
- Attemptهای Retry در History بمانند؛ آخرین سبز، قرمز اول را overwrite نکند.
در Pipelineهای سریع و کند، زمان رسیدن Evidence باید با تصمیم هماهنگ باشد؛ راهنمای Continuous Testing در CI/CD این Feedback budget و Gateها را تشریح میکند.
Triage؛ Failure را به اقدام تبدیل کنید
Triage صرفاً جلسهٔ Severity نیست. برای هر Failed، Blocked یا Inconclusive این مسیر را طی کنید:
- Identity: آیا Case/Build/Environment/Data دقیق است؟
- Reproduce: آیا با همان Baseline و بدون تغییر قابل مشاهده است؟
- Compare: Expected/Oracle معتبر است یا Requirement تغییر کرده؟
- Classify: Product، Test، Data، Environment، Dependency یا Unknown؟
- Assess: Impact، likelihood، exposure و affected scope چیست؟
- Act: Defect، Test fix، Data reset، Environment repair، provider escalation یا investigation؟
- Own: Owner، deadline و شرط Retest چیست؟
| طبقه | نمونه | مسیر |
|---|---|---|
| Product | Callback تکراری دو Refund میسازد | Defect + fix + targeted regression |
| Test | Selector با تغییر متن شکسته است | Test issue؛ Coverage gap تا Fix |
| Data | Merchant آزمایشی سقف روزانه را پر کرده | Reset/namespace + تحلیل آلودگی |
| Environment | Feature flag با Manifest اختلاف دارد | Pause affected runs + repair/drift record |
| Dependency | PSP sandbox پاسخ نمیدهد | Blocker + provider/virtual fallback policy |
| Unknown | Trace ناقص و Failure متناوب | Investigation؛ نه بستن با حدس |
Severity، Priority و Status را مخلوط نکنید
Severity اثر Failure، Priority ترتیب کار و Result status نتیجهٔ Attempt است. یک Failed با Severity پایین ممکن است فوری Fix شود؛ یک Blocked پرریسک ممکن است Release را متوقف کند، با اینکه Product defect ثبت نشده است.
Rerun و Retest؛ نتیجهٔ قبلی را پاک نکنید
| وضعیت | عمل درست | تفسیر |
|---|---|---|
| Runner crash قبل از Assertion | Attempt جدید با Infrastructure classification | Outcome محصول نامعلوم است |
| همان SHA/Config، Failure سپس Pass | هر دو Attempt حفظ؛ Flaky candidate | Pass دوم Failure اول را رد نمیکند |
| Product fix با Build جدید | Retest در Run/attempt مرتبط با Build جدید | Evidence تازه برای نسخهٔ تازه |
| Data reset بدون تغییر نرمافزار | Attempt جدید با علت Data ثبتشده | اثر State قبلی باید تحلیل شود |
| Oracle اشتباه بود | Case version جدید؛ نتیجهٔ قدیمی reclassify با audit، نه حذف | تاریخچهٔ تصمیم حفظ شود |
| صرفاً برای سبزکردن Dashboard | ممنوع | Selection bias و پنهانکردن Signal |
GitHub Actions هنگام Rerun همان commit SHA و ref اجرای اولیه را بهکار میگیرد؛ این برای مقایسه مفید است، اما علت Rerun، تغییر محیط و شمارهٔ Attempt همچنان باید ثبت شود. Retry خودکار را محدود، قابل مشاهده و جدا از Outcome نهایی طراحی کنید.
Flaky test و Quarantine قرارداد میخواهند
Flaky یعنی با همان Code و Context ظاهراً ثابت، نتیجهٔ Pass و Fail دیده میشود؛ علت واقعی میتواند Test یا رفتار nondeterministic محصول باشد. Quarantine یک درمان نیست. برای هر مورد Issue، owner، علت فرضی، تاریخ انقضا، دفعات Failure و Coverage gap ثبت کنید. Test قرنطینهشده نباید در مخرج Gate سالم وانمود شود.
Change control در میانهٔ Cycle
چرخه ثابت نمیماند؛ Requirement، Build، Case، Data و زمان تغییر میکند. برای هر تغییر این Record را نگه دارید:
change_id:
requested_at / requester / approver:
type: scope | build | config | case | data | oracle | schedule
before:
after:
reason:
affected_runs_and_results:
risk_impact:
baseline_delta:
decision: accept | split-run | replan | stop
چه زمانی Run تازه بسازیم؟
- Build/commit یا image digest تغییر کرده است؛
- Config یا Environment boundary معنیدار عوض شده است؛
- Expected result/Oracle تصحیح شده است؛
- Case set بهاندازهای تغییر کرده که مخرج قبلی گمراهکننده است؛
- هدف تصمیم یا Window جدید است؛
- Cycle قبلی بسته و آرشیوی شده است.
برای تغییر کوچک Metadata میتوان Run را ادامه داد، اما Delta باید آشکار باشد. قاعده را پیشاپیش در Charter بنویسید تا زیر فشار Release تغییر نکند.
Monitoring و Control؛ Dashboard باید تصمیم بسازد
طبق ISTQB، Monitoring مقایسهٔ پیوستهٔ پیشرفت واقعی با Plan است و Control اقدام لازم برای رسیدن به هدف تست. نمودار بدون Trigger و Action فقط تزئین است.
| Signal | Trigger نمونه | Action از پیش توافقشده |
|---|---|---|
| High-risk Untested | پس از نیمهٔ Window هنوز بیش از ۲۰٪ | Reorder، ظرفیت یا Scope را بازتصمیم کنید |
| Blocked age | Blocker بحرانی بیش از ۲ ساعت | Environment owner/escalation؛ affected run Pause |
| Failure burst | ۵ Failure با signature مشترک | Suite را متوقف و Build health را بررسی کنید |
| Unknown ratio | بیش از آستانهٔ محلی | Instrumentation/Triage capacity اضافه کنید |
| Rerun rate | روند افزایشی سه Cycle | Flake investigation و محدودکردن Retry |
| Environment drift | Manifest mismatch | نتایج پس از Drift را جدا و اعتبارشان را ارزیابی کنید |
متریکهای چرخه و فرمول درست
ابتدا نام مخرج و Snapshot time را بنویسید. اگر Baseline عوض شد، مقدار Original و Current هر دو لازماند.
- Execution coverage: تعداد Testهای دارای Attempt معتبر ÷ Baseline قابل اجرا × ۱۰۰
- Addressed: Passed + Failed + Inconclusive + Blocked + dispositioned Skip؛ قراردادی جدا از Execution coverage
- Result distribution: سهم هر Status از مخرج صریح؛ نه یک Pass rate تنها
- High-risk coverage: Risk itemهای پراثر با Evidence کافی ÷ کل Risk itemهای پراثر
- Blocked age: زمان از ثبت Blocker تا رفع/Disposition؛ همراه با Risk
- Failure classification: Product/Test/Data/Environment/Dependency/Unknown با Count و Trend
- Rerun rate: Testهای دارای بیش از یک Attempt ÷ Testهای Attemptشده
- Flaky candidate rate: Testهای دارای Pass و Fail روی Baseline همسان ÷ Testهای Attemptشده
- Evidence completeness: Resultهای نیازمند Evidence که فیلدهای اجباری را دارند ÷ همان Resultها
- Cycle time: از Entry accepted تا Closure؛ همراه با Waiting و Active time
Pass rate چه چیزی را نمیگوید؟
اگر ۴۳ Passed، شش Failed، پنج Blocked، دو Inconclusive و ۱۶ Untested از Baseline ۷۲ دارید، «۴۳ از ۵۱ Attempt قطعی Pass» میتواند ۸۴٫۳٪ باشد؛ اما فقط ۷۰٫۸٪ Baseline Attempt شده و ۲۱ Test هنوز Blocked/Untested است. هیچکدام بهتنهایی احتمال Incident یا آمادگی Release را نشان نمیدهد.
Trend فقط با قرارداد ثابت قابل مقایسه است
تغییر Status semantics، Case set، Risk mix، Runner یا مخرج میتواند Trend را جابهجا کند. Metric dictionary شامل نام، سؤال، فرمول، منبع، owner، cadence، segmentation و محدودیت بسازید. برای تبدیل گزارش به تصمیم، از راهنمای گزارش تست و Release readiness کمک بگیرید.
Cadence عملیاتی یک Cycle
Kickoff کوتاه
- Decision، Baseline، Entry/Exit/Stop و ownerها را تأیید کنید.
- محدودهٔ Config و Riskهای حساس را مرور کنید.
- کانال Triage، SLA پاسخ و Escalation را مشخص کنید.
کنترل در طول روز
- Queue آماده، Blockerهای جدید و ظرفیت را بررسی کنید.
- Failure cluster را قبل از تولید Duplicate defect جدا کنید.
- Build/Environment change را به Runها Propagate و ثبت کنید.
- High-risk Untested را جلوتر از تستهای کماثر قرار دهید.
گزارش پایان Window
Cycle/Run + snapshot time:
Baseline original/current + delta:
Build/config/environment:
Status distribution:
High-risk coverage and gaps:
New failures by classification:
Blocked/unknown with owner and age:
Forecast vs window:
Control actions taken:
Decision needed from whom/by when:
گزارش روزانه نباید Completion report را تقلید کند؛ هدف آن اقدام روی انحراف است.
Continue، Pause، Replan یا Close؟
| تصمیم | زمان مناسب | خروجی |
|---|---|---|
| Continue | Signal معتبر و Plan هنوز جواب میدهد | Schedule جاری + next checkpoint |
| Pause | Build/Environment/Data خراب یا Side effect خطرناک است | Stop reason + owner + resume gate |
| Replan | زمان، Risk، Scope یا Dependency تغییر کرده است | Baseline delta + trade-off + approval |
| Split | Build/Config/هدف متفاوت باید جدا سنجیده شود | Run جدید و Link به Parent cycle |
| Close | Activity خاتمه و تمام کار باز disposition شده است | Archive + completion evidence |
Exit criteria یک فرمول جادویی نیست
«۹۵٪ Passed و صفر Critical defect» ممکن است تستهای حیاتی Untested، Blocked یا Oracle ضعیف را پنهان کند. Exit را چندبعدی بنویسید: Coverage ریسک، وضعیت کار باز، Confidence شواهد، Environment validity، Defectهای باز، Unknownها و Risk acceptance. Target محققنشده را با Waiver مالکدار ثبت کنید؛ عدد را پس از دیدن نتیجه تغییر ندهید.
Closure و آرشیو قابل ممیزی
- Baseline original/current و همهٔ Deltaها را Freeze کنید.
- Untested، Blocked، Inconclusive و Quarantined را تکتک disposition کنید.
- Defect/Issueها را Link و Duplicateها را روشن کنید.
- Resultهای بدون Context/Evidence ضروری را تکمیل کنید.
- Residual risk و Assumptionها را با owner/expiry ثبت کنید.
- Test data، Account، Lease و Environment موقت را Cleanup کنید.
- Progress و Completion report را از snapshot یکسان بسازید.
- Run/Plan را در ابزار Close/Archive کنید؛ تغییر بعدی باید Run جدید باشد.
- یک Improvement candidate قابل آزمایش به Backlog ببرید.
در TestRail، بستن Run یا Plan نتایج را آرشیو میکند، تغییرات بعدی Case را به تستهای تاریخی اعمال نمیکند و Result جدید نمیپذیرد. این ویژگی برای History قابل اتکا مفید است؛ پیش از Close مطمئن شوید کار باز تعیین تکلیف شده، چون Closure صرفاً دکمهٔ مرتبسازی نیست.
مثال کامل: Cycle بازپرداخت در یک فینتک ایرانی
۱. Charter و Baseline
تصمیم: آیا Build ۸۴۲۱ سرویس Refund برای Canary پنجدرصدی آماده است؟ Baseline شامل ۷۲ Test روی PSP-A و PSP-B، مبلغهای ریالی، callback تکراری/دیررس، timeout، Idempotency، Ledger و Reconciliation است. Data pack نسخهٔ ۱۲، Schema ۲۱۴، Feature flag مشخص و دو Sandbox در Manifest ثبت میشوند.
۲. Entry gate
Deploy digest و Schema صحیحاند؛ PSP-A سالم است، اما PSP-B occasionally timeout دارد. چون Contract چرخه اجازه میدهد Scope PSP-A شروع شود و PSP-B بهصورت Blocker جدا بماند، Cycle با Risk note آغاز میشود؛ سلامت PSP-B بهعنوان «سبز» جعل نمیشود.
۳. اجرای Window اول
| Status | تعداد | تفسیر |
|---|---|---|
| Passed | 43 | Observationهای تعریفشده منطبقاند |
| Failed | 6 | نیازمند Triage؛ نه شش باگ قطعی |
| Blocked | 5 | چهار PSP-B و یک حساب Merchant |
| Inconclusive | 2 | Trace ناقص برای callback |
| Untested | 16 | چهار مورد High-risk |
Execution coverage برابر ۵۱÷۷۲ یا ۷۰٫۸٪ است. Triage شش Failure را به دو Product defect، یک Test defect، یک Data issue، یک Environment drift و یک Dependency anomaly تقسیم میکند. پس Dashboard «شش باگ» نمیسازد.
۴. Control action
- پس از Drift، affected Resultها علامتگذاری و محیط Repair میشود.
- چهار Test پرریسک Untested جلوتر از Cosmetic regression میآید.
- برای دو Product defect، Build ۸۴۲۲ ساخته و Retest در Run جدید Link میشود.
- Failureهای ۸۴۲۱ باقی میمانند؛ نتیجهٔ Build جدید آنها را overwrite نمیکند.
- PSP-B بعد از دو ساعت طبق SLA Escalate و Run مربوط Pause میشود.
۵. تصمیم و Closure
چرخهٔ Build ۸۴۲۱ با Recommendation «No-Go برای Scope کامل؛ ادامهٔ محدود PSP-A فقط با تأیید صاحب ریسک» بسته میشود. Runهای ۸۴۲۲ و PSP-B Follow-up جدا هستند. چهار Gap پرریسک، دو Blocker و Assumption مربوط به Sandbox در Completion report باقی میمانند. این گزارش شفافتر از یک Pass rate سبز است.
Cycle در Agile، Scrum و DevOps
Scrum یک «فاز تست بعد از توسعه» تعریف نمیکند. Increment باید Definition of Done را برآورده کند و چند Increment میتواند در Sprint ساخته شود. Test Cycle ابزار داخلی تیم برای ساماندهی Evidence است، نه بهانهای برای انتقال همهٔ تستها به روز آخر Sprint.
| Context | نمونهٔ Cycle/Run | نکتهٔ کنترل |
|---|---|---|
| PR | Changed-area unit/component/contract | commit ثابت، Feedback سریع، retry آشکار |
| Nightly | Regression وسیع و matrix | Trend، flake و environment drift |
| Sprint | Evidence برای PBI/Increment | با DoD یکپارچه؛ نه mini-waterfall |
| Release candidate | Risk-based system/rehearsal | Baseline قفل، residual risk و authority |
| Production verification | Synthetic/canary observation | Blast radius، stop و data safety |
در CI/CD، Pipeline job و Test Run را با commit و artifact یکسان Link کنید. Job retry، environment rerun و product retest سه رخداد متفاوتاند و نباید در یک Result آخر پنهان شوند.
پیادهسازی در TestRail بدون وابستگی به ابزار
- Milestone را برای هدف Release/زمان، Plan را برای ماتریس چند Run و Run را برای Case set یک Configuration بهکار ببرید.
- نام Run را ماشینی و قابل جستوجو کنید:
PAY-RC1405-07 | build-8421 | PSP-A | fa-IR. - Build/commit، Manifest، Data pack، Config و Pipeline URL را Result/Run field کنید.
- Case version و References را به Requirement/Risk وصل کنید.
- Status سفارشی را کم و با قرارداد Final/non-final نگه دارید.
- Result comment را جای Issue tracker یا Secret store نکنید.
- Configuration matrix را در Plan بسازید؛ Case تکراری برای هر Browser ایجاد نکنید.
- Closure را بعد از Disposition انجام دهید تا Snapshot تاریخی ثابت بماند.
همین مدل در هر ابزار دیگر نیز قابل اجراست. Tool باید History append-only یا audit trail، API idempotent، Result-level context، permission، configuration matrix، attachment policy و export قابل اتکا داشته باشد. خرید ابزار جای Status contract و ownership را نمیگیرد.
نقشها و اختیارها
| نقش | مسئولیت | اختیار |
|---|---|---|
| Cycle owner/Test lead | Charter، Baseline، Schedule و Control | Pause/Replan طبق قرارداد |
| Tester/Runner owner | Execution و Evidence معتبر | ثبت Outcome؛ نه پذیرش ریسک کسبوکار |
| Developer | تحلیل و Fix Product/Test issue | ارائهٔ evidence فنی و target build |
| Environment/Data owner | Health، Manifest، Data و Reset | اعلام invalid window یا repair |
| Product/Risk owner | Impact، Scope و Risk acceptance | پذیرش/رد residual business risk |
| Release manager | ترکیب Evidenceهای انتشار | Go/No-Go/Rollout طبق governance |
QA میتواند Recommendation قوی بدهد و در شرایط Stop تعریفشده Cycle را متوقف کند؛ اما نباید وانمود کند تنها مالک تصمیم کسبوکار است. مسئولیت مشترک به معنی اختیار مبهم نیست.
قیود عملی تیمهای ایرانی
- دسترسی ناپایدار Vendor یا تحریم را با Self-host/export path و Runbook جایگزین پیشبینی کنید.
- زمانها را با timezone صریح و در صورت نمایش شمسی، مقدار ISO/Gregorian قابل تبادل نیز ذخیره کنید.
- ریال/تومان، ارقام فارسی/لاتین، نیمفاصله، RTL و متن دوزبانه را Configuration/Data dimension بدانید.
- Sandbox درگاه را Production-equivalent فرض نکنید؛ Contract، محدودیت و زمان قطعی آن را Label کنید.
- Evidence مالی و هویتی را Mask و دسترسی/Retention آن را با سیاست سازمان هماهنگ کنید.
- در قطعی اینترنت یا پیامک، Blocked را Product Failed گزارش نکنید؛ Dependency evidence و affected risk را ثبت کنید.
برنامهٔ ۳۰ روزه استقرار
هفتهٔ اول: قرارداد و Baseline
- یک Cycle پرتکرار را انتخاب و واژهنامهٔ Run/Test/Result/Attempt بسازید.
- Status contract، فیلدهای اجباری و Change policy را تصویب کنید.
- Build/commit/Config/Manifest/Data را به Baseline اضافه کنید.
هفتهٔ دوم: Gate و Triage
- Entry/Smoke ماشینی و Stop criteria را Pilot کنید.
- Failure taxonomy، Owner و Triage SLA را روی یک Window اجرا کنید.
- Rerun reason و Attempt history را اجباری کنید.
هفتهٔ سوم: Control و گزارش
- Dashboard را از Pass rate تنها به Risk coverage، Blocked age و Unknown گسترش دهید.
- Trigger→Actionهای Continue/Pause/Replan را تعریف کنید.
- Daily progress template و Completion snapshot را هممنبع کنید.
هفتهٔ چهارم: Closure و آزمایش بهبود
- Runهای کامل را پس از Disposition ببندید و Follow-up را جدا کنید.
- Rerun/Flaky/Evidence completeness را Baseline کنید.
- یک فرضیهٔ بهبود با Guardrail و تاریخ تصمیم ثبت کنید؛ الگوی کامل در راهنمای بهبود مستمر QA آمده است.
اشتباههای رایج در مدیریت Test Run
- Pass rate بدون مخرج: Untested و Blocked پرریسک پنهان میشوند.
- ویرایش Run پس از Build جدید: Evidence چند نسخه مخلوط میشود.
- Fail مساوی Bug: Test/Data/Environment/Dependency issue به Product نسبت داده میشود.
- Retry تا سبزشدن: Flakiness و Failure واقعی پاک میشود.
- Blocked بهعنوان Untested: مانع و مسئولیت عملیاتی ناپدید میشود.
- Bulk pass بدون Assertion: Activity به Evidence جعلی تبدیل میشود.
- Statusهای سفارشی زیاد: گزارش و Automation semantics مبهم میشود.
- Close برای مرتبشدن صفحه: کار باز و Residual risk بدون Disposition میماند.
- Screenshot حاوی Token/PII: Evidence به رخداد امنیتی تبدیل میشود.
- Cycle جدا از Delivery: تست به فاز پایانی و صف انتظار تبدیل میشود.
چکلیست نهایی مدیریت چرخه اجرای تست
پیش از شروع
- Decision، Scope، exclusions، Risk و owner روشن است.
- Baseline نسخهدار Case/Build/Config/Environment/Data/Oracle ثبت شده است.
- Entry/Exit/Stop، Status contract و Change policy وجود دارد.
- Schedule با Risk/dependency/capacity هماهنگ است.
هنگام اجرا
- هر Result به Attempt، Context و Evidence کافی وصل است.
- Failed پیش از Triage با Product defect یکی نشده است.
- Blocked/Unknown owner و Age دارد.
- Rerun علت دارد و Attempt قبلی حفظ شده است.
- Baseline delta و اثر آن بر مخرج آشکار است.
- Triggerهای Control به اقدام منجر میشوند.
هنگام بستن
- همهٔ Untested/Blocked/Inconclusive/Quarantined disposition شدهاند.
- Risk coverage و Residual risk کنار Result distribution گزارش شدهاند.
- تاریخچه، لینک Defect و Evidence ضروری کامل است.
- Data/Environment cleanup و Retention انجام شده است.
- Run آرشیو و Follow-up در Run جدید ساخته شده است.
- Recommendation با Decision authority اشتباه نشده است.
جمعبندی
مدیریت مؤثر چرخه اجرای تست از یک Dashboard سبز شروع نمیشود؛ از قرارداد Evidence شروع میشود. Test Run باید بگوید کدام Case روی کدام نسخه، محیط، داده و Config چه نتیجهای داده است. Cycle باید تغییر، Blocker، Failure، Rerun و Risk gap را بدون پاککردن تاریخچه کنترل کند. در این مدل، Passed ادعایی محدود، Failed یک Anomaly نیازمند Triage، Closure یک Snapshot ممیزیپذیر و Release یک تصمیم چندمنبعی است.
اگر فقط یک تغییر انجام میدهید، Baseline و Status contract را اجباری کنید. همین دو مورد بخش بزرگی از «سبز جعلی»، Rerun مبهم، گزارش متناقض و اختلاف میان QA، توسعه و محصول را قابل مشاهده میکند.
سؤالات متداول
چرخه اجرای تست چیست؟
یک Timebox مدیریتی برای برنامهریزی، اجرای یک یا چند Test Run، Triage نتایج، کنترل انحراف و Closure است. Cycle باید Decision، Baseline، Scope، Risk، owner و تاریخچهٔ تغییر داشته باشد؛ صرفاً فهرستی از Caseها نیست.
تفاوت Test Run و Test Cycle چیست؟
Test Run معمولاً نمونههای Test را برای یک Build و Configuration مشخص نگه میدارد؛ Test Cycle میتواند چند Run، مثلاً برای Browserها یا PSPهای مختلف، بهاضافهٔ Triage و تصمیم مدیریتی را در یک بازه جمع کند. ابزارها ممکن است نام متفاوتی استفاده کنند، پس قرارداد تیم را مستند کنید.
آیا هر Failed test یک Bug است؟
خیر. Failed یعنی Actual با Expected/Oracle اختلاف دارد. پس از Triage ممکن است علت Product defect، Test defect، داده، محیط، Dependency یا حتی Oracle نامعتبر باشد. Bug فقط زمانی ثبت میشود که نوع Issue و Evidence آن تأیید شده باشد.
آیا میتوان تست Failed را دوباره اجرا کرد؟
بله، اگر علت و Baseline ثبت شود؛ اما Attempt اول باید بماند. Pass روی همان commit میتواند نشانهٔ Flaky behavior باشد و Pass روی Build اصلاحشده Evidence نسخهٔ جدید است، نه پاککنندهٔ Failure قبلی.
چه زمانی Test Run را ببندیم؟
وقتی فعالیت تعریفشده خاتمه یافته، همهٔ Untested/Blocked/Inconclusive و Risk gapها تعیین تکلیف شده، Evidence و لینکها کامل و Follow-upها جدا شدهاند. بستن Run تاریخچه را تثبیت میکند؛ بهتنهایی مجوز Release نیست.
منابع معتبر برای مطالعهٔ بیشتر
- ISTQB CTFL ۴.۰.۱ — Test execution، monitoring/control و completion
- ISTQB CTAL Test Analyst ۴.۰ — Test implementation و execution schedule
- TestRail — Submitting test results و وضعیتهای پیشفرض
- TestRail — Configurations در Test Plan
- TestRail — Closing و آرشیو Run/Plan
- GitHub Actions — Rerun با همان commit SHA و ref
- Google Testing Blog — Flaky tests با کد یکسان
- Scrum Guide ۲۰۲۰ — Increment و Definition of Done
- OWASP Logging Cheat Sheet — حفاظت از Log و دادههای حساس

