سه تست کارمزد تسویه سبز هستند. Expected هر سه نیز دقیقاً با همان تابعی ساخته شده که در Production اجرا می‌شود. تابع به‌اشتباه مبلغ را Round می‌کند، اما چون «پاسخ درست» و «پاسخ واقعی» از یک خطا آمده‌اند، Suite با اطمینان کامل دروغ می‌گوید.

این همان جایی است که اوراکل تست یا Test Oracle اهمیت پیدا می‌کند. Oracle فقط یک عدد Expected در Test case نیست؛ منبع و روشی است که از آن برای تعیین انتظار، مشاهده رفتار، مقایسه Actual با Expected و ساخت Verdict استفاده می‌کنیم. اگر منبع مبهم، قدیمی، وابسته به پیاده‌سازی یا ناقص باشد، تست می‌تواند هم False pass بسازد و هم False fail.

در این راهنما Oracle را از Test Basis، Assertion، Comparator و تصمیم Release جدا می‌کنیم؛ انواع Specification، Reference، Differential، Model، Invariant، Property، Metamorphic، Statistical و Human oracle را می‌سنجیم؛ مشکل Oracle را در سیستم‌های توزیع‌شده و احتمالاتی بررسی می‌کنیم؛ و با یک اجرای واقعی Node.js نشان می‌دهیم چرا Line coverage و Pass rate نمی‌توانند قدرت قضاوت تست را ثابت کنند.

اوراکل تست چیست؟

Test Oracle یک منبع برای تعیین نتیجه مورد انتظار است. این منبع می‌تواند Requirement تأییدشده، استاندارد، مثال کسب‌وکار، مدل مستقل، پیاده‌سازی مرجع، رابطه متامورفیک، Invariant، Benchmark، داده برچسب‌خورده یا قضاوت متخصص دامنه باشد.

صفحه رسمی ISTQB Certified Tester Foundation Level به Syllabus و Glossary رسمی اصطلاحات تست متصل است. تعریف کوتاه Test Oracle مفید است، اما در عمل باید علاوه بر «منبع Expected»، روش مشاهده، Comparator، Tolerance و قواعد Verdict را هم نسخه‌دار کنیم.

پاسخ کوتاه

Oracle نمی‌گوید محصول در همه حالت‌ها درست است؛ برای یک Test condition و Scope مشخص، شواهد لازم جهت قضاوت را فراهم می‌کند. Pass یعنی Observation در محدوده تعریف‌شده با Expectation سازگار بود، نه اینکه نرم‌افزار بی‌نقص یا Requirement حتماً صحیح است.

Test Basis، Oracle، Assertion و Verdict را جدا کنید

جزء نقش مثال پرداخت
Test Basis اطلاعاتی که Test از آن تحلیل می‌شود Rule کارمزد، قرارداد PSP، Risk
Oracle source منبع تعیین Expected FEE-RULE-۷ + مثال تأییدشده
Observation رفتار/State واقعاً دیده‌شده Response، Ledger، Audit و DB
Comparator روش سنجش Expected و Actual Exact integer equality
Assertion بیان اجرایی یک انتظار actualFee === 49999
Verdict Pass/Fail/Inconclusive برای Test Fail به‌علت اختلاف ۱ ریال
Decision اقدام محصول/Release Block release، Fix یا Risk acceptance

یک Oracle ممکن است چند Assertion بسازد و یک Test case ممکن است چند Oracle مستقل داشته باشد. همچنین یک Assertion فنی می‌تواند درست اجرا شود اما منبع Expected آن غلط باشد.

Oracle «منبع حقیقت مطلق» نیست

Requirement ممکن است با قانون کسب‌وکار تعارض داشته باشد؛ مستندات ممکن است قدیمی باشند؛ نسخه قبلی ممکن است همان Defect را داشته باشد؛ متخصص انسانی ممکن است اشتباه کند؛ داده برچسب‌خورده ممکن است Bias داشته باشد. بنابراین از عبارت «Source of Truth» با احتیاط استفاده کنید.

چه چیزی باید درباره Oracle بدانیم؟

  • Authority: چه کسی اجازه تعریف یا تغییر انتظار را دارد؟
  • Provenance: انتظار از کدام Requirement/Standard/Example آمده است؟
  • Version: برای کدام نسخه محصول و تاریخ معتبر است؟
  • Scope: روی چه Input/State/Environment قابل‌اعمال است؟
  • Independence: با SUT چه Failure مشترکی دارد؟
  • Uncertainty: Exact است یا Tolerance/Distribution/Human judgment دارد؟
  • Dispute path: اگر دو Oracle اختلاف داشتند چه می‌کنیم؟

مسئله Oracle چیست؟

گاهی اجرای SUT آسان است اما تشخیص نتیجه درست دشوار، گران یا ناممکن است. پژوهش مروری The Oracle Problem in Software Testing این چالش را تمایز رفتار صحیحِ مطلوب از رفتار نادرست توصیف و خانواده‌هایی مانند Specification، Model، Contract و Metamorphic testing را بررسی می‌کند.

مسئله فقط «Expected نداریم» نیست. شکل‌های رایج:

  • پاسخ Exact محاسبه‌پذیر است، اما هزینه محاسبه مرجع بسیار بالاست؛
  • چند خروجی درست وجود دارد؛
  • سیستم احتمالاتی است و هر Run خروجی متفاوت دارد؛
  • نتیجه پس از Eventual consistency و در Window زمانی معلوم می‌شود؛
  • رفتار مطلوب کیفی یا وابسته به Context انسانی است؛
  • فقط بخشی از State قابل مشاهده است؛
  • Specification ناقص، متناقض یا متحرک است؛
  • Reference implementation مستقل در دسترس نیست.

Expected Result فقط مقدار خروجی نیست

برای یک API پرداخت، status=success کافی نیست. Expected می‌تواند این ابعاد را داشته باشد:

  • Response code، Schema و Field semantics؛
  • State transition و Version؛
  • Side effect در Ledger، Queue، Email یا Audit؛
  • عدم وقوع یک اثر ناخواسته، مانند Duplicate charge؛
  • Timing/Deadline و ترتیب Event؛
  • Authorization و Data visibility؛
  • UI/Accessibility outcome برای کاربر؛
  • Recovery و Consistency window؛
  • Telemetry لازم برای اثبات نتیجه؛
  • رفتار Error و Retryability.

قالب کامل Expected و Traceability در راهنمای نوشتن تست‌کیس حرفه‌ای آمده است. در این مقاله روی کیفیت منبع و قضاوت تمرکز می‌کنیم.

قرارداد Oracle را نسخه‌دار کنید

  1. Oracle ID/Name: شناسه پایدار؛
  2. Question/Risk: قرار است درباره چه چیزی قضاوت کند؟
  3. Source + version: Requirement، استاندارد، مدل یا داده؛
  4. Authority/owner: مالک معنا و Reviewer؛
  5. Applicability: Input، State، Role، Locale و Environment؛
  6. Expected dimensions: Value، State، side effect، timing، absence؛
  7. Observation point: کجا و چگونه Actual جمع می‌شود؟
  8. Comparator: Exact، set، order، tolerance، relation، distribution؛
  9. Uncertainty: Confidence interval، label disagreement یا Unknown؛
  10. Independence/common mode: منابع خطای مشترک؛
  11. Verdict policy: Pass/Fail/Inconclusive و Severity؛
  12. Evidence/retention: چه Artifactی و تا چه زمان؛
  13. Change/expiry: Trigger بازبینی و تاریخ انقضا.

Oracle مبتنی بر Specification

Requirement، Acceptance criteria، Policy و استاندارد می‌توانند انتظار را تعیین کنند. مزیت آن‌ها Traceability و Authority است؛ ضعف‌شان ابهام، تناقض و فاصله با رفتار واقعی است.

Specification را قابل‌آزمون کنید

عبارت «کارمزد مناسب محاسبه شود» Oracle نیست. نسخه بهتر:

برای مبلغ مثبت به ریال، کارمزد برابر Floor از ۰٫۵٪ مبلغ است؛ حداقل ۵٬۰۰۰ و حداکثر ۵۰٬۰۰۰ ریال. محاسبه با Integer انجام می‌شود و خروجی تومان فقط Presentation است.

به این Rule، مثال‌های مرزی، رفتار صفر/منفی/Overflow، واحد Canonical، Version و Owner اضافه کنید. Example جای Rule را نمی‌گیرد؛ Rule بدون Example نیز مستعد تفسیر متفاوت است.

Oracle قرارداد API؛ Schema با Semantics فرق دارد

OpenAPI Specification ساختار Operation، Parameter، Request، Response و Schema را استاندارد می‌کند. از آن می‌توان برای Oracle قرارداد استفاده کرد، اما Schema فقط شکل داده را می‌سنجد. مقدار amount: 1000 ممکن است از نظر Schema عدد صحیح و از نظر واحد پول ده برابر غلط باشد.

  • Schema: Field وجود دارد و Type درست است؛
  • Semantic: Amount ریال است یا تومان؟
  • State: آیا Success با Ledger سازگار است؟
  • Security: آیا این Actor مجاز به مشاهده Order است؟
  • Temporal: آیا State نهایی در Window مقرر رسیده است؟

استاندارد و پروتکل به‌عنوان Oracle

وقتی محصول ادعای Conformance دارد، متن Normative استاندارد می‌تواند Oracle باشد. RFC ۹۱۱۰ برای HTTP Semantics میان MUST، SHOULD و MAY و نقش Client/Server/Intermediary تمایز می‌گذارد. تست نباید Recommendation را بی‌دلیل Requirement اجباری یا رفتار اختیاری را Defect اعلام کند.

Checklist استاندارد

  • نسخه و Errata درست را Pin کنید؛
  • نقش و شرط Applicability را ثبت کنید؛
  • Normative wording را از مثال Informative جدا کنید؛
  • استثناء و Extension محصول را با Authority روشن کنید؛
  • Anchor دقیق Section را در Finding نگه دارید.

Golden Example و Approval Table

برای Ruleهای مالی، جدول مثال تأییدشده می‌تواند Oracle کم‌هزینه و خوانا باشد. هر ردیف باید Source ID، Input canonical، Expected، دلیل مرزی و Approver داشته باشد.

Source Amount (IRR) Expected fee دلیل
FEE-RULE-7/EX-1 ۱٬۰۰۰٬۰۰۰ ۵٬۰۰۰ Minimum فعال
FEE-RULE-7/EX-2 ۱٬۰۰۰٬۱۹۹ ۵٬۰۰۰ Floor، نه Round
FEE-RULE-7/EX-3 ۹٬۹۹۹٬۹۹۹ ۴۹٬۹۹۹ یک گام پیش از Cap
FEE-RULE-7/EX-4 ۱۰٬۰۰۰٬۰۰۰ ۵۰٬۰۰۰ Cap دقیق

Golden data را در فایل نسخه‌دار نگه دارید؛ Snapshot بدون Provenance به‌تدریج به آخرین خروجی SUT تبدیل می‌شود.

Reference Implementation؛ استقلال مهم‌تر از شباهت است

پیاده‌سازی مرجع معمولاً ساده‌تر، کندتر و مستقل نوشته می‌شود. اگر Production و Reference یک Helper، Library، Query یا Specification اشتباه را Copy کنند، Common-mode failure می‌سازند.

  • الگوریتم/زبان/Library متفاوت در صورت امکان؛
  • سادگی و خوانایی بالاتر از Performance؛
  • Source و Version ثابت؛
  • Test مستقل برای Reference؛
  • عدم استفاده از Output خود SUT به‌عنوان Fixture؛
  • Scope محدود و اعلام مواردی که Reference نمی‌داند.

Differential Oracle؛ اختلاف شاهد است، نه حکم

در Differential Testing یک Input به دو یا چند پیاده‌سازی/نسخه داده و خروجی‌ها مقایسه می‌شوند. اختلاف یک Signal قدرتمند است، اما مشخص نمی‌کند کدام طرف درست است. حتی توافق همه نسخه‌ها ممکن است ناشی از Library یا Specification مشترک معیوب باشد.

مستند «How SQLite Is Tested» نمونه‌ای از تنوع Harness، Test suite، Mutation/fault و مقایسه‌های گسترده در یک پروژه واقعی است. از چنین تجربه‌ای باید اصل Portfolio of evidence را گرفت، نه اینکه ابزار یک پروژه را نسخه آماده هر محصول بدانیم.

موارد استفاده Differential

  • نسخه قبلی و جدید برای Backward compatibility؛
  • دو Parser/Compiler مستقل؛
  • Query engineها روی زیرمجموعه مشترک استاندارد؛
  • Backend جدید در Shadow mode در برابر Legacy؛
  • Implementation سریع در برابر Reference کند؛
  • Providerهای مختلف با Contract یکسان.

Model-Based Oracle

State machine، Decision table، Mathematical model یا Domain model می‌تواند State/Transition مجاز را پیش‌بینی کند. مدل باید از SUT جدا، کوچک و قابل‌بازبینی باشد؛ مدل کاملِ هم‌اندازه محصول فقط Defect را جابه‌جا می‌کند.

برای تولید Sequence و Expected state از مدل و ثبت پوشش Transition، راهنمای تست مبتنی بر مدل را ببینید. در این‌جا نکته Oracle این است: Version مدل، Mapping میان Model/SUT و رفتار خارج از Abstraction باید صریح باشد.

Invariant و Property Oracle

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

  • مجموع تخصیص‌ها برابر مبلغ کل است؛
  • Balance هرگز منفی نمی‌شود مگر Contract اجازه دهد؛
  • Serialize→Deserialize ساختار معادل را برمی‌گرداند؛
  • عملیات Idempotent پس از تکرار State تازه نمی‌سازد؛
  • مرتب‌سازی خروجی Ordered و Permutation ورودی است؛
  • Fee در Bounds است و با Amount کاهش نمی‌یابد.

Property می‌تواند ضعیف یا Vacuous باشد. در آزمایش این مقاله، Bounds و Monotonic بودن کارمزد معیوب هر دو Pass شدند، اما خطای Round را نگرفتند. طراحی Generator، Property، Shrink و Replay در راهنمای Property-Based Testing آمده است.

Metamorphic Oracle؛ رابطه میان چند اجرا

Metamorphic Testing به‌جای Expected دقیق یک Run، رابطه مورد انتظار میان Source input/output و Follow-up input/output را می‌سنجد. مقاله Metamorphic Testing: A New Approach for Generating Next Test Cases این رویکرد را برای تولید Testهای بعدی توضیح می‌دهد.

نمونه رابطه‌های متامورفیک

  • تغییر ترتیب آیتم‌ها نباید Total سبد را عوض کند؛
  • افزودن فاصله مجاز/Normalization متن نباید Identity کاربر را عوض کند؛
  • تقسیم Batch به دو بخش و جمع نتایج باید با اجرای یکجا سازگار باشد؛
  • تبدیل Coordinate و معکوس آن باید نتیجه را برگرداند؛
  • افزودن رکورد نامرتبط نباید رتبه/نتیجه هدف را تغییر دهد—اگر Contract چنین می‌گوید.

Relation باید از Domain بیاید. «خروجی با تغییر X نباید عوض شود» اگر X واقعاً معنی را تغییر دهد، Oracle غلط می‌سازد.

Implicit Oracle؛ Crash-free کافی نیست

Crash، uncaught exception، memory error، data corruption آشکار یا نقض Assertion داخلی می‌تواند بدون Expected دقیق Failure را نشان دهد. این Oracleها ارزشمندند، به‌خصوص در Fuzzing؛ اما نبود Crash یعنی Correctness نیست.

  • Parser ممکن است Payload را بی‌صدا اشتباه تفسیر کند؛
  • API ممکن است ۲۰۰ با مبلغ غلط بدهد؛
  • مدل AI ممکن است پاسخ روان اما نادرست بسازد؛
  • پرداخت ممکن است Duplicate شود بدون Exception.

Human و Heuristic Oracle

در UX، زبان، Safety، اخلاق، تناسب محتوا یا سناریوی جدید، انسان ممکن است بهترین منبع قضاوت باشد. «انسان» نباید به معنی نظر بی‌ثبت باشد. Rubric، مثال مرزی، Training، Blind review، چند Reviewer و مسیر اختلاف، تکرارپذیری را بهتر می‌کنند.

برای تبدیل مشاهده و شهود به Hypothesis/Evidence در Session، راهنمای تست اکتشافی ساختاریافته را ببینید.

Human Oracle قابل‌ممیزی

  • سؤال و معیار قضاوت روشن؛
  • نمونه Pass/Fail/Borderline؛
  • Reviewer با دانش Domain و Conflict declaration؛
  • نتیجه Pass/Fail/Unsure همراه دلیل؛
  • Inter-rater agreement برای کار مقیاس‌پذیر؛
  • Escalation برای اختلاف؛
  • بازکالیبراسیون با تغییر محصول/جامعه/قانون.

Accessibility Oracle چندلایه است

WCAG 2.2 Success criterionهای Normative را ارائه می‌کند، اما هر Criterion روش ارزیابی خودش را دارد. ابزار خودکار فقط بخشی از خطاها را می‌بیند؛ Keyboard، Screen reader، Zoom/Reflow و قضاوت Contextual ممکن است انسان یا Technique دیگر بخواهند.

راهنمای تست دسترس‌پذیری Portfolio اسکن خودکار، Keyboard و Screen reader را عملی می‌کند. Pass یک Scanner، Oracle کامل WCAG نیست.

Oracle برای متن فارسی و Unicode

Binary equality برای متن فارسی همیشه Semantic equality نیست؛ از طرف دیگر Normalization کور نیز می‌تواند تمایز مهم را پاک کند. Unicode Standard Annex #15 NFC/NFD/NFKC/NFKD و Canonical/Compatibility equivalence را تعریف و درباره کاربرد کور NFKC/NFKD هشدار می‌دهد.

تصمیم‌های Oracle فارسی

  • آیا ی و ي در Identity معادل‌اند یا Data quality issue؟
  • آیا ک و ك Normalize می‌شوند؟ در کدام Boundary؟
  • ZWNJ در Search نادیده و در Display حفظ می‌شود؟
  • ارقام فارسی/عربی/لاتین برای Parse معادل‌اند؟
  • NFC برای Storage اجباری است یا Comparison-time؟
  • Bidi controlهای ناخواسته Reject، Escape یا حفظ می‌شوند؟
  • Collation و Sort با انتظار زبان فارسی کجا تعریف شده است؟

Expected باید Representation و Semantics را جدا کند. نام نمایش‌داده‌شده شاید ZWNJ را حفظ کند، درحالی‌که Search key Canonical دیگری دارد.

Oracle زمان، تاریخ و منطقه زمانی

مقایسه String تاریخ شکننده است. Oracle باید Instant، Zone، Calendar و Formatting را تفکیک کند:

  • Event و Expiry با UTC Instant مقایسه شوند؛
  • Asia/Tehran برای Presentation نسخه‌دار باشد؛
  • تقویم جلالی Oracle تبدیل مستقل و مثال مرزی داشته باشد؛
  • Clock در Test ثابت و قابل‌کنترل باشد؛
  • DST/قانون منطقه زمانی از Runtime version ناشناخته نیاید؛
  • Tolerance زمان Network/async صریح باشد، نه Sleep تصادفی.

Oracle سیستم توزیع‌شده و Eventual Consistency

Expected در سیستم توزیع‌شده اغلب «فوراً این مقدار» نیست؛ ممکن است «در Window معین به State نهایی همگرا شود و هیچ Invariantی در مسیر نشکند» باشد.

چه چیزهایی را مشاهده کنیم؟

  • API response و Correlation ID؛
  • Outbox/Inbox و Offset پیام؛
  • Write model، Read model و Replica؛
  • Ledger/Audit مستقل؛
  • Duplicate، Reorder و Late event؛
  • State transitionهای مجاز؛
  • Deadline و Convergence window؛
  • Side effect خارجی مانند PSP/Notification.

Polling باید Condition و Deadline داشته باشد و آخرین Evidence را حفظ کند. یک Sleep ثابت ممکن است هم False fail و هم Test کند بسازد.

Oracle آماری و سیستم‌های احتمالاتی

برای Ranking، Recommendation، Fraud model و LLM، یک Output Exact معمولاً Oracle مناسبی نیست. باید Population، Dataset، Label policy، Metric، Threshold، Confidence/uncertainty، Slice و Cost خطا تعریف شود.

برنامه NIST برای AI TEVV بر Measurement و Evaluation قابل‌اعتماد برای Accuracy، Reliability، Robustness، Safety و ویژگی‌های دیگر تأکید می‌کند. Metric بدون Context استفاده و نمونه نماینده، Oracle معتبر نمی‌سازد.

قرارداد Statistical Oracle

  • Target population و Sampling method؛
  • Label source، Guideline و disagreement؛
  • Metric و جهت بهتر/بدتر؛
  • Minimum effect و Confidence interval؛
  • Sliceهای فارسی، Dialect، Device، Merchant و Risk؛
  • Baseline/Champion و Leakage check؛
  • False positive/negative cost؛
  • Repeat، Seed، Model/Data/Prompt version؛
  • Human appeal برای تصمیم پراثر.

طراحی Evaluation داده/مدل/Production در راهنمای تست سیستم‌های AI/ML با جزئیات آمده است.

Tolerance؛ Exact را بی‌دلیل کنار نگذارید

Tolerance باید از Error budget دامنه بیاید. abs(actual-expected)<0.01 شاید برای نمایش نمودار مناسب و برای Ledger مالی فاجعه‌بار باشد.

نوع Comparator ریسک
Integer money Exact canonical unit تبدیل ریال/تومان و Overflow
Floating point science Absolute + relative + domain bounds NaN/Infinity و scale
Set Membership، subset/superset نادیده‌گرفتن Duplicate/Order
Time Window/Deadline Clock/Timezone و flaky wait
Image Pixel/perceptual/region معنای UI در امتیاز کل گم می‌شود
Distribution Metric + uncertainty Sample/leakage/Multiple testing

آزمایش واقعی: Oracle Laundering در کارمزد

Rule تأییدشده کارمزد چنین بود: floor(amount × 0.005) با حداقل ۵٬۰۰۰ و حداکثر ۵۰٬۰۰۰ ریال. نسخه معیوب از round استفاده می‌کرد. شبیه‌ساز با Node.js ۲۴.۱۸.۰ اجرا شد.

function approvedFee(amountRial) {
  return Math.min(50_000, Math.max(5_000,
    Math.floor(amountRial * 0.005)));
}

function buggyFee(amountRial) {
  return Math.min(50_000, Math.max(5_000,
    Math.round(amountRial * 0.005)));
}

Oracle معیوب: Expected از همان کد

same_code_expected:
  passed: 3 / 3
  amount 1,000,199: expected 5,001 / actual 5,001
  amount 9,999,999: expected 50,000 / actual 50,000

weak_invariants_on_bug:
  bounded: true
  monotonic: true

سه Test سبز شدند چون Expected همان خطا را تکرار کرد. دو Property «در Bounds بودن» و «Monotonic بودن» نیز صحیح اما ناکافی بودند؛ Round همچنان هر دو را حفظ می‌کرد.

Oracle مستقل: مثال‌های تأییدشده کسب‌وکار

approved_examples_against_bug:
  passed: 0 / 2
  1,000,199 IRR: expected 5,000 / actual 5,001
  9,999,999 IRR: expected 49,999 / actual 50,000

approved_examples_after_fix:
  passed: 2 / 2

seeded_rounding_mutant_killed: true

مثال‌ها به FEE-RULE-7/EX-2 و EX-3 Trace داشتند و خطا را گرفتند. این آزمایش کوچک اثبات کامل Oracle نیست؛ Overflow، مقدار منفی، Decimal input و واحد تومان را پوشش نمی‌دهد. مزیت آن جداسازی روشن Common-mode failure است.

Mutation Testing قدرت Oracle را می‌سنجد

Coverage می‌گوید کد اجرا شد؛ نمی‌گوید Assertion تغییر معنایی را حس کرد. Mutation Testing تغییرهای کوچک مانند < به <=، حذف Call یا تغییر Return را Seed می‌کند و می‌سنجد Suite آن‌ها را می‌کشد.

مستندات Mutatorهای PIT نمونه‌هایی مانند Boundary، Negate conditional، Math و Return-value mutations را فهرست می‌کند. Equivalent mutant و Invalid mutant باید جدا شوند؛ Mutation score خام حقیقت نیست.

برای طراحی Campaign، Triage و جلوگیری از بازی‌کردن Metric، راهنمای تست جهش را ببینید.

False Pass و False Fail را مدل کنید

Oracle verdict محصول واقعاً درست محصول واقعاً غلط
Pass True pass False pass؛ خطر فرار Defect
Fail False fail؛ نویز و اتلاف True fail

تیم‌ها معمولاً Flaky/False fail را سریع می‌بینند چون Pipeline قرمز می‌شود، اما False pass پنهان است. Seeded defects، Mutation، escaped-defect analysis و Independent review برای دیدن آن ضروری‌اند.

Oracle Conflict و ترتیب مرجع‌ها

اگر Requirement می‌گوید Round و مثال مالی می‌گوید Floor، نباید یکی را تصادفی انتخاب کنید. Test باید Blocked/Inconclusive شود و تعارض به Authority مربوط برسد.

قالب Resolution

  1. هر دو Source، Version و Scope ثبت شوند؛
  2. Observation از Interpretation جدا شود؛
  3. قانون/استاندارد اجباری و Contract مشتری بررسی شود؛
  4. Product/Domain/Security owner تصمیم بگیرد؛
  5. Decision record، مثال و Requirement با هم Update شوند؛
  6. Regression برای تعارض ساخته شود؛
  7. Baseline قدیمی Deprecate شود.

«SUT فعلی همین کار را می‌کند» دلیل Authority نیست. رفتار Legacy ممکن است Constraint سازگاری باشد، اما باید آگاهانه مستند شود.

Oracle Laundering با AI

اگر LLM از Production code Expected بسازد، خروجی را با توضیح روان تکرار کند و تیم آن را «مستقل» بنامد، Common-mode failure شسته شده است. AI می‌تواند Candidate relation، Example یا Gap پیشنهاد دهد؛ منبع و Oracle نهایی نیست مگر Grounding، Validation و Approval مشخص داشته باشد.

  • Prompt باید Test basis و Source ID داشته باشد؛
  • Expected و دلیل آن جدا از Procedure تولید شوند؛
  • کد SUT تنها Source نباشد؛
  • Output با Rule/Domain owner و اجرای مستقل بررسی شود؛
  • Model/Prompt/Context/Date ثبت شود؛
  • Hallucination و Prompt injection در نظر گرفته شود؛
  • تست تولیدشده Mutation/Execution gate بگیرد.

Workflow کامل Candidate→Traceability→Oracle→Quality Gate در راهنمای تولید تست کیس با هوش مصنوعی آمده است.

Oracle Review؛ چه پرسش‌هایی بپرسیم؟

  • این Expected از کجا آمده و چه کسی آن را تأیید کرده؟
  • آیا Source و SUT یک منطق/Library/داده مشترک دارند؟
  • فقط Response را می‌بینیم یا Side effect هم Oracle دارد؟
  • عدم وقوع اثر ناخواسته بررسی می‌شود؟
  • Tolerance و Window از Domain آمده‌اند یا برای سبزشدن؟
  • چند خروجی درست ممکن است؟ Comparator آن را می‌داند؟
  • اگر Oracle نداند، Inconclusive ممکن است؟
  • Failure عمدی کوچک این Assertion را می‌شکند؟
  • Locale/Timezone/Unicode/Unit در Scope هستند؟
  • پس از تغییر Rule چه چیزهایی با هم Update می‌شوند؟

Oracle Portfolio بسازید

برای جریان پرریسک، یک Oracle واحد شکننده است. Portfolio نمونه پرداخت:

  • Specification rule برای Formula؛
  • Golden examples برای Boundary؛
  • Independent reference برای دامنه وسیع؛
  • Invariant برای Ledger و Bounds؛
  • Metamorphic relation برای تغییر ترتیب آیتم‌ها؛
  • Differential با نسخه Legacy در محدوده سازگاری؛
  • Mutation برای قدرت Assertion؛
  • Human review برای متن/UX خطای مالی؛
  • Production reconciliation برای Unknown outcome.

تنوع فقط وقتی مفید است که Failureها مستقل باشند. پنج Assertion که همه از یک Helper Expected استفاده می‌کنند، پنج Oracle نیستند.

Oracle در CI/CD

Lane Oracle Gate
PR Specification example، Property، Model، Mutation sample Fast deterministic
Integration Contract + DB/Queue/Ledger side effect State/Evidence
Nightly Differential، Metamorphic، Statistical sample Trend/triage
Release Critical Golden set + Human/Domain approval Risk-based
Production Reconciliation، SLO، anomaly + appeal Monitor/rollback، نه جای pre-release

Oracle change باید همانند Product code Review شود. تغییر Snapshot، Threshold، Label set یا Golden expected ممکن است معنای Pass را عوض کند و باید Diff/Reason/Approver داشته باشد.

Evidence یک Verdict قابل‌دفاع

  1. Test/Run ID و Build؛
  2. Input/State/Environment؛
  3. Oracle ID، Source و Version؛
  4. Expected dimensions؛
  5. Raw observation بدون تفسیر اضافی؛
  6. Comparator/Tolerance/Window؛
  7. Verdict و Confidence/Uncertainty؛
  8. Side-effect and absence checks؛
  9. Reviewer/Automation version؛
  10. Decision و Residual risk.

Artifact باید حداقل داده لازم را داشته باشد؛ Log و Screenshot واقعی کاربر برای اثبات Oracle مجوز نشت PII نیست.

متریک‌های سلامت Oracle

  • Source-traceable expectations / کل Expectations؛
  • Oracle mutation kill rate با Triage Equivalent؛
  • Seeded-defect detection بر اساس Risk؛
  • False fail و Inconclusive rate به تفکیک علت؛
  • Escaped defect ناشی از Missing/weak/wrong oracle؛
  • Common-mode dependency count؛
  • Stale/expired Oracle و زمان Update؛
  • Oracle conflict resolution time؛
  • Human reviewer agreement و Unsure rate؛
  • Statistical uncertainty و Slice coverage؛
  • Side-effect/absence observation coverage؛
  • Cost per useful verdict.

Pass rate معیار Oracle نیست؛ Oracle ضعیف دقیقاً Pass rate را بالا می‌برد.

ضدالگوهای اوراکل تست

  1. Expected از همان Function: Common-mode bug.
  2. Snapshot update روی هر Fail: Actual به Expected تبدیل می‌شود.
  3. فقط Status code: State و Side effect گم می‌شوند.
  4. عدم Exception برابر Pass: Silent corruption دیده نمی‌شود.
  5. نسخه قبلی برابر حقیقت: Legacy defect تکثیر می‌شود.
  6. اکثریت Differential برابر درست: همه می‌توانند مشترکاً غلط باشند.
  7. Property بسیار ضعیف: Bug مهم هنوز Relation را حفظ می‌کند.
  8. Tolerance برای خاموش‌کردن Flake: False pass افزایش می‌یابد.
  9. Sleep به‌جای Temporal oracle: Window مبهم.
  10. Human says OK: بدون Rubric، Evidence و Owner.
  11. AI says expected: Provenance و Independence حذف می‌شود.
  12. Schema برابر Semantics: Amount صحیح‌نوع اما غلط‌واحد است.
  13. Coverage برابر قدرت: Assertion حساس نیست.
  14. Pass/Fail اجباری: Unknown را به Verdict کاذب تبدیل می‌کند.

برنامه ۳۰روزه بهبود Oracleها

هفته اول: Inventory و Risk

  • سه Critical Flow و Assertionهای آن را فهرست کنید؛
  • Source/Version/Owner هر Expected را ثبت کنید؛
  • Same-code، Snapshot کور و Status-only را علامت بزنید؛
  • Escaped defectهای Oracle-related را مرور کنید.

هفته دوم: استقلال و Portfolio

  • Golden boundary examples را با Domain owner بسازید؛
  • Invariant و Absence oracle اضافه کنید؛
  • Reference/Differential/Metamorphic PoC انتخاب کنید؛
  • Oracle Contract و Conflict path را تعریف کنید.

هفته سوم: قدرت و Automation

  • Mutantهای Risk-relevant Seed کنید؛
  • False fail/false pass و Inconclusive را طبقه‌بندی کنید؛
  • Side-effect observation و Correlation را کامل کنید؛
  • Oracle change review را وارد CI کنید.

هفته چهارم: Governance و Metric

  • Expiry/Review cadence برای Rule/Standard/Label set تعیین کنید؛
  • Human rubric و agreement sample اجرا کنید؛
  • متریک‌های Seed detection و escaped weakness را Baseline کنید؛
  • Remediation backlog و Owner ۶۰روزه بسازید.

چک‌لیست طراحی Test Oracle

  • □ سؤال و Risk قضاوت روشن است.
  • □ Oracle source، Version و Owner ثبت شده‌اند.
  • □ Scope و Applicability مشخص‌اند.
  • □ Expected شامل Value/State/Side effect/Absence/Time لازم است.
  • □ Observation point مستقل و قابل‌اعتماد است.
  • □ Comparator و Tolerance از Domain آمده‌اند.
  • □ Uncertainty و Inconclusive مجاز تعریف شده‌اند.
  • □ Common-mode failure با SUT بررسی شده است.
  • □ Rule و Golden examples Traceable و هم‌نسخه‌اند.
  • □ Schema از Semantics جدا سنجیده می‌شود.
  • □ Property/Metamorphic relation برای Domain معتبر است.
  • □ Differential disagreement به بررسی می‌رود، نه رأی اکثریت کور.
  • □ Statistical sample/metric/uncertainty/سهم‌ها ثبت شده‌اند.
  • □ Human review Rubric، مثال و Escalation دارد.
  • □ Mutation/Seeded defect حساسیت Oracle را می‌سنجد.
  • □ Oracle change Diff، Reason و Approver دارد.
  • □ Evidence حداقلی و بدون داده حساس است.
  • □ Conflict، Expiry و Review cadence تعریف شده‌اند.

سؤالات متداول اوراکل تست

اوراکل تست چیست؟

منبعی برای تعیین Expected result است؛ مانند Specification، استاندارد، مثال تأییدشده، مدل، پیاده‌سازی مرجع، Property، Metamorphic relation، داده برچسب‌خورده یا متخصص. در عمل Observation، Comparator، Tolerance و Verdict policy نیز باید کنار آن تعریف شوند.

آیا Expected Result همان Test Oracle است؟

خیر. Expected نتیجه مشتق‌شده برای یک Test condition است؛ Oracle منبع و روش تعیین آن است. Assertion نیز بیان اجرایی مقایسه است و Verdict نتیجه همان اجرا.

اگر پاسخ درست را ندانیم چگونه تست کنیم؟

بسته به Domain از Invariant، Property، Metamorphic relation، Differential/reference، Model، Statistical evaluation یا Human rubric استفاده کنید. هر روش محدودیت دارد و بهتر است Portfolio مستقل بسازید.

چرا استفاده از کد Production برای ساخت Expected خطرناک است؟

چون SUT و Oracle یک Failure مشترک پیدا می‌کنند. همان Bug در Actual و Expected تکرار و Test سبز می‌شود. Reference باید تا حد لازم مستقل، ساده و Traceable به Source بیرونی باشد.

چگونه قدرت Oracle را اندازه بگیریم؟

Coverage کافی نیست. Mutant و Defectهای Seed‌شده مرتبط با Risk را اجرا کنید، False pass/false fail و escaped defects را تحلیل کنید، Common-mode dependency و Staleness را بسنجید و برای Human/Statistical oracle توافق و عدم‌قطعیت را ثبت کنید.

جمع‌بندی

تست زمانی معنی دارد که بتواند میان رفتار قابل‌قبول، غیرقابل‌قبول و نامعلوم تمایز بگذارد. این تمایز از یک Expected تصادفی یا Snapshot تازه نمی‌آید؛ از Oracle دارای Provenance، Scope، Independence، Comparator، Uncertainty و Governance می‌آید.

آزمایش کارمزد نشان داد همان پیاده‌سازی معیوب اگر Expected را بسازد، ۳/۳ Pass می‌دهد و حتی Bounds و Monotonic بودن نیز Bug را نمی‌گیرند. دو مثال مستقل و Traceable خطا را ۰/۲ آشکار کردند؛ پس از Fix هر دو سبز و Mutant کشته شد. نتیجه عملی روشن است: هر سبزی Pipeline را باید با این سؤال بخوانید—چه چیزی می‌توانست غلط شود و آیا Oracle ما واقعاً آن را می‌دید؟

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