多个异步测试和期望 [英] multiple asynchronous tests and expectation

查看:91
本文介绍了多个异步测试和期望的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个测试,每个测试都在给定参数的情况下测试相同的异步方法以获得不同的结果.

I have multiple tests and each test is testing the same asynchronous method for different results with given parameters.

我发现对于异步测试,我们必须声明一个期望值,等待期望值并实现期望值.这可以.每个测试单独完成时都可以正常工作,但是当我尝试运行整个测试类时,某些测试会通过,而其他一些则在正常运行并通过时会崩溃或失败.

I found out for asynchronous tests we have to declare an expectation, wait for expectation, and fulfil the expectation. This is fine. Each test works out correctly when done separately, but when I try to run the whole test class some tests pass and others crash or fail when they run and pass normally.

我已经在网上寻找了快速进行3次带有期望的多重测试",每个解释期望的人都只能在一种测试方法中举一个例子.在同一个类中的多个方法中不可能有期望吗?

I've looked all over online for "swift 3 multiple tests with expectation" and everyone who explains expectation only ever has an example in one test method. Is it not possible to have expectations in multiple methods in the same class?

一个测试示例如下:

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

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

As far as I'm aware, this is the correct use of expectation and each test follows the same pattern

根据Rob的要求,我将在此处提供MCVE https://bitbucket.org/chirone/mcve_test测试类使用模拟API管理器,但是当我使用真实的API管理器进行测试时,仍然会发生错误.

As requested by Rob I will provide an MCVE here https://bitbucket.org/chirone/mcve_test The test classes use a mock API Manager but when I was testing with the real one the errors still occurred.

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

As an explanation for the code, the view-model communicates with a given API manager who invokes a server and gives back the response to the view-model for him to interpret the errors or success.

第一个测试将对空字段进行测试,而视图模型会验证该字段,而不是APIManager进行验证.第二项测试测试不正确的用户名和密码第三次测试测试有效的用户名和密码

The first test tests for empty fields, something that the view-model validates rather than the APIManager. The second test tests for incorrect username and password The third test tests for valid username and password

分别运行的三个测试可以正常运行,但是当运行整个文件时,由于以下原因,我会收到SIGABRT错误:

The three tests run separately will run fine, however when the whole file is run I will get a SIGABRT error with the following reasons:

XCTAssertEqual失败:(" Optional(MCVE.LoginError.wrongCredentials))不等于(""Optional(MCVE.LoginError.emptyFields)")-

XCTAssertEqual failed: ("Optional(MCVE.LoginError.wrongCredentials)") is not equal to ("Optional(MCVE.LoginError.emptyFields)") -

***-[XCTestExpectation满足],/Library/Caches/com.apple.xbs/Sources/XCTest_Sim/XCTest-12124/Sources/XCTestFramework/Async/XCTestExpectation.m:101

*** Assertion failure in -[XCTestExpectation fulfill], /Library/Caches/com.apple.xbs/Sources/XCTest_Sim/XCTest-12124/Sources/XCTestFramework/Async/XCTestExpectation.m:101

***由于未捕获的异常"NSInternalInconsistencyException"而终止应用程序,原因:违反API-多次调用-[XCTestExpectation履行]以测试空字段."

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'API violation - multiple calls made to -[XCTestExpectation fulfill] for testing for empty fields.'

SIGABRT通常发生在第二种测试方法上,如果您按一下播放,则它会在XCTest方法之一上失败,声称该错误不是预期的错误.

The SIGABRT happens usually on the second test method and if you hit play then it fails on one of the XCTest methods claiming the error it got is not the error it was expecting.

我希望MCVE可以帮助解释我的问题.

I hope the MCVE helps explain my problem.

推荐答案

重构了以下代码.

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

      } catch let error {
        XCTAssertEqual(error as? LoginError, LoginError.wrongCredentials)
      }
      expect.fulfill()
   })

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

如果仍然遇到以下崩溃,则意味着异步代码的完成处理程序将多次调用.然后多次调用 expect.fulfill().不允许.

If you are still getting the following crash, that means your completion handler for the asynchronous code is calling multiple time. And there by invoking expect.fulfill() multiple times. Which is not allowed.

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'API violation - multiple calls made to -[XCTestExpectation fulfill] for testing for empty fields.'

出于期望, fulfill()应该只调用一次.如果有一些罕见的情况,并且您需要多次调用 expect.fulfill(),然后设置以下属性.

For an expectation fulfill() should call only once. If there are some rare scenarios and you need to invoke expect.fulfill() more than once then set the following property.

expectedFulfillmentCount

请参考以下链接 https://developer.apple.com/documentation/xctest/xctestexpectation/2806572-expectedfulfillmentcount?language = objc

这篇关于多个异步测试和期望的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆