ข้ามไปยังเนื้อหา

Testing — #[test], cargo test และ Doctest

ใน TypeScript คุณใช้ Jest (หรือ Vitest) เขียน describe/it/expect ไว้ใน .test.ts แยกไฟล์ ส่วน Rust มี test runner ติดมากับ compiler อยู่แล้ว: แปะ #[test] บน function ไหนก็ได้ แล้ว cargo test จะไล่หาและรันให้เองทั้งหมด — ไม่ต้องพึ่ง crate ภายนอก

TypeScript
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
// math.test.ts
import { add } from './math';
test('adds two numbers', () => {
expect(add(3, 4)).toBe(7);
});
Rust
// 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 จะตัดทิ้งให้อัตโนมัติ

Terminal window
cargo test # รัน test ทั้งหมดใน project
cargo test test_add # รัน test ที่ชื่อมี "test_add"
cargo test -- --nocapture # แสดง println! output ระหว่าง test
cargo test -- --test-threads=1 # รัน test ตามลำดับ (ไม่ parallel)
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 กำหนดเอง
#[test]
#[should_panic(expected = "divide by zero")]
fn test_divide_by_zero() {
divide(10, 0); // function นี้ควร panic
}

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 test binary และไม่สามารถรันใน browser playground ได้ snippet ด้านล่างใช้ fn main กับ assert_eq! เพื่อสาธิต logic เดียวกัน — รัน cargo test ใน local สำหรับประสบการณ์ test suite เต็มรูปแบบ

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!");
}
Attribute ใดทำเครื่องหมาย Rust function ว่าเป็น test?
`#[cfg(test)]` ทำอะไร?
Macro ใดเทียบเท่ากับ `expect(a).toBe(b)` ของ Jest?
Rust integration test อยู่ที่ไหน?