2017-05-30 118 views
4

我有多个测试,每个测试正在测试相同的异步方法,对于给定参数的不同结果。多个异步测试和期望

我发现异步测试,我们必须宣布期望,等待期望,并满足期望。 这很好。每个测试在单独完成时都能正确运行,但是当我尝试运行整个测试类时,有些测试会通过,而其他测试会在运行并正常传递时发生崩溃或失败。

我已经在网上搜索了“swift 3 multiple tests with expectation”,每个解释期望的人都有一个测试方法的例子。 对于同一个班级的多种方法,是否有可能有所期望?

测试的例子如下:

func testLoginWrongUsernameOrPasswordFailure() { 
    let viewModel = LoginViewModel() 
    let loginAPI = APIManager() 
    let expect = expectation(description: "testing for incorrect credentials") 

    viewModel.loginWith(username: "qwerty", password: "qwerty", completion: { loginCompletion in 

     do { 
     try loginCompletion() 
      XCTFail("Wrong Login didn't error") 
      expect.fulfill() 
     } catch let error { 
      XCTAssertEqual(error as? LoginError, LoginError.wrongCredentials) 
      expect.fulfill() 
     } 
     }) 

     waitForExpectations(timeout: 10) { error in 
     XCTAssertNil(error) 
     } 
} 

据我所知,这是正确的使用期望,每个测试遵循相同的模式

按照要求由罗布我将在这里提供一个MCVE https://bitbucket.org/chirone/mcve_test 测试类使用模拟API管理器,但是当我用真实测试时,错误仍然存​​在。

作为对代码的解释,视图模型与调用服务器的给定API管理器进行通信,并将响应返回给视图模型,供他解释错误或成功。

第一个测试空字段的测试,这是视图模型验证的,而不是APIManager。 第二个测试测试不正确的用户名和密码 为有效的用户名和密码,第三次试验测试

三个测试单独运行将运行正常,但是当整个文件运行,我会出现以下原因SIGABRT错误:

XCTAssertEqual失败:( “可选(MCVE.LoginError.wrongCredentials)”)不等于( “可选(MCVE.LoginError.emptyFields)”) -

***在断言失败 - [XCTestExpectation实现],/ Library/Caches /com.apple.xbs/Sources/XCTest_Sim/XCTest-12124/Sources/XCTestFrame工作/异步/ XCTestExpectation.m:101

***终止应用程序由于未捕获的异常“NSInternalInconsistencyException”,理由是:“API违规 - 以制作多个呼叫 - [XCTestExpectation履行]用于测试空字段。”

SIGABRT通常发生在第二种测试方法上,如果你玩游戏,那么它失败的一个XCTest方法声称它得到的错误不是它期望的错误。

我希望MCVE帮助解释我的问题。

+0

当你说“设置”,你指的是'setUp'方法或者是你使用术语更一般(即调用'testLoginWrongUsername'在测试本身的开始,而不是从'setUp')? – Rob

+0

你能分享坠毁的细节吗?更好的是,你可以分享[MCVE](http://stackoverflow.com/help/mcve)吗?仅供参考,我想不出任何在多个异步测试中本质上会产生问题的东西。我们这些做异步测试的人总是有很多,没有发生。如果你从多个测试所产生的问题,我通常怀疑单身或其他'static'变量(这就是为什么我们尽量避免它们),而不是他们正好是异步的事实。 – Rob

+0

嗨,Rob,我按照要求添加了一个MCVE。我现在意识到我使用“setup”这个词的含糊之处,并已将其从帖子中删除以作澄清。我也认为这可能是由单例或静态变量引起的问题,但将API管理器作为实例也无济于事。 – Chirone

回答

1

是否有可能等待多个期望;是。这是一个XCTestCase方法的签名,显示了这一点。

func wait(for: [XCTestExpectation], timeout: TimeInterval) 

有一个版本,也可以确保期望以相同的顺序完成,因为它们出现在for:阵列英寸

见苹果在XCode->窗口 - 提供的文档>文档和API参考,然后搜索XCTestCase。

+0

感谢您的建议。我知道这种方法,但从我能告诉你在一种测试方法中实例化多个期望时使用它。我有多种测试方法。我对此感到抱歉,并调整了我原来的帖子,并且包含一个小型项目,以根据Rob的要求说明我的问题 – Chirone

+0

仔细检查您的'loginWith'完成处理程序。在完成处理程序的参数中传入'loginCompletion'函数似乎很奇怪,而不是从上下文中捕获它。 'loginCompletion'中可能存在一些干扰后续运行的状态。 –

+0

不幸的是我不得不做这种方式,因为我想的'loginWith'方法抛出一个错误(这是该调用者可以做它想要与错误)。但是,因为我使用Alamofire,所以不能从调用Alamofire请求方法的类抛出错误,因为返回类型不兼容。(_)throws - >()'与'(DataResponse )不一样 - >虚空(希望这是有道理的)。 – Chirone