အခန်း ၇ :: Software Verification and Validation (V&V)

Software Development မှာ "Code ရေးလို့ ပြီးပြီ" ဆိုတာကတော့ ခရီးတစ်ဝက်ပဲ​ ရှိသေးတယ် ဆိုရမယ်။ ကျွန်တော် တို့ ရေးလိုက်သည့် Software တွေဟာ ထင်ထားသလို အလုပ်လုပ်ရဲ့လား ၊ User အတွက် တကယ် အကျိုးရှိရဲ့လား ၊ အသုံးဝင်ရဲ့လားကို စစ်ဆေးရပါမည်။ ဤလုပ်ငန်းစဉ်ကို Verification and Validation (V&V) ဟု ခေါ်ပါသည်။

"Quality is not an afterthought" လို့ ဆိုသည့် အတိုင်း Software Engineer တစ်ယောက်က quality ကောင်းသည့် software တစ်ခု ဖြစ်အောင် စ ကတည်းက ထည့်သွင်း စဥ်းစား တည်ဆောက်ရမည့် အရာ ဖြစ်ပါသည်။ Cost of Bugs သီအိုရီ အရ Bug တစ်ခု ကို Requirement အဆင့်မှာ တွေ့လျှင် $1 ကုန်သော်လည်း Production ရောက်မှ တွေ့လျှင် $1000 လောက် အထိ ကုန်ကျ နိုင်ပါတယ်။

Software Developer တွေမှာ အခက်အခဲ ဆုံး အလုပ်က ကိုယ်ရေးတာ မှားနေသည့် code ကို ပြန်ရှာ ရတာပဲ။ ပုံမှန် အားဖြင့် ကိုယ်တိုင် ရေး ကိုယ်တိုင် test လုပ်သည့် အခါမှာ အမှားတွေ တွေ့ရတာ နည်းပါတယ်။ ဒါကြောင့် test လုပ်သည့် အခါမှာ ဖြစ်နိုင်သည့် နည်းလမ်းတွေ ပိုစဥ်းစားဖို့ လို သလို ဖြစ်နိုင်လျှင် ကိုယ်တိုင် မစစ်ပဲ စစ်ဆေးမှု ကျွမ်းကျင်သည့် QA တွေ ကို စစ်ဆေး ခိုင်းတာက အများကြီး ပို အဆင်ပြေပါလိမ့်မယ်။

၇.၁ Verification vs Validation

Verification နှင့် Validation သည် နာမည်ဆင်တူသော်လည်း software engineering တွင် အဓိပ္ပာယ် မတူပါဘူး။ ပုံမှန် Junior developer တွေ အနေနဲ့ စတင် လေ့လာကာစ မှာ verification နှင့် validation ကို တူညီတယ် လို့ ထင်မှတ် ကြပါတယ်။ authorization နှင့် authentication နဲ့ မတူသလို Verification နှင့် Validation မတူပါဘူး။

Verification (အတည်ပြုခြင်း):
"Are we building the product right?"

ကျွန်တော်တို့ တည်ဆောက်နေသော Product သည် Engineering Spec များ၊ Design များ၊ Standard များနှင့် ကိုက်ညီမှု ရှိရဲ့လား။ Logic အမှား (Bug) ကင်းစင်ရဲ့လား။

Focus: Internal Quality (Software အတွင်းပိုင်း မှန်ကန်မှု)

Validation (မှန်ကန်ကြောင်း သက်သေပြခြင်း):
"Are we building the right product?"

ကျွန်တော်တို့ Software သည် User တကယ် လိုချင်သော အရာ ဟုတ်ရဲ့လား။ သူတို့၏ ပြဿနာကို တကယ် ဖြေရှင်းပေးနိုင်ရဲ့လား။

Focus: External Value (အသုံးပြုသူအတွက် တန်ဖိုး)

ဒန်း ဥပမာ

Verification နဲ့ Validation အကြောင်းပြောရရင် Project Management မှာ မပါမဖြစ် ဥပမာ တစ်ခု ဖြစ်သည့် ဒန်း ဥပမာ ကို ပြောပြချင်ပါတယ်။

Verification အဆင့် အရ သစ်ပင်မှာ ကြိုးနဲ့ ချီ ထားရမယ်။ သစ်သားပါ ပါရမယ်။ Secure ဖြစ်ရမယ်။ ခိုင်ခံရမယ်။ ဒီ အချက်တွေ အကုန် ကိုက်ညီပါတယ်။

Validation မှာတော့ User လိုချင်တာနဲ့ ကိုက်ညီမှု မရှိသည့် အတွက် Validation မ အောင်မြင်ပါဘူး။

နောက်ထပ် ဥပမာ တစ်ခု အနေနဲ့ ရှမ်းခေါက်ဆွဲ ဆိုင်တစ်ဆိုင် ဖွင့်တယ်လို့ သဘောထားကြည့်ရအောင်ဗျာ။

graph LR
    subgraph Verification
        direction TB
        V_Q["<b>Are we building the product RIGHT?</b><br><br>Specification နဲ့ ကိုက်ညီရဲ့လား?"]
        V_Check["Process: Reviews, Inspections, Static Analysis"]
    end
    subgraph Validation
        direction TB
        Val_Q["<b>Are we building the RIGHT product?</b><br><br>User လိုချင်တာ ဟုတ်ရဲ့လား?"]
        Val_Check["Process: UAT, User Feedback, Beta Testing"]
    end

၇.၂ Code မ run ခင် စစ်ဆေးခြင်း (Static Testing)

Testing ဆိုလျှင် Code ကို Run ပြီး စစ်တာ (Dynamic Testing) ဟုပဲ ပြေးမြင်တတ်ကြပါသည်။ သို့သော် Code မ Run ခင်မှာကတည်းက Error တွေကို ရှာဖွေနိုင်ပါသည်။ ၎င်းကို Static Testing ဟု ခေါ်ပါသည်။ Code တွေ မ Run ခင် ကြိုတင် စစ်ဆေးထားရင် အမှားအယွင်း တော်တော်များများကို ကာကွယ်နိုင်ပါတယ်။

၁။ Code Reviews (The First Line of Defense)

Code Review က developers အခြင်းခြင်း မဖြစ်မနေ ပြုလုပ်သင့်ပါတယ်။ ပုံမှန် အားဖြင့် development branch ထဲမှာ တိုက်ရိုက် မရေးပဲ pull request တစ်ခု တင်ထားပါတယ်။ code review ကို developer ၂ ယောက် က ကြည့်ပြီး approve ဖြစ်မှ development branch ကို merge လုပ်သည့် ပုံစံ မျိုးကို company တွေ မှာ အသုံးပြုကြပါတယ်။ တနည်းအားဖြင့် တခြား developer ရေးထားတာကို နားလည် စေရန်။ bugs များကို ရှာဖွေ တွေ့ရှိရန် ဖြစ်ပါသည်။ ဒီ code review လုပ်သည့် အခါမှာ junior code ကို senior က ကြည့်သလို senior code တွေလည်း junior တွေက ကြည့်ပြီး review လုပ်ခွင့် ရှိပါတယ်။ Developer တိုင်းက ကိုယ်ရေးထားသည့် code ရဲ့ bugs တွေကို ရှာ မတွေ့တတ်ကြပါဘူး။​ Pull Request တင်ပြီး အပြန်အလှန် စစ်ဆေးခြင်းဟာ code quality ကို ပိုပြီး ကောင်းမွန် စေသလို ရုံးတွင်း code guide line ကိုလည်း follow လုပ်ပြီးသား ဖြစ်စေပါတယ်။

၂။ Static Analysis Tools (Robots checking your code)

လူက စစ်တာ တစ်ခါတစ်လေ လွတ်သွားနိုင်ပါတယ်။ စက်ကို စစ်ခိုင်းတာ ပိုစိတ်ချရပါတယ်။ Developer တွေ မေ့သွားတတ်တဲ့ အချက်အလက်တွေ စည်းကမ်းတွေကို Tool တွေက ကူညီစစ်ဆေးပေးနိုင်ပါတယ်။

ဒါကြောင့် Modern IDE (VS Code) တွေမှာ အနီရောင် မျဉ်းတား လိုင်းတား ပြနေတာတွေဟာ တကယ်တော့ Static Testing လုပ်နေတာပဲ ဖြစ်ပါသည်။

၇.၃ Testing Strategies နှင့် The Testing Pyramid

Code ကို Run ပြီး စစ်ဆေးတော့မည် ဆိုလျှင် ဘယ်လို စစ်မလဲ။ Strategy ဘယ်လို ထားမလဲ။ အသုံးအများဆုံး Model ကတော့ Mike Cohn's Testing Pyramid ဖြစ်ပါသည်။

Pyramid ပုံစံ ခိုင်းနှိုင်းထားခြင်းမှာ အောက်ခြေ (Unit Test) ကို အများဆုံး တည်ဆောက်ရမည် ဖြစ်ပြီး၊ ထိပ်ဆုံး (E2E Test) ကို အနည်းဆုံး ထားရမည် ဟု ဆိုလိုခြင်း ဖြစ်သည်။

graph TD
    subgraph "The Testing Pyramid"
        direction TB
        A["<b>UI / End-to-End Tests (10%)</b><br/><i>Slow, expensive, brittle</i>"] --> B["<b>Integration Tests (20%)</b><br/><i>Test component connections</i>"]
        B --> C["<b>Unit Tests (70%)</b><br/><i>Fast, cheap, should be majority</i>"]
    end
    style A fill:#ffcccc,stroke:#333
    style B fill:#ffffcc,stroke:#333
    style C fill:#ccffcc,stroke:#333

1. Unit Testing (အောက်ခြေဖောင်ဒေးရှင်း)

Unit Test ဆိုသည်မှာ Code ၏ အသေးဆုံး အစိတ်အပိုင်း (Function တစ်ခု၊ Class တစ်ခု) ကို သီးခြားခွဲထုတ်ပြီး စစ်ဆေးခြင်း ဖြစ်သည်။

Example (TypeScript & Jest):

စျေးဝယ်လှည်း (Cart) ထဲက ပစ္စည်းတန်ဖိုး စုစုပေါင်း တွက်တဲ့ Function ကို စစ်ကြည့်ရအောင်။

// src/cart.ts
export function calculateTotal(items: { price: number; qty: number }[]): number {
  return items.reduce((total, item) => total + item.price * item.qty, 0);
}

// tests/cart.test.ts
import { calculateTotal } from '../src/cart';

describe('Cart Calculator', () => {
  it('should calculate total price correctly', () => {
    const items = [
      { price: 100, qty: 2 }, // 200
      { price: 50, qty: 1 }   // 50
    ];
    
    expect(calculateTotal(items)).toBe(250);
  });

  it('should return 0 for empty cart', () => {
    expect(calculateTotal([])).toBe(0);
  });
});

ဒီ Test က စက္ကန့်ပိုင်းအတွင်း ပြီးသွားပါမယ်။ calculateTotal function မှာ Logic မှားတာနဲ့ Test Fail ပြီး ချက်ချင်း သိရပါမယ်။

2. Integration Testing (အစိတ်အပိုင်းများ ချိတ်ဆက်ခြင်း)

Unit Test တွေ အကုန် Pass ပေမယ့်၊ ပေါင်းလိုက်ရင် Error တက်နိုင်ပါတယ်။ ဥပမာ - API က Database ထဲ Data သွားထည့်လို့ ရရဲ့လား၊ Payment Service နဲ့ ချိတ်တာ အဆင်ပြေလား။

Integration Test က အစိတ်အပိုင်း ၂ ခု (သို့) ၂ ခုထက်ပိုတဲ့ အရာတွေ တွဲလုပ်တဲ့အခါ အဆင်ပြေမပြေ စစ်ဆေးခြင်း ဖြစ်ပါတယ်။

တခါတရံ ပြင်ပ System တွေ (ဥပမာ - Bank API) ကို တကယ် မခေါ်ချင်တဲ့အခါ Running Mock သို့မဟုတ် Fake တွေကို သုံးပြီး စစ်ဆေးလေ့ ရှိပါတယ်။

3. End-to-End (E2E) Testing (သုံးစွဲသူ ဘက်မှ စမ်းသပ်ခြင်း)

ဒါကတော့ အစစ်အမှန်ဆုံးပါပဲ။ Chrome browser ထဲမှာ User တစ်ယောက် Login ဝင်တယ်၊ ပစ္စည်းရွေးတယ်၊ ဝယ်တယ်၊ ပိုက်ဆံရှင်းတယ် ဆိုတဲ့ Flow တစ်ခုလုံးကို Robot တစ်ကောင် (Automation Tool) ကို လုပ်ခိုင်းပြီး စစ်ဆေးတာပါ။

၇.၄ Test Automation & CI/CD Pipeline

Test တွေ ရေးထားပြီးရင် ဘယ်အချိန် Run မလဲ။ လူကပဲ အမြဲ Command ရိုက်ပြီး Run နေရရင် မေ့ကျန်ခဲ့နိုင်ပါတယ်။ ဒါကြောင့် CI/CD (Continuous Integration / Continuous Deployment) Pipeline တွေမှာ ထည့်သွင်း Run လေ့ ရှိပါတယ်။

Developer က Code ကို GitHub ပေါ် Push လိုက်တာနဲ့ GitHub Actions က အလိုအလျောက် Test တွေကို Run ပေးပါတယ်။ Test Fail ဖြစ်ရင် Merge လုပ်ခွင့် မပေးပါဘူး။ ဒီလိုမှသာ Quality ကို အမြဲ ထိန်းထားနိုင်မှာပါ။

နောက်တချက်က node js library ဖြစ်သည့် husky ကို အသုံးပြုပြီး pre commit , pre push တွေမှာ lint စစ်ဆေးခြင်း type စစ်ဆေး ခြင်း တွေ့ ထည့်ထားခြင်းဖြင့် code quality ကို ထိန်းသိမ်းနိုင်သလို bugs တွေလည်း စောစီးစွာ တွေ့စေနိုင်ပါတယ်။ Github Action cost ကိုလည်း သက်သာ စေနိုင်မှာပါ။ Github Action မှာ fail ဖြစ်လို့ ပြန်စစ်ရတာ ထက် push မလုပ်ခင်မှာ စစ်ဆေးတာ ပိုကောင်းပါလိမ့်မယ်။

pre push မှာ unit test ကို ထည့် run ထားခြင်းဖြင့် pull request မတင်ခင် git ပေါ် မရောက်ခင်မှာ ကိုယ့်စက်ထဲမှာ bugs ကို အရင် ရှာ တွေ့ စေမှာပါ။

၇.၅ Test-Driven Development (TDD)

ပုံမှန်အားဖြင့် Code ရေးပြီးမှ Test ရေးကြပါတယ်။ ဒါပေမယ့် Agile လောကမှာ နာမည်ကြီးတဲ့ နည်းလမ်း တစ်ခုက TDD ဖြစ်ပါတယ်။ သူက ပြောင်းပြန်ပါ။ Test အရင်ရေး၊ ပြီးမှ Code ရေး ရတာပါ။

TDD Cycle ကို Red-Green-Refactor ဟု ခေါ်သည်။

  1. Red: မရှိသေးတဲ့ Feature အတွက် Test တစ်ခု ရေးပါ။ (ဥပမာ - add(1, 2) ဆိုရင် 3 ထွက်ရမယ်ဆိုပြီး Test ရေး)။ Run ကြည့်ပါ။ Fail ပါလိမ့်မယ် (ဘာလို့လဲဆိုတော့ Code မှ မရှိသေးတာ)။
  2. Green: Test Pass ဖြစ်ရုံလောက်ပဲ Code ကို အရိုးရှင်းဆုံး ရေးလိုက်ပါ။ (ဥပမာ - return 3 လို့ ရေးလိုက်ရင်တောင် Pass တာပါပဲ)။ ရည်ရွယ်ချက်က အမြန်ဆုံး Green ဖြစ်ဖို့ပါ။
  3. Refactor: အခုမှ Code ကို သပ်ရပ်အောင် ပြန်ပြင်ပါ။ Logic တွေ အမှန်ထည့်ပါ။ ပြန် Run ရင်လည်း Green ဖြစ်နေရပါမယ်။

TDD ၏ အားသာချက်:

Development လုပ်ရတာ နှေးသလို ခံစားရပေမယ့်၊ Debugging လုပ်ရတဲ့ အချိန် လုံးဝ မရှိသလောက် နည်းသွားပါတယ်။ Code တိုင်းမှာ Test ရှိနေတာ သေချာသွားပါတယ်။

၇.၆ AI ခေတ် Software Verification

ယနေ့ခေတ် AI (LLMs) တွေက Code ရေးပေးနိုင်တဲ့ ခေတ်မှာ Verification က ပိုလို့တောင် အရေးကြီးလာပါတယ်။

1. Trust but Verify (AI Generated Code)

AI က ရေးပေးတဲ့ Code က ကြည့်လိုက်ရင် အမှန်ကြီးလို့ ထင်ရပေမယ့် (Hallucination)၊ Logic မှားတာ၊ Security ပေါက်တာတွေ ပါနိုင်ပါတယ်။ ဒါကြောင့် AI ရေးတဲ့ Code တိုင်းကို လူက Review လုပ်ရမယ်၊ Test နဲ့ စစ်ဆေးရပါမယ်။ အထက်မှာ ပြောခဲ့သလို Pull Request တင်ပြီး developer ၂ ယောက်လောက် စစ်ဆေးပြီးမှ အတည်ပြုသင့်တယ်။ ဒါဆိုရင် AI ရေးထားတာကို ပိုပြီး ယုံကြည်စိတ်ချ နိုင်သလို အမှားတွေကိုလည်း အစောပိုင်းမှာ ရှာတွေ့ နိုင်ပါတယ်။

2. AI as a QA

AI ကို ကိုယ့်ရဲ့ Code ကို ပေးပြီး "ဒီ Function မှာ Edge Case တွေ ဘာတွေ လွတ်နေလဲ၊ Bug ဖြစ်နိုင်ခြေ ရှိလား" လို့ မေးမြန်းခြင်းသည် အလွန်ကောင်းမွန်သော နည်းလမ်း ဖြစ်ပါတယ်။ တစ်ခါတစ်လေ ရေးထားသည့် code တွေထဲကနေ AI ကို Test Plan ထုတ်ပြီး manual စစ်ဆေးတာမျိုး တွေလည်း အဆင်ပြေနိုင်ပါတယ်။

တနည်းပြောရင် AI က ယနေ့ခေတ် Software Development ကို ပိုမို မြန်ဆန် ဖို့ အထောက်အပံ့ ပေးသည့် Tool တစ်ခု ဖြစ်ပါတယ်။

၇.၇ Quality Metrics (တိုင်းတာခြင်း)

"Testing ကောင်းမကောင်း ဘယ်လို သိမလဲ" ဆိုရင် အောက်ပါ Metric တွေကို ကြည့်လေ့ရှိပါတယ်။

  1. Code Coverage:

    • Test တွေက Code base ရဲ့ ဘယ်လောက် ရာခိုင်နှုန်းကို လွှမ်းခြုံထားလဲ။ (80% ဆိုရင် ကောင်းပါတယ်)။
    • သတိပြုရန်: Coverage 100% ဖြစ်တာနဲ့ Bug မရှိဘူးလို့ မဆိုလိုပါ။ Code အလွတ်ကြီးကို Run သွားရင်လည်း Cover ဖြစ်တယ်လို့ ယူဆလို့ပါ။ Assertion (စစ်ဆေးချက်) တွေ မှန်ဖို့ လိုပါတယ်။
  2. Defect Density:

    • Code လိုင်း ၁၀၀၀ မှာ Bug ဘယ်နှစ်ခု တွေ့လဲ။ ဒါက Code quality ကို ယေဘုယျ ပြသပါတယ်။
  3. Flaky Tests:

    • တခါ Run ရင် Pass လိုက်၊ တခါ Run ရင် Fail လိုက် ဖြစ်နေတဲ့ Test တွေ ရှိတတ်ပါတယ်။ (ဥပမာ - Network နှေးလို့ Fail တာမျိုး)။ ဒီလို Test တွေက Developer တွေကို စိတ်ဒုက္ခပေးပါတယ်။ ဒါတွေကို ချက်ချင်း ပြင်ရပါမယ်၊ မရရင် ဖျက်ပစ်တာကမှ ပိုကောင်းပါသေးတယ်။ Test ကို လူက မယုံတော့ရင် Run နေတာ အလကား ဖြစ်သွားလို့ပါ။

Summary

V&V သည် Software ကို ယုံကြည်စိတ်ချစွာ ဖြန့်ချိနိုင်ဖို့ အတွက် မရှိမဖြစ် လိုအပ်ပါတယ်။

Software တစ်ခုဟာ Feature ဘယ်လောက်စုံစုံ၊ Bug တွေနဲ့ ပြည့်နှက်နေရင် ဘယ် User မှ သုံးမှာ မဟုတ်ပါဘူး။

Quality is functionality ဆိုတာ မမေ့ပါနှင့်။