اختبر ضمانات قاعدتك على ملفات الهجرة الحقيقية
كتبت في قاعدة البيانات مجموعة قيود: سجل لا يقبل التعديل، وفهارس unique، ومراجع بين الجداول. وبعد كتابتها احتجت طريقة تثبت أنها تعمل.
الخطأ الشائع
أن ينشئ الاختبار جداوله بنفسه:
db.exec("CREATE TABLE posts (id INTEGER, slug TEXT)");
هذه السطور تختبر ما كتبته أنت في الاختبار، لا ما يعمل في الإنتاج. الـ schema الحقيقي يحمل قيودا و triggers وفهارس لا أثر لها في هذين السطرين، فيمر الاختبار بينما ينكسر الإنتاج.
ما أفعله
أشغل ملفات الـ migrations نفسها على قاعدة تعمل في الذاكرة:
for (const f of readdirSync(migrations).filter(f => f.endsWith('.sql')).sort()) {
db.exec(readFileSync(path.join(migrations, f), 'utf8'));
}
كل اختبار يبدأ بقاعدة جديدة، مبنية بالطريقة نفسها التي يبنى بها الإنتاج.
ما كشفه لي هذا فعلا
اتضح أن الـ schema سليم، والعيب كان في بيانات الاختبار نفسها: كنت أدرج صفوفا ناقصة الأعمدة، والمخطط الحقيقي يفرض حقولا إلزامية لم أكن أمررها. فشل الاختبار، وكان الفشل في محله.
وكشف أيضا عمودا لا وجود له. افترضت وجوده في جدول المدفوعات وهو غير موجود أصلا، ولولا تشغيل الـ migrations الحقيقية لبقي هذا الافتراض قائما.
ما يصير سهلا بعد ذلك
اختبار القيود مباشرة:
assert.throws(() => insertSameKeyTwice(), /UNIQUE/);
سطر كهذا يثبت أن الضمان موجود فعلا، لا أنك نويت وجوده.
المصيدة
الترتيب مهم. رتب ملفات الـ migrations بالاسم قبل تنفيذها. الترتيب الأبجدي يكفي ما دامت الأسماء مرقمة بأصفار بادئة: 0001, 0002, 0010. بدون هذه الأصفار سيأتي 10 قبل 2.
ما آخذه من هذا
المخطط الذي تختبره والمخطط الذي تنشره يجب أن يكونا الشيء نفسه. أي فرق بينهما سيظهر يوما ما في الإنتاج، بلا اختبار يمسكه.