在 Swift playground 中編寫單元測試

在 Swift playground 中編寫單元測試

Swift playground 對於試用新的 framework探索語言的新特性來講十分有用。它提供的實時反饋能讓你快速嘗試新的想法與解決方案,大大提升生產力。html

自 Swift 問世以來,不管是設計 framework API,仍是給 app 開發新功能,我一直在不停地使用 playground,但願找到將它整合進工做流的辦法。前端

本週,讓咱們來了解如何將 Swift playground 應用於編寫單元測試,以及如何讓 TDD - 測試驅動開發(ish)工做流變得更加順暢。android

基礎

實際上在 playground 編寫測試與編寫 test target 基本一致。你能夠先導入 XCTest,而後建立測試用例,例如:ios

import Foundation
import XCTest

class UserManagerTests: XCTestCase {
    var manager: UserManager!

    override func setUp() {
        super.setUp()
        manager = UserManager()
    }

    func testLoggingIn() {
        XCTAssertNil(manager.user)

        let user = User(id: 7, name: "John")
        manager.login(user: user)
        XCTAssertEqual(manager.user, user)
    }
}
複製代碼

如何訪問你的代碼

不過,若是你尚未實現直接在 playground 中測試的代碼,那麼在剛開始時訪問代碼可能會有點麻煩。你必須根據代碼的來源( app 仍是 framework ),而選擇不一樣的方式來訪問將要測試的代碼git

測試 app 代碼github

因爲能夠在編寫 playground 時不直接導入 app target,所以可使用下面的幾種方法測試 app 代碼:swift

1) 複製代碼 這大概是最簡單的方法了。將想測試的代碼複製至 playground 運行,最後再拷回去。這個方法簡單粗暴。後端

2) 複製文件 若是你不想直接將要測試的代碼放到 playground 中,也能夠將須要的源文件複製到 playground 的 Sources 目錄中(使用 ⌘ + 0 顯示 organizer,而後將文件拖進去)。接下來同上,在運行測試以後再將改變後的文件拷回覆蓋源文件。xcode

3) 建立 framework target 若是你討厭複製文件,你也能夠建立一個包含須要測試代碼的 framework。在 Xcode 中建立一個新的 framework(或使用 SwiftPlate 建立一個跨平臺 framework),接着按照下面的步驟操做。bash

測試 framework 代碼

你能夠經過如下操做將任意 framework 加入 playground:

  • 將 framework 的 Xcode 工程拖入 playground 的 organizer 中。
  • 系統將提示你將 playground 保存爲一個工做區,照作便可(請注意不要將 playground 的內部工做區覆蓋掉,而應該在 playground 文件夾外去建立一個新的工做區)。
  • 打開此工做區。
  • 選擇你的 framework 的 scheme,對其進行構建。
  • 如今,能夠 import 你的 framework,開始編碼了!

若是你但願自動執行上述操做,可使用我寫的腳本 - Playground,它能讓你經過一行命令完成上述除了 framework 的構建與 import 以外的全部操做:

$ playground -d /Path/To/Framework/Project.xcodeproj
複製代碼

運行測試

如今已經能夠訪問須要測試的代碼了,而且咱們還爲其編寫好了一個測試用例。如今試着運行這個測試用例! 🚀

在通常的 test target 中,你通常會使用 ⌘ + U 來運行你的測試;但在 playground 中,我但願 Xcode 能自動運行測試(以得到舒爽的實時反饋)。最簡單的實現方式就是爲你的測試用例運行 defaultTestSuite,以下所示:

UserManagerTests.defaultTestSuite().run()
複製代碼

執行上面的操做會運行測試,並將測試結果轉儲至控制檯(可以使用 ⌘ + ⇧ + C 呼出)。這樣作雖然沒問題,但很容易錯過錯誤信息。爲此,能夠建立一個測試觀察者(test observer),在測試發生錯誤時觸發一個斷言失敗(assertionFailure)錯誤:

class TestObserver: NSObject, XCTestObservation {
    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
        assertionFailure(description, line: lineNumber)
    }
}

let testObserver = TestObserver()
XCTestObservationCenter.shared().addTestObserver(testObserver)
複製代碼

在開始測試出現失敗時,咱們將看到編輯器提示一個行內錯誤 🎉

若是你用的是 Swift 4,須要將上面的代碼改爲下面這樣:

class TestObserver: NSObject, XCTestObservation {
    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) {
        assertionFailure(description, line: UInt(lineNumber))
    }
}

let testObserver = TestObserver()
XCTestObservationCenter.shared.addTestObserver(testObserver)
UserManagerTests.defaultTestSuite.run()
複製代碼

總結

雖然須要額外作一些設置,但我仍是很喜歡使用 Swift playground 進行單元測試。我以爲這樣經過快速的反饋並輕鬆進行修改,更加接近理想中的紅綠重構。這也能夠構建更健壯的測試與更高的測試覆蓋率。

我我的傾向於爲正在開發的 app 與 framework 準備好一個 playground,以便更輕鬆地深刻調試。此外,我還傾向於圍繞 framework 構建 app,這樣只需簡單將代碼引入 playground 就能開始編碼。我會在以後的博文中討論這些結構與設置的細節。

你怎麼看?你是否準備使用 playground 進行單元測試?或者你是否在嘗試其它方法?請經過評論或 Twitter @johnsundell 讓做者知道你的意見、問題與反饋。

感謝您的閱讀 🚀


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索