[英]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)
}
在調用站點,您可以讓默認參數提供file
和line
。 所以它看起來像:
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.