xcode5 मैं सेन्टीस्टिंग किट/OCUnit से XCTest पर कैसे जाऊँ?




(2)

मैं अपने प्रोजेक्ट को Xcode 4.6.3 से Xcode 5.0.2 तक माइग्रेट करने की प्रक्रिया में हूं। इस परियोजना की इकाई परीक्षण सेनटिटिंगकिट / ओसीयूनिट के साथ विकसित किए गए थे। अब जब मैं Xcode 5 में परीक्षण चला रहा हूं, तो मुझे मुझे बताकर RunUnitTests स्क्रिप्ट से एक त्रुटि मिली

RunUnitTests अप्रचलित है।

संभवतः संबंधित Xcode 5 रिलीज़ नोटों में यह नोट है:

SenTestingKit और OCUnit को हटा दिया गया है। XCTest पर जाने के लिए प्रवासी का उपयोग करें।

दुर्भाग्य से, मैं इस रहस्यमय "प्रवासी" के बारे में अधिक पता नहीं लगा पाया हूं। संभवतः मेरे google-fu में [फिर से] कमी है, इसलिए मेरा मुख्य सवाल यह है: मैं सेन्टेसिंगकिट / OCUnit से नए XCTest ("माइग्रेटर" के साथ) के बिना यूनिट परीक्षणों को कैसे स्थानांतरित करूं?

एक माध्यमिक प्रश्न, अगर माइग्रेट करना एक जटिल व्यवसाय है: क्या यूनिट परीक्षण चलाने के लिए Xcode 5 प्राप्त करना संभव है जो अभी भी SenTestingKit / OCUnit पर आधारित हैं? आखिरकार, ये केवल पदावनत हैं, इसलिए उन्हें अभी भी चारों ओर और कार्यात्मक होना चाहिए।


Edit -> Refactor -> XCTest में बदलें

OCUnit परीक्षण अभी भी काम करेंगे, लेकिन आप भी पलायन कर सकते हैं। परिवर्तन बहुत कम हो रहे हैं।


झबरा मेंढक के जवाब के लिए धन्यवाद, हम जानते हैं कि Xcode रिलीज़ नोटों में उल्लिखित रहस्यमय "माइग्रेटर" एक जादूगर है जिसे "Edit> Refactor> Convert To XCTest" का चयन करके लॉन्च किया गया है। मैं दो हिस्सों में इस जादूगर के साथ अपने अनुभव के बारे में लिखने जा रहा हूं। पहला भाग प्राथमिक प्रश्न का अधूरा उत्तर है, दूसरा भाग द्वितीयक प्रश्न का उत्तर देता है।

भाग 1: OCUnit से XCTest पर कैसे जाएं

पहली चीज जो आपको महसूस करने की आवश्यकता है वह यह है कि विज़ार्ड को काम करने के लिए, आपको एक इकाई परीक्षण लक्ष्य का चयन करने की आवश्यकता है। यदि आपके पास मुख्य लक्ष्य चयनित है, तो विज़ार्ड केवल कन्वर्ट करने के लिए किसी भी लक्ष्य को सूचीबद्ध नहीं करता है।

एक बार जब मुझे इस बारे में पता चला, तो मैं विज़ार्ड के माध्यम से कदम रखने में सक्षम था, लेकिन मेरे मामले में अंतिम परिणाम अभी भी एक शानदार विफलता थी! विज़ार्ड ने दावा किया कि कोई भी स्रोत परिवर्तन आवश्यक नहीं थे और केवल XCTest पर माइग्रेट करने के लिए अपडेट की जाने वाली सेटिंग का निर्माण करना आवश्यक था। अंत में, विज़ार्ड ने इसे सही ढंग से करने का प्रबंधन भी नहीं किया: इसने सेनटाइटिंगकिट फ्रेमवर्क के संदर्भ को हटा दिया, लेकिन इसने एक्ससीटीस्ट फ्रेमवर्क के संदर्भ में नहीं डाला।

वैसे भी, निम्न प्रकार से उन परिवर्तनों की एक सूची है जो मुझे मैन्युअल रूप से बनाने थे क्योंकि विज़ार्ड मेरे लिए उन्हें बनाने में विफल रहा। यदि विज़ार्ड आपके लिए बेहतर काम करता है, तो आपको इन सभी चीजों को करने की आवश्यकता नहीं हो सकती है।

  1. इकाई परीक्षण लक्ष्य से "रन स्क्रिप्ट" बिल्ड चरण निकालें
  2. SenTestCase से SenTestCase के सभी टेस्ट केस क्लास के बेस क्लास को XCTestCase
  3. इंपोर्टेड हेडर को <SenTestingKit/SenTestingKit.h> से <XCTest/XCTest.h>
  4. परीक्षण लक्ष्य की बिल्ड सेटिंग में, Wrapper एक्सटेंशन को octest से octest में xctest
  5. ST* से STAssertTrue XCT* तक सभी STAssertTrue मैक्रोज़ का नाम बदलें (जैसे STAssertTrue बन जाता है)
  6. उपरोक्त अपवाद: STAssertEquals नाम बदलकर XCTAssertEqual (अंत में लापता "s" पर ध्यान देने की आवश्यकता है)। आपको पता चल जाएगा कि आप इस बारे में भूल गए हैं यदि आपको यह संकलक चेतावनी मिलती है: warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
  7. नए XCTest मुखर मैक्रोज़ nil को विफलता विवरण के रूप में पारित करने की अनुमति नहीं देते हैं। उदाहरण के लिए, XCTAssertNotNil(anObject, nil) संभव नहीं है और इसे XCTAssertNotNil(anObject) बदल दिया जाना चाहिए। आपको पता चल जाएगा कि यह कंपाइलर त्रुटि मिलने पर आपको यह समस्या है: error: called object type 'NSString *' is not a function or function pointer
  8. यदि आपको एक विफलता विवरण पास करने की आवश्यकता है, तो नए XCTest मुखर मैक्रो को प्रारूप स्पेसियर के लिए निरंतर अभिव्यक्ति की आवश्यकता होती है, जिस तरह NSString वर्ग विधि NSString stringWithFormat: करता है। आपको पता चल जाएगा कि जब आपको यह कंपाइलर एरर: error: expected ')' मिलता है तो आपको यह समस्या होती है। कुछ उदाहरण:
NSString* formatSpecifier = @"%@";
NSString* failureDescription = @"foo";
// These are OK
XCTAssertNotNil(anObject, @"foo")
XCTAssertNotNil(anObject, @"%@", failureDescription)
// These are not OK
XCTAssertNotNil(anObject, failureDescription);
XCTAssertNotNil(anObject, formatSpecifier, failureDescription);

अंतिम लेकिन कम से कम, जैसा कि पहले ही आगे बताया गया है, XCTest ढांचे के संदर्भ को इकाई परीक्षण लक्ष्य में जोड़ने की आवश्यकता है। आपको पता चल जाएगा कि अगर आप Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo जैसे लिंकर त्रुटियों को प्राप्त करते हैं तो आप इसे भूल गए हैं Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo

Xcode 6 अपडेट : Xcode 6 के खिलाफ लिंकिंग की आवश्यकता अब Xcode 6 में नहीं है (वास्तव में XCTest को अब उपलब्ध फ्रेमवर्क के रूप में सूचीबद्ध नहीं किया गया है)। इसके बजाय बिल्ड सेटिंग CLANG_ENABLE_MODULES को YES पर सेट करें (UI में "सक्षम मॉड्यूल (C और उद्देश्य-C)" के रूप में)। यह XCTest के खिलाफ स्वचालित रूप से लिंक करने का कारण बनेगा जब यह एक #import <XCTest/XCTest.h> विवरण देखता है। विवरण क्लैंग डॉक्यूमेंटेशन के "मॉड्यूल्स" खंड में उपलब्ध हैं।

भाग 2: Xcode 5 में OCUnit परीक्षण कैसे चलाएं

इस बिंदु पर मुझे एक लिंकर त्रुटि मिली जिससे मुझे एहसास हुआ कि XCTest में स्थानांतरित करने का मेरा मिशन विफल हो गया था। कारण: XCTest SDK 6.1 का हिस्सा नहीं है, लेकिन मैं अभी भी अपनी परियोजना का निर्माण आधार SDK iOS 6.1 के साथ कर रहा हूं ( यह SO उत्तर बताता है कि SDK 6.1 को Xcode 5 में कैसे एकीकृत किया जाए)।

चूंकि मैं माइग्रेशन को जारी रखने में असमर्थ हूं, इसलिए पल के लिए मेरा समाधान इसलिए है कि जब तक मैं अपने ऐप को आईओएस 7 में अपग्रेड न करूं, तब तक सेन्टस्टिंग किट / ओसीयूनाइट के आधार पर अपनी यूनिट परीक्षण जारी रखें। यही वह है जो मुझे करना था इकाई परीक्षण चलाने के लिए:

  1. इकाई परीक्षण लक्ष्य से "रन स्क्रिप्ट" बिल्ड चरण निकालें। यह वह सब है जो "टेस्ट" कार्रवाई ( that + U ) के माध्यम से यूनिट परीक्षण निष्पादित करने के लिए Xcode निष्पादित करने के लिए आवश्यक है, जबकि इकाई परीक्षण लक्ष्य चयनित है
  2. हालांकि, यह आदर्श नहीं है, क्योंकि मैं केवल यूनिट परीक्षणों को निष्पादित करने के लिए लक्ष्य स्विच नहीं करना चाहता हूं। इसके बजाय मैं मुख्य परीक्षणों का चयन करते समय इकाई परीक्षणों को निष्पादित करना चाहता हूं। दूसरा चरण इसलिए मुख्य लक्ष्य की Xcode योजना को संशोधित करना है ताकि जब मैं "परीक्षण" कार्रवाई चलाऊं, तो इकाई परीक्षण लक्ष्य के परीक्षणों को इसके बजाय निष्पादित किया जाए।

अंतिम समाधान Xcode 4.x में उतना अच्छा नहीं है जहां यूनिट परीक्षणों को हर बार स्वचालित रूप से निष्पादित किया गया था जो कि मैंने मुख्य लक्ष्य की "रन" या "बिल्ड" कार्रवाई को चलाया था। दुर्भाग्य से, ऐसा लगता है कि मैं "रन स्क्रिप्ट" बिल्ड चरण के बिना काम करने के लिए इसे प्राप्त नहीं कर सकता।