مقدمة: لماذا الاختبار في Rust سهل وموثوق
تم تصميم Rust منذ البداية كلغة تساعد في كتابة كود آمن وموثوق. ومع ذلك، حتى أكثر أنظمة الأنواع صرامة لا تضمن صحة منطق الأعمال. وهنا يأتي دور الاختبار. في Rust، عملية كتابة الاختبارات مدمجة مباشرة في أدوات cargo، مما يجعلها مريحة وسهلة الوصول بشكل لا يصدق.
في هذه المقالة، سنستعرض ثلاثة مستويات من الاختبار: unit (اختبار الوحدة)، integration (اختبار التكامل)، و e2e (اختبار شامل). ستتعلم كيفية كتابة الاختبارات، ومتى تستخدم كل نهج، وكيفية أتمتة التحقق من الكود الخاص بك. ستكون المادة مفيدة لكل من المبتدئين والمطورين ذوي الخبرة الذين ينتقلون إلى Rust.
اختبارات Unit: الاختبار من الداخل
اختبارات Unit (اختبارات الوحدة) هي النوع الأساسي والأكثر شيوعاً من الاختبارات. وهي تتحقق من الدوال الفردية، أو الطرق، أو الوحدات النمطية بشكل منفصل عن باقي النظام. في Rust، من المعتاد كتابة اختبارات unit مباشرة في نفس ملف الكود المختبر، أو في ملف منفصل tests.rs داخل الوحدة النمطية.
كيفية كتابة اختبارات unit في Rust
لإنشاء اختبار، يتم استخدام الخاصية #[test]. توضع الاختبارات في وحدة نمطية تحتوي على الخاصية #[cfg(test)]، والتي تضمن عدم تضمين كود الاختبار في البناء النهائي.
// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
pub fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("Division by zero"))
} else {
Ok(a / b)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, 1), 0);
}
#[test]
fn test_divide_success() {
let result = divide(10.0, 2.0);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 5.0);
}
#[test]
fn test_divide_by_zero() {
let result = divide(10.0, 0.0);
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "Division by zero");
}
}
تشغيل اختبارات unit
يمكن تشغيل الاختبارات بأمر واحد:
cargo test
سيظهر الإخراج عدد الاختبارات التي نجحت والتي فشلت. لتشغيل اختبار معين، استخدم عامل التصفية:
cargo test test_add
اختبارات unit مثالية للتحقق من الحالات الحدودية، ومعالجة الأخطاء، وصحة الخوارزميات. إنها سريعة ولا تتطلب تبعيات خارجية.
اختبارات Integration: التحقق من تفاعل الوحدات النمطية
تتحقق اختبارات التكامل من كيفية عمل الوحدات النمطية المختلفة لمكتبتك أو تطبيقك معاً. على عكس اختبارات unit، ليس لديها إمكانية الوصول إلى الدوال الداخلية (إلا إذا تم تصديرها كـ pub). تُكتب اختبارات التكامل في مجلد منفصل tests/ على مستوى جذر المشروع.
هيكل اختبارات التكامل
أنشئ مجلد tests/ في جذر مشروعك وأضف إليه ملفات الاختبارات. سيتم تجميع كل ملف كـ crate منفصل.
// tests/integration_test.rs
use my_crate; // اسم crate الخاص بك
#[test]
fn test_add_integration() {
assert_eq!(my_crate::add(10, 20), 30);
}
#[test]
fn test_divide_integration() {
let result = my_crate::divide(100.0, 4.0);
assert_eq!(result.unwrap(), 25.0);
}
وحدة نمطية مشتركة للاختبارات
إذا كانت عدة اختبارات تكامل تستخدم دوال مساعدة متطابقة، فقم بإخراجها إلى وحدة نمطية مشتركة. للقيام بذلك، أنشئ مجلد tests/common/mod.rs:
// tests/common/mod.rs
pub fn setup() {
// تهيئة المسجل، قاعدة البيانات، إلخ.
println!("Setting up test environment...");
}
// tests/another_test.rs
mod common;
#[test]
fn test