Thuta Learning
ရှာဖွေရန်
Rust
AdvancedProgrammingbeginner

Testing နှင့် Error-Handling Strategy

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Testing နှင့် Error-Handling Strategy concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ Rust code ကို ကိုယ်တိုင် run ပြီး output စစ်နိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

`#[test]` attribute ကို function တစ်ခုပေါ်တွင် ထားရင် `cargo test` က ဒီ function ကို automatically run ပြီး test ကို "pass" လို့ သတ်မှတ်ဖို့ function ဟာ panic မဖြစ်ရအောင် run ပြီးရမှာဖြစ်ပါတယ်—`assert_eq!`/`assert!` macro တွေက condition မမှန်ရင် panic ဖြစ်စေပြီး failure message ကို ဆွဲထုတ်ပေးပါတယ်။ Unit test တွေက `src/` ထဲမှာ ရေးထားလေ့ရှိပြီး (`#[cfg(test)] mod tests { ... }` ဖြင့်) private function တွေကိုပါ direct access လုပ်နိုင်ပါတယ်—function ငယ်လေးများ correct ဖြစ်ကြောင်း confirm ပါတယ်၊ integration test တွေကတော့ `tests/` directory ထဲ သီးခြားရေးပြီး public API ကိုသာ ခေါ်ကာ real usage pattern ကို simulate ပါတယ်။ Error-handling strategy ဆိုတဲ့ practical decision မှာ Lesson 11 ရဲ့ `Result<T, E>` (recoverable) နှင့် `panic!` (unrecoverable) ကို ဘယ်အချိန် ဘယ်ဟာသုံးရမလဲဆိုတာ rule of thumb ရှိပါတယ်—input ဟာ external source (user input, file, network) ကနေ လာလို့ invalid ဖြစ်နိုင်ခြေရှိရင် `Result` ကို သုံးပြီး caller ဆီ decision ပေးအပ်ရမယ်၊ ဒါပေမယ့် program ရဲ့ internal invariant ("ဒီ situation ဟာ code correct ဆိုရင် ဘယ်တော့မှ မဖြစ်သင့်ဘူး") ကို ချိုးဖောက်တာဆိုရင်တော့ `panic!` က သင့်တော်ပါတယ်—continue လုပ်ရင် data corruption ဖြစ်နိုင်ချေထက် ချက်ချင်းရပ်တန့်တာက ပိုစိတ်ချရလို့ပါ။ Library crate ရေးတဲ့အခါ `panic!` ကို minimum ထားပြီး `Result` ကို preferable ထားသင့်ပါတယ်—library ရဲ့ caller ကို ဘယ်လို error handle ချင်လဲ ဆုံးဖြတ်ခွင့် ပေးရမှာဖြစ်လို့ပါ—application binary (`main.rs`) ထဲမှာတော့ `.unwrap()`/`.expect()` ကို "program continue ရင် အန္တရာယ်ရှိတယ်" ဆိုတဲ့ situation တွေမှာ လက်တွေ့ကျကျ သုံးနိုင်ပါတယ်။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Content analyzer ရဲ့ `count_words` function အတွက် `#[test] fn counts_words_correctly() { assert_eq!(count_words("a b c"), 3); }` unit test ရေးမယ်—refactor လုပ်တိုင်း `cargo test` run ပြီး regression ကို ချက်ချင်းရှာတွေ့နိုင်ပါတယ်။ `read_lesson` function ကို `tests/read_lesson_test.rs` ထဲမှာ integration test ရေးမယ်—actual test fixture file တစ်ခုကို disk ပေါ် ဖန်တီးပြီး public API ကို end-to-end call လုပ်ကြည့်မယ်။ File path parameter ကို empty string ("") ဖြင့် ခေါ်ရင် ဒါဟာ user/caller ရဲ့ invalid input ဖြစ်နိုင်ချေရှိလို့ `Result::Err` ပြန်ပေးမယ်—ဒါပေမယ့် word count ကို accumulate နေရင်း `total` variable ရဲ့ type ကနေ overflow ဖြစ်နေရင် (theoretically ဘယ်တော့မှ ဖြစ်သင့်ခြင်းမဟုတ်တဲ့ internal invariant violation) ဆိုရင် `panic!`/`debug_assert!` ကို သုံးမယ်။

အတူတူ စမ်းရေးကြည့်မယ်

rust
fn count_words(text: &str) -> u32 {
    text.split_whitespace().count() as u32
}

fn read_lesson_body(path: &str) -> Result<String, String> {
    if path.is_empty() {
        return Err(String::from("path must not be empty"));
    }
    Ok(format!("contents of {path}"))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn counts_words_correctly() {
        assert_eq!(count_words("rust ownership basics"), 3);
    }

    #[test]
    fn rejects_empty_path() {
        assert!(read_lesson_body("").is_err());
    }
}
You should see
`cargo test` run လိုက်ရင် "test result: ok. 2 passed" ကို terminal ထဲ ပြသနိုင်မည်။

၅ မိနစ် စမ်းကြည့်

`fn classify(word_count: u32) -> &'static str` (Lesson 5 ကနေ) အတွက် `#[test]` function သုံးခု ရေးပါ—boundary value (499, 500, 1500) တစ်ခုစီအတွက် expected output ကို `assert_eq!` ဖြင့် စစ်ပါ။

သတိလေးတစ်ချက်

External input (user-provided file path, network response) ကို validate လုပ်စရာမလိုလို့ ယူဆပြီး `panic!`/`.unwrap()` ချည်းသာ သုံးခြင်း—user ရဲ့ ရိုးရိုး typo တစ်ခုကတောင် whole program ကို crash ဖြစ်စေနိုင်ပါတယ်—`Result` ဖြင့် gracefully handle သင့်ပါတယ်။

Unit test ကို private function implementation detail အတိအကျ (internal helper တစ်ခုစီ) အထိ over-test လုပ်ခြင်း—implementation ပြောင်းတိုင်း test ကျိုးနေရင် test ဟာ behavior အစား implementation ကို test လုပ်နေတာဖြစ်ပြီး refactor လုပ်ရခက်စေပါတယ်။

The Rust Programming Language — Writing Automated TestsRust

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • External input (user-provided file path, network response) ကို validate လုပ်စရာမလိုလို့ ယူဆပြီး `panic!`/`.unwrap()` ချည်းသာ သုံးခြင်း—user ရဲ့ ရိုးရိုး typo တစ်ခုကတောင် whole program ကို crash ဖြစ်စေနိုင်ပါတယ်—`Result` ဖြင့် gracefully handle သင့်ပါတယ်။
  • Unit test ကို private function implementation detail အတိအကျ (internal helper တစ်ခုစီ) အထိ over-test လုပ်ခြင်း—implementation ပြောင်းတိုင်း test ကျိုးနေရင် test ဟာ behavior အစား implementation ကို test လုပ်နေတာဖြစ်ပြီး refactor လုပ်ရခက်စေပါတယ်။
  • နမူနာ code ကို production system ပေါ် တိုက်ရိုက်မစမ်းဘဲ local/test environment တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

`fn classify(word_count: u32) -> &'static str` (Lesson 5 ကနေ) အတွက် `#[test]` function သုံးခု ရေးပါ—boundary value (499, 500, 1500) တစ်ခုစီအတွက် expected output ကို `assert_eq!` ဖြင့် စစ်ပါ။

You'll know it worked when: `cargo test` run လိုက်ရင် "test result: ok. 2 passed" ကို terminal ထဲ ပြသနိုင်မည်။

Testing နှင့် Error-Handling Strategy | Thuta Learning