الاختبار القائم على الخصائص في Swift: اصطد الأخطاء التي لم تبحث عنها

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

الاختبار القائم على الخصائص في Swift: عندما تفشل الاختبارات التقليدية

\n\n

هل سبق لك أن كتبت اختبار وحدة ينجح "بامتياز"، ثم يتعطل التطبيق على بيانات حقيقية؟ مألوف، أليس كذلك؟ الاختبارات التقليدية القائمة على الأمثلة (عندما نتحقق من مدخل ومخرج محددين) جيدة، لكن لديها عيب أساسي: فهي تتحقق فقط مما نبتكره نحن بأنفسنا. ماذا لو كان الخطأ يعيش على حدود القيم المسموح بها، أو في تركيبة لم تخطر على بالنا ببساطة؟

\n\n

هنا يظهر على الساحة الاختبار القائم على الخصائص في Swift. إنه نهج تصف فيه ليس حالات محددة، بل خصائص (properties) يجب أن تكون صحيحة لـ أي بيانات إدخال. ويقوم إطار عمل خاص (مثل SwiftCheck) بتوليد مئات القيم العشوائية والتحقق مما إذا كانت خاصيتك قد انتهكت. إذا تم العثور على خطأ، يقوم الإطار "بتقليل" بيانات الإدخال - وستحصل على أبسط مثال ينهار فيه كل شيء.

\n\n

في هذه المقالة، سنشرح كيفية دمج الاختبار القائم على الخصائص في Swift في مشروعك، وسنكتب أمثلة كود حقيقية، ونرى أي الأخطاء يمكن اكتشافها بهذا النهج. هيا بنا!

\n\n

ما هو الاختبار القائم على الخصائص ولماذا هو مطلوب؟

\n\n

تخيل أنك تختبر دالة تقوم بترتيب مصفوفة. بدلاً من كتابة 10 اختبارات بمصفوفات مختلفة، تقول: "بالنسبة لأي مصفوفة، بعد الترتيب لا يتغير الطول، وكل عنصر أصغر أو يساوي الذي يليه". هذه هي الخاصية - الثابت الذي يجب أن يتحقق.

\n\n

الاختبار القائم على الخصائص في Swift مثالي لـ:

\n
    \n
  • التحقق من الدوال الرياضية (الجمع، القسمة، التقريب)؛
  • \n
  • اختبار المحللات والمُسلسِلات (التسلسل → إلغاء التسلسل يجب أن يعيد الأصل)؛
  • \n
  • التحقق من منطق الأعمال مع عدد كبير من التركيبات؛
  • \n
  • البحث عن الانحدارات على القيم الحدودية.
  • \n
\n\n

المكافأة الرئيسية: تجد أخطاء لم تكن تعلم بوجودها. وهذا، كما توافق، أفضل من تأكيد الواضح.

\n\n

SwiftCheck - الأداة الرئيسية للاختبار القائم على الخصائص في Swift

\n\n

في عالم Swift، الإطار الأكثر شيوعًا لهذا النهج هو SwiftCheck. إنه ينقل الأفكار من Haskell (مكتبة QuickCheck) ويتكامل بشكل ممتاز مع XCTest.

\n\n

للبدء، أضف التبعية في Package.swift:

\n\n
// swift-tools-version:5.9\nimport PackageDescription\n\nlet package = Package(\n    name: "MyProject",\n    dependencies: [\n        .package(url: "https://github.com/typelift/SwiftCheck.git", from: "0.12.0")\n    ],\n    targets: [\n        .testTarget(\n            name: "MyProjectTests",\n            dependencies: ["SwiftCheck"]),\n    ]\n)\n
\n\n

الآن يمكنك كتابة الاختبارات. دعنا نشرح بناء الجملة الأساسي.

\n\n

أول اختبار قائم على الخصائص: التحقق من الجمع

\n\n

لنكتب خاصية بسيطة: "الجمع تجميعي". لأي أعداد صحيحة a + b + c يجب أن يساوي (a + b) + c.

\n\n
import XCTest\nimport SwiftCheck\n\nclass MathPropertiesTests: XCTestCase {\n    func testAdditionIsAssociative() {\n        property("الجمع تجميعي") <- forAll { (a: Int, b: Int, c: Int) in\n            return (a + b) + c == a + (b + c)\n        }\n    }\n}\n
\n\n

نشغل الاختبار - يقوم بتشغيل 100 تركيبة عشوائية (افتراضيًا). إذا فشل واحد على الأقل، سيعرض SwiftCheck القيم المحددة. لاحظ: نحن لا نحدد أي رقم محدد! الاختبار القائم على الخصائص في Swift يولد البيانات بنفسه.

\n\n

التحقق من التحويل العكسي (roundtrip)

\n\n

هذا هو النمط الأكثر شيوعًا. لنفترض أن لدينا هيكلًا يتم تسلسله إلى JSON. الخاصية: "بعد التسلسل وإلغاء التسلسل نحصل على نفس الشيء".

المدونات

توصيات الكتب