"पहले टेस्ट - फिर कोड": यह Swift में क्यों काम करता है?
\n\nक्या आपने कभी एक ही मॉड्यूल को तीसरी बार फिर से लिखा है क्योंकि "इसे तुरंत लॉन्च करना ज़रूरी था"? या प्रोडक्शन में कोई बग पकड़ा जिसे लिखने के चरण में ही रोकना आसान था? अगर हाँ - तो TDD (Test-Driven Development) की दुनिया में आपका स्वागत है।
\n\nटेस्ट-ड्रिवन डेवलपमेंट सिर्फ एक फैशनेबल पद्धति नहीं है। यह सोचने का एक तरीका है जो आपको कोड लिखने से पहले यह स्पष्ट करने पर मजबूर करता है कि कोड को कैसे व्यवहार करना चाहिए। Swift में, अपनी सख्त टाइपिंग और शक्तिशाली XCTest फ्रेमवर्क के साथ, TDD रिग्रेशन और अप्रत्याशित क्रैश के खिलाफ एक विश्वसनीय ढाल बन जाता है।
इस लेख में, हम वास्तविक उदाहरणों के साथ TDD को समझेंगे, नेटवर्क लेयर और डेटा मॉडल के लिए टेस्ट लिखेंगे, और सबसे महत्वपूर्ण बात - यह समझेंगे कि इस अभ्यास को बिना दर्द के कैसे लागू किया जाए। चलिए शुरू करते हैं!
\n\nलाल-हरा-रीफैक्टरिंग: चक्र का जादू
\n\nTDD का आधार तीन चरणों का एक चक्र है:
\n\n- \n
- लाल (Red) - हम एक ऐसा टेस्ट लिखते हैं जो पास नहीं होता (क्योंकि कोड अभी मौजूद नहीं है)। \n
- हरा (Green) - हम न्यूनतम कोड लिखते हैं ताकि टेस्ट पास हो जाए। \n
- रीफैक्टरिंग (Refactor) - हम कोड को बेहतर बनाते हैं, उसके व्यवहार को बदले बिना (टेस्ट सुरक्षा प्रदान करते हैं)। \n
सरल लगता है? Swift पर प्रयास करते हैं।
\n\nपहला टेस्ट: User मॉडल की जाँच
\n\nमान लीजिए, हमारे पास एक सरल उपयोगकर्ता मॉडल है। हम चाहते हैं कि यह पूरा नाम सही ढंग से फ़ॉर्मेट करे। पहले - टेस्ट:
\n\nimport XCTest\n@testable import MyApp\n\nfinal class UserTests: XCTestCase {\n \n func testFullName_GivenFirstNameAndLastName_ReturnsFormattedString() {\n // Arrange\n let user = User(firstName: "अन्ना", lastName: "कैरेनिना")\n \n // Act\n let fullName = user.fullName()\n \n // Assert\n XCTAssertEqual(fullName, "अन्ना कैरेनिना", "पूरा नाम पहले नाम और अंतिम नाम से स्पेस के साथ बना होना चाहिए")\n }\n}\n\n\nचलाते हैं - टेस्ट फेल होता है (लाल)। कंपाइलर शिकायत करता है कि User मौजूद नहीं है। बढ़िया, यही अपेक्षित है।
अब टेस्ट पास करने के लिए न्यूनतम कोड लिखते हैं:
\n\nstruct User {\n let firstName: String\n let lastName: String\n \n func fullName() -> String {\n return "\\(firstName) \\(lastName)"\n }\n}\n\n\nचलाते हैं - हरा! अब रीफैक्टरिंग पर जा सकते हैं। उदाहरण के लिए, खाली स्ट्रिंग या मिडल नेम को हैंडल करना। लेकिन जल्दी न करें - टेस्ट बताएंगे कि कब इसकी ज़रूरत है।
\n\nएसिंक्रोनस नेटवर्क लेयर का परीक्षण
\n\niOS डेवलपमेंट में सबसे आम समस्याओं में से एक है नेटवर्क के साथ काम करना। TDD यहाँ विशेष रूप से उपयोगी है क्योंकि आप स्पष्ट रूप से लॉजिक को नेटवर्क कॉल से अलग करते हैं।
\n\nप्रोटोकॉल और mock-ऑब्जेक्ट लिखना
\n\nपहले परिभाषित करते हैं कि हमारी सेवा कैसी दिखनी चाहिए:
\n\nprotocol WeatherServiceProtocol {\n func fetchWeather(for city: String, completion: @escaping (Result<Weather, Error>) -> Void)\n}\n\n\nअब - टेस्ट। हम वास्तविक API पर निर्भर नहीं होना चाहते, इसलिए एक mock बनाते हैं:
\n\nclass MockWeatherService: WeatherServiceProtocol {\n var shouldReturnError = false\n var mockWeather: Weather?\n \n func fetchWeather(for city: String, completion: @escaping (Result<Weather, Error>) -> Void) {\n if shouldReturnError {\n completion(.failure(NetworkError.serverError))\n } else if let weather = mockWeather {\n completion(.success(weather))\n }\n }\n}\n\nfinal class WeatherViewModelTests: XCTestCase {\n \n func testFetchWeather_Success_UpdatesModel() {\n // Arrange\n let mockService = MockWeatherService()\n mockService.mockWeather = Weather(temperature: 25.0, condition: "धूप")\n let viewModel = WeatherViewModel(service: mockService)\n let expectation = XCTestExpectation(description: "मौसम लोड होने की प्रतीक्षा")\n \n