簡體   English   中英

Swift - 在 Xcode 中內聯顯示斷言失敗,如 XCTest 失敗?

[英]Swift - Display assertion failures inline in Xcode like XCTest failures?

我想編寫一些自定義測試斷言類型並將它們顯示在 Xcode 中,類似於 XCTAssert() 失敗的顯示方式:

有沒有辦法讓我連接到 Xcode 並實現這一點?

我希望我自己的斷言函數在這里以相同的方式內聯顯示其錯誤:

在此處輸入圖片說明

到目前為止,我找到的最好的資源是 Apple 的 XCTest源代碼,但我無法理解它是否包括負責顯示錯誤 UI 的邏輯。

最簡單的方法是從您的自定義斷言中調用XCTFail() ,但傳遞調用站點的文件名和行號。 例如:

func verify(myThing: MyThing, file: StaticString = #filePath, line: UInt = #line) {
   // Do your verification. Then when you want to fail the test,
   XCTFail("Some message about \(myThing)", file: file, line: line)
}

在調用站點,您可以讓默認參數提供fileline 所以它看起來像:

verify(myThing: thing)

在 Swift 中,XCTest 斷言是全局函數。 這意味着您的 helper 也可以是一個全局函數,並在測試套件之間共享,而無需子類XCTestCase

完全可以做你想做的事,我只是設法做到了,就像這樣:

使用記錄recordFailure

您可以通過在任何測試中調用recordFailure來實現您想要的(繼承自標准XCTestCase )。

更短的語法

要么擴展XCTestCase

如果您想簡化對此函數的調用,您可以編寫一個擴展函數來包裝它。

或子類

您還可以將XCTestCase子類XCTestCase (如果您想共享一些設置,這可能是一個好主意,在setup中調用,然后您只需要在這個新的超類中為您的測試類執行此操作)。

class TestCase: XCTestCase {

  func forwardFailure(
        withDescription description: String = "Something went wrong",
        inFile filePath: String = #file,
        atLine line: Int = #line,
        expected: Bool = false
    ) {
        self.recordFailure(
            withDescription: description,
            inFile: filePath,
            atLine: line,
            expected: expected
        )
    }

}

我不確定如何使用expected: Bool ,它是recordFailure方法 (source)的必需參數,但看起來 Apple 大多將其設置為false

自定義斷言方法

現在您可以像這樣聲明您的自定義斷言方法(或作為XCTestCase的擴展,取決於您的選擇):


extension TestCase {

    /// Since `Foobar.Type` does not conform to `Equatable`, even if `Foobar` conforms to `Equatable`, we are unable to write `XCTAssertEquals(type(of: foo), Foobar.self)`, this assert method fixes that.
    func XCTAssertType<Actual, Expected>(
        of actual: Actual,
        is expectedType: Expected.Type,

        _ filePath: String = #file,
        _ line: Int = #line
    ) {

        if let _ = actual as? Expected { return /* success */  }
        let actualType = Mirror(reflecting: actual).subjectType

        forwardFailure(
            withDescription: "Expected '\(actual)' to be of type '\(expectedType)', but was: '\(actualType)'",

            inFile: filePath,
            atLine: line
        )
    }

}

現在它報告錯誤,不是在自定義斷言中,而是在調用站點 🎉。

使用標准斷言方法 + 文件中的轉發位置

您也可以只轉發該line並傳遞給標准斷言,如果您查看XCTAssertTrue ,它接受一個行參數和一個file參數。

使用Xcode 12我們可以使用XCTIssue內聯斷言,並且不推薦使用現有的recordFailure 這是測試的例子

import XCTest
@testable import TestAssertionForward

class TestAssertionForwardTests: XCTestCase {

    func testExample() throws {
        assert(actual: 10, expected: 20) // asserts in method
        assert(actual: 10, expected: 11) // asserts in method
        assertInLine(actual: 10, expected: 11) // asserts in line
        assertInLine(actual: 10, expected: 11) // asserts in line
    }
}

extension TestAssertionForwardTests {

    func assert(actual: Int, expected: Int) {
        XCTAssertEqual(actual, expected)
    }

    func assertInLine(actual: Int, expected: Int, filePath: String = #file, lineNumber: Int = #line) {
        if actual != expected {
            let location = XCTSourceCodeLocation(filePath: filePath, lineNumber: lineNumber)
            let context = XCTSourceCodeContext(location: location)
            let issue = XCTIssue(type: .assertionFailure,
                                 compactDescription: "\(actual) is not equal to \(expected)",
                                 detailedDescription: nil,
                                 sourceCodeContext: context,
                                 associatedError: nil,
                                 attachments: [])
            record(issue)
        }
    }
}

下面是失敗斷言的截圖

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM