Testing — #[test], cargo test และ Doctest
Jest → cargo test
หัวข้อที่มีชื่อว่า “Jest → cargo test”ใน TypeScript คุณใช้ Jest (หรือ Vitest) เขียน describe/it/expect ไว้ใน .test.ts แยกไฟล์ ส่วน Rust มี test runner ติดมากับ compiler อยู่แล้ว: แปะ #[test] บน function ไหนก็ได้ แล้ว cargo test จะไล่หาและรันให้เองทั้งหมด — ไม่ต้องพึ่ง crate ภายนอก
Unit test อยู่ใกล้ code
หัวข้อที่มีชื่อว่า “Unit test อยู่ใกล้ code”// math.tsexport function add(a: number, b: number): number { return a + b;}
// math.test.tsimport { add } from './math';test('adds two numbers', () => { expect(add(3, 4)).toBe(7);});// src/lib.rs (test อยู่ใน file เดียวกัน)pub fn add(a: i32, b: i32) -> i32 { a + b}
#[cfg(test)]mod tests { use super::*; // import ทุกอย่างจาก parent module
#[test] fn test_add() { assert_eq!(add(3, 4), 7); }
#[test] fn test_add_negative() { assert_eq!(add(-1, 1), 0); }}attribute #[cfg(test)] หมายความว่า test module จะ compile เฉพาะตอนรัน cargo test เท่านั้น — release build จะตัดทิ้งให้อัตโนมัติ
การรัน test
หัวข้อที่มีชื่อว่า “การรัน test”cargo test # รัน test ทั้งหมดใน projectcargo test test_add # รัน test ที่ชื่อมี "test_add"cargo test -- --nocapture # แสดง println! output ระหว่าง testcargo test -- --test-threads=1 # รัน test ตามลำดับ (ไม่ parallel)Assertion macro ที่ใช้บ่อย
หัวข้อที่มีชื่อว่า “Assertion macro ที่ใช้บ่อย”assert_eq!(left, right); // expect(a).toBe(b)assert_ne!(left, right); // expect(a).not.toBe(b)assert!(condition); // expect(condition).toBeTruthy()assert!(condition, "message {}", 42); // พร้อม failure message กำหนดเองการคาดหวัง panic (เหมือน Jest’s toThrow)
หัวข้อที่มีชื่อว่า “การคาดหวัง panic (เหมือน Jest’s toThrow)”#[test]#[should_panic(expected = "divide by zero")]fn test_divide_by_zero() { divide(10, 0); // function นี้ควร panic}Doctest — test ใน doc comment
หัวข้อที่มีชื่อว่า “Doctest — test ใน doc comment”Rust รัน code example ที่เขียนใน /// doc comment ได้จริง ตัวอย่างชุดเดียวจึงทำหน้าที่เป็นทั้ง documentation และ test
/// บวกเลขจำนวนเต็มสองตัวเข้าด้วยกัน////// # Examples////// ```/// let result = my_crate::add(2, 3);/// assert_eq!(result, 5);/// ```pub fn add(a: i32, b: i32) -> i32 { a + b}รันด้วย command เดิม: cargo test
Playground note: function
#[test]ต้องการ context ของcargo testbinary และไม่สามารถรันใน browser playground ได้ snippet ด้านล่างใช้fn mainกับassert_eq!เพื่อสาธิต logic เดียวกัน — รันcargo testใน local สำหรับประสบการณ์ test suite เต็มรูปแบบ
ลองเลย — logic ที่จะ test
หัวข้อที่มีชื่อว่า “ลองเลย — logic ที่จะ test”fn add(a: i32, b: i32) -> i32 { a + b}
fn is_even(n: i32) -> bool { n % 2 == 0}
fn main() { // ทดสอบ logic ด้วยตนเอง (ใน project จริงใช้ #[test]) assert_eq!(add(3, 4), 7); assert_eq!(add(-1, 1), 0); assert!(is_even(4)); assert!(!is_even(7)); println!("All assertions passed!");}Compiling…