اختبارات Swift: الوحدة، التكامل، E2E — المستوى المتقدم

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

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

ابدأ الدورة

الاختبارات المتقدمة في Swift: الوحدة والتكامل و E2E



الاختبارات ليست مجرد فحص، بل هي أساس الكود الموثوق. على المستوى المتقدم، يحتاج مطور Swift ليس فقط إلى كتابة الاختبارات، بل إلى بناء هرم الاختبارات بشكل صحيح: من اختبارات الوحدة السريعة إلى سيناريوهات end-to-end (e2e) المعقدة. في هذه المقالة، سنستعرض التقنيات المتقدمة لمشاريع iOS/macOS: العمل مع التبعيات، اختبارات تكامل CoreData، وأتمتة واجهة المستخدم.



1. اختبارات الوحدة: إدارة التبعيات والمحاكاة (Mocks)



على المستوى المتقدم، يجب أن تكون اختبارات الوحدة معزولة. التقنية الأساسية هي حقن التبعيات (Dependency Injection - DI). بدلاً من اختبار طبقة الشبكة الحقيقية أو قاعدة البيانات، نقوم باستبدالها بمحاكاة (Mocks).



مثال: البروتوكول و DI

protocol NetworkServiceProtocol {    func fetchData(completion: @escaping (Result<String, Error>) -> Void)}

class ViewModel { private let networkService: NetworkServiceProtocol init(networkService: NetworkServiceProtocol) { self.networkService = networkService } func loadData() { networkService.fetchData { result in // معالجة النتيجة } }}

// محاكاة للاختباراتclass MockNetworkService: NetworkServiceProtocol { var shouldReturnError = false func fetchData(completion: @escaping (Result<String, Error>) -> Void) { if shouldReturnError { completion(.failure(NSError(domain: "test", code: -1))) } else { completion(.success("Mock data")) } }}


في الاختبار، تقوم بإنشاء MockNetworkService وتمريره إلى ViewModel. هذا يسمح باختبار سيناريوهات الخطأ والنجاح دون الحاجة إلى API حقيقي.



XCTestExpectation للعمليات غير المتزامنة

func testViewModelLoadDataSuccess() {    let mock = MockNetworkService()    let viewModel = ViewModel(networkService: mock)        let expectation = self.expectation(description: "تم تحميل البيانات")        viewModel.loadData()        // محاكاة استدعاء غير متزامن    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {        expectation.fulfill()    }        waitForExpectations(timeout: 1.0)    // التحقق من حالة ViewModel}


2. اختبارات التكامل: CoreData والعمل مع البيانات الحقيقية



تتحقق اختبارات التكامل من تفاعل المكونات. بالنسبة لـ CoreData، نستخدم حاوية في الذاكرة (in-memory container) لتجنب تلويث قاعدة البيانات الرئيسية.



إعداد CoreData في الذاكرة

class CoreDataTestStack {    lazy var persistentContainer: NSPersistentContainer = {        let container = NSPersistentContainer(name: "MyModel")        let description = NSPersistentStoreDescription()        description.type = NSInMemoryStoreType        container.persistentStoreDescriptions = [description]        container.loadPersistentStores { _, error in            if let error = error {                fatalError("فشل تحميل المخزن: \\(error)")            }        }        return container    }()        var context: NSManagedObjectContext {        return persistentContainer.viewContext    }}


مثال اختبار تكامل

func testSaveAndFetchUser() {    let stack = CoreDataTestStack()    let repository = UserRepository(context: stack.context)        // إنشاء مستخدم    let user = User(context: stack.context)    user.name = "مستخدم اختبار"    user.age = 30        try? stack.context.save()        // التحقق من حفظ البيانات    let fetchRequest: NSFetchRequest<User> = User.fetchRequest()    let users = try? stack.context.fetch(fetchRequest)        XCTAssertEqual(users?.count, 1)    XCTAssertEqual(users?.first?.name, "مستخدم اختبار")}


هام: بعد كل اختبار، قم بمسح السياق (context) لضمان عدم تأثير الاختبارات على بعضها البعض.

المدونات

توصيات الكتب