xcode - 在运行测试之前,如何让 XCTest 在 setUp 中等待异步调用?

标签 xcode unit-testing swift asynchronous xctest

我正在 Xcode 6 中编写集成测试,以配合我的单元和功能测试。 XCTest 有一个 setUp() 方法,在每次测试之前都会调用它。伟大的!

它还有 XCTestException,让我可以编写异步测试。也很棒!

但是,我想在每次测试之前用测试数据填充我的测试数据库,并且 setUp 只是在异步数据库调用完成之前开始执行测试。

有没有办法让 setUp 等到我的数据库准备好后再运行测试?

这是我现在所做的一个例子。由于 setUp 在数据库完成填充之前返回,因此我必须在每次测试时复制大量测试代码:

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)
            }
        }

    }

}

最佳答案

您可以使用在异步测试用例中使用的相同 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];
}

关于xcode - 在运行测试之前,如何让 XCTest 在 setUp 中等待异步调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29504712/

相关文章:

c++ - 在 iPhone xcode 应用程序中,是否可以声明具有全局范围的指针?

swift - `swift test` 产生 "symbol(s) not found for architecture x86_64"链接器错误

Swift Promises - 重新加载数据方法未绑定(bind)数据

ios - 如何根据用户选择在 CollectionView 标题下方显示不同的单元格?

ios - Xcode UI 测试允许系统警报系列

java - 将 PowerMockito 与静态方法一起使用时出现异常

c# - 尝试在新的 AppDomain 中加载混合的 C# 和 C++/CLI dll 时,从错误的 AppplicationBase 加载 DLL

ios - Google geocoding api OVER_QUERY_LIMIT 在 5 个请求后发生

ios - 将两个以上的参数传递给选择器,该选择器由字符串组成

ios - 在 Xcode 9/iOS 11 中将应用程序图标自定义为构建阶段