Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XCTest and asynchronous testing in Xcode 6

Tags:

xcode

ios

xctest

So Apple said in the release note of Xcode 6 that we can now do asynchronous testing directly with XCTest.

Anyone knows how to do it using Xcode 6 Beta 3 (Using objective-C or Swift)? I don't want the known semaphore method, but the new Apple way.

I searched into the released note and more but I found nothing. The XCTest header is not very explicit either.

like image 867
Dimillian Avatar asked Jul 11 '14 18:07

Dimillian


People also ask

What is the test method to test an asynchronous operation in XCTest?

XCTest provides two approaches for testing asynchronous code. For Swift code that uses async and await for concurrency, you mark your test methods async or async throws to test asynchronously.

What is XCTest in Xcode?

Overview. Use the XCTest framework to write unit tests for your Xcode projects that integrate seamlessly with Xcode's testing workflow. Tests assert that certain conditions are satisfied during code execution, and record test failures (with optional messages) if those conditions aren't satisfied.

How do I run XCTest in Xcode?

To run your app's XCTests on Test Lab devices, build it for testing on a Generic iOS Device: From the device dropdown at the top of your Xcode workspace window, select Generic iOS Device. In the macOS menu bar, select Product > Build For > Testing.

What is the difference between XCTest and XCUITest?

XCTest / XCUITest is pure iOS and cannot help the team that needs to test both iOS and Android devices. XCUITest was built for the iOS and Xcode Developer in mind and focuses less on the QA Automation Engineer.


4 Answers

Obj-C example:

- (void)testAsyncMethod
{

    //Expectation
    XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method Works!"];

    [MyClass asyncMethodWithCompletionBlock:^(NSError *error, NSHTTPURLResponse *httpResponse, NSData *data) {

        if(error)
        {
            NSLog(@"error is: %@", error);
        }else{
            NSInteger statusCode = [httpResponse statusCode];
            XCTAssertEqual(statusCode, 200);
            [expectation fulfill];
        }

    }];


    [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) {

        if(error)
        {
            XCTFail(@"Expectation Failed with error: %@", error);
        }

    }];
}
like image 129
jonbauer Avatar answered Oct 23 '22 12:10

jonbauer


The sessions video is perfect, basically you want to do something like this

func testFetchNews() {
    let expectation = self.expectationWithDescription("fetch posts")

    Post.fetch(.Top, completion: {(posts: [Post]!, error: Fetcher.ResponseError!) in
        XCTAssert(true, "Pass")
        expectation.fulfill()
    })

    self.waitForExpectationsWithTimeout(5.0, handler: nil)
}
like image 52
Dimillian Avatar answered Oct 23 '22 12:10

Dimillian


Session 414 covers async testing in Xcode6

https://developer.apple.com/videos/wwdc/2014/#414

like image 11
mittens Avatar answered Oct 23 '22 10:10

mittens


How I did in swift2

Step 1: define expectation

let expectation = self.expectationWithDescription("get result bla bla")

Step 2: tell the test to fulfill expectation right below where you capture response

responseThatIGotFromAsyncRequest = response.result.value
expectation.fulfill()

Step 3: Tell the test to wait till the expectation is fulfilled

waitForExpectationsWithTimeout(10)

STep 4: make assertion after async call is finished

XCTAssertEqual(responseThatIGotFromAsyncRequest, expectedResponse)
like image 1
Ankit Vij Avatar answered Oct 23 '22 11:10

Ankit Vij