2017-05-30 48 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