2015-04-08 10 views
31

मैं अपनी इकाई और कार्यात्मक परीक्षण के साथ जाने के लिए एक्सकोड 6 में एकीकरण परीक्षण लिख रहा हूं। XCTest में एक सेटअप() विधि है जिसे प्रत्येक परीक्षण से पहले बुलाया जाता है। महान!परीक्षण चलाने से पहले सेटअप में एसिंक कॉल की प्रतीक्षा करने के लिए मैं एक्ससीटीएस्ट कैसे प्राप्त कर सकता हूं?

इसमें XCTestException भी है जो मुझे एसिंक परीक्षण लिखने देता है। भी महान!

हालांकि, मैं प्रत्येक परीक्षण से पहले परीक्षण डेटा के साथ अपने परीक्षण डेटाबेस को पॉप्युलेट करना चाहता हूं और सेटअप केवल एसिंक डेटाबेस कॉल करने से पहले परीक्षण निष्पादित करना शुरू कर देता है।

क्या सेटअप समाप्त होने से पहले मेरा डेटाबेस तैयार होने तक सेटअप प्रतीक्षा करने का कोई तरीका है?

यहां मैंने जो किया है उसका एक उदाहरण यहां दिया गया है।

func test_checkSomethingExists() { 

    let expectation = expectationWithDescription("") 
    var expected:DatabaseItem 

    // Fill out a database with data. 
    var data = getData() 
    overwriteDatabase(data, { 
     // Database populated. 
     // Do test... in this pseudocode I just check something... 
     db.retrieveDatabaseItem({ expected in 

     XCTAssertNotNil(expected) 

     expectation.fulfill() 
     }) 
    }) 

    waitForExpectationsWithTimeout(5.0) { (error) in 
     if error != nil { 
      XCTFail(error.localizedDescription) 
     } 
    } 

} 

यहाँ मैं चाहते हैं क्या करना है::

class MyTestCase: XCTestCase { 

    override func setUp() { 
     super.setUp() 

     // Fill out a database with data. I can make this call do anything, here 
     // it returns a block. 
     var data = getData() 
     db.overwriteDatabase(data, onDone:() ->() { 

      // When database done, do something that causes setUp to end 
      // and start running tests 

     })   
    } 

    func test_checkSomethingExists() { 

     let expectation = expectationWithDescription("") 
     var expected:DatabaseItem 


      // Do test... in this pseudocode I just check something... 
      db.retrieveDatabaseItem({ expected in 

      XCTAssertNotNil(expected) 

      expectation.fulfill() 
     }) 

     waitForExpectationsWithTimeout(5.0) { (error) in 
      if error != nil { 
       XCTFail(error.localizedDescription) 
      } 
     } 

    } 

} 
+0

आप के लिए अतिप्रवाह ढेर खोज करते हैं "[iOS] अतुल्यकालिक इकाई परीक्षण" आप न केवल 'XCTestExpectation' (नहीं' XCTestException') तकनीक, लेकिन यह भी सेमाफोर तकनीक के साथ जवाब में से एक टन देखेंगे। जैसे http://stackoverflow.com/a/23658385/1271826। आप शायद अपने async डेटाबेस कोड के लिए सेमफोर तकनीक का उपयोग कर सकते हैं (हालांकि आपने यह साझा नहीं किया है कि आप यह डेटाबेस सामग्री कैसे कर रहे हैं ताकि हम उससे अधिक विशिष्ट न हों)। मुझे आश्चर्य है कि आपकी डेटाबेस लाइब्रेरी में एक तुल्यकालिक सुविधा नहीं है, क्योंकि यह डेटाबेस पुस्तकालयों में बहुत आम है। – Rob

+0

रोब, मैंने अपना प्रश्न संपादित करने के लिए संपादित किया जो मैं ढूंढ रहा हूं। मुझे पता है कि एसिंक परीक्षण लिखने के लिए XCTest और XCTestException का उपयोग कैसे करें। मुझे नहीं पता कि सेट अप होने तक परीक्षणों को कैसे चलाना है। धन्यवाद। –

+0

लॉल। फिर, 'XCTestException' जैसी कोई चीज़ नहीं। यह 'XCTestExpectation' है। और जैसा कि मैंने कहा, 'सेटअप' में सेमफोर तकनीक का उपयोग करें, न कि 'XCTestExpectation'। (परीक्षणों में अपेक्षाओं का उपयोग करें, लेकिन 'सेटअप' में सेमफोर का उपयोग करें।) – Rob

उत्तर

19

अतुल्यकालिक परीक्षण चलाने के लिए दो तकनीकों हैं के बाद से डेटाबेस से पहले सेटअप रिटर्न पॉप्युलेट किया जाता है मैं परीक्षण कोड का एक बहुत हर परीक्षण नकल करने की है। XCTestExpectation और सेमफोरस। है कि काम करने के लिए के लिए

override func setUp() { 
    super.setUp() 

    // Fill out a database with data. I can make this call do anything, here 
    // it returns a block. 

    let data = getData() 

    let semaphore = dispatch_semaphore_create(0) 

    db.overwriteDatabase(data) { 

     // do some stuff 

     dispatch_semaphore_signal(semaphore) 
    } 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 
} 

ध्यान दें,, इस onDone ब्लॉक मुख्य थ्रेड पर नहीं चल सकता (वरना आप गतिरोध जाएगा): setUp में कुछ अतुल्यकालिक कर के मामले में, आप सेमाफोर तकनीक का उपयोग करना चाहिए।


इस onDone ब्लॉक मुख्य कतार पर चलता है, तो आप को चलाने का उपयोग कर सकते छोरों:

override func setUp() { 
    super.setUp() 

    var finished = false 

    // Fill out a database with data. I can make this call do anything, here 
    // it returns a block. 

    let data = getData() 

    db.overwriteDatabase(data) { 

     // do some stuff 

     finished = true 
    } 

    while !finished { 
     NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture()) 
    } 
} 

यह एक बहुत अक्षम पैटर्न है, लेकिन overwriteDatabase कैसे लागू किया गया था पर निर्भर करता है, यह आवश्यक हो सकता है

नोट, केवल इस पैटर्न का उपयोग करें यदि आप जानते हैं कि onDone ब्लॉक मुख्य धागे पर चलता है (अन्यथा आपको finished चर के कुछ सिंक्रनाइज़ेशन करना होगा)।

+0

क्या यह काम करने के लिए वैसे भी है अगर ऑनडोन ब्लॉक मुख्य धागे में चलता है? –

+0

मैंने इसे उदाहरण के साथ अपडेट किया है जो मुख्य धागे पर 'ऑनडोन' चलने पर रनलोप्स का उपयोग करता है। – Rob

63

सेमफोर या अवरुद्ध लूप का उपयोग करने के बजाय, आप उसी waitForExpectationsWithTimeout:handler: फ़ंक्शन का उपयोग अपने एसिंक परीक्षण मामलों में उपयोग कर सकते हैं।

// Swift 
override func setUp() { 
    super.setUp() 

    let exp = expectation(description: "\(#function)\(#line)") 

    // Issue an async request 
    let data = getData() 
    db.overwriteDatabase(data) { 
     // do some stuff 
     exp.fulfill() 
    } 

    // Wait for the async request to complete 
    waitForExpectations(timeout: 40, handler: nil) 
} 

// Objective-C 
- (void)setUp { 
    [super setUp]; 

    NSString *description = [NSString stringWithFormat:@"%s%d", __FUNCTION__, __LINE__]; 
    XCTestExpectation *exp = [self expectationWithDescription:description]; 

    // Issue an async request 
    NSData *data = [self getData]; 
    [db overwriteDatabaseData: data block: ^(){ 
     [exp fulfill]; 
    }];   

    // Wait for the async request to complete 
    [self waitForExpectationsWithTimeout:40 handler: nil]; 
} 
+2

बढ़िया! यह ऐप्पल की सिफारिश करता है - Xcode API संदर्भ में XCTestExpectation पर खोजें। इच्छा है कि मैं ओबीजेसी और स्विफ्ट दोनों के लिए मतदान को दोगुना कर दूं! –

+0

हां, यहां सही जवाब है। –

+2

यह स्वीकार्य उत्तर होना चाहिए। NSHipster से एसिंक्रोनस परीक्षण http://nshipster.com/xctestcase/ के साथ काम करने के तरीके के बारे में बताते हुए एक शानदार पोस्ट है। – isanjosgon

संबंधित मुद्दे