Swift Testing 是苹果的 XCTest 现代替代库,并引入了新的宏,如 #require。我们之前已经介绍了 #expect 宏,现在将深入研究它的同伴,为给定的测试设置需求。
每个 #require 宏都需要通过测试才能继续。这是一种早期的逻辑预期,除非满足所有要求,否则不会继续。虽然使用 Swift Testing 编写测试不需要宏,但它会使测试更清晰、更容易理解。让我们开始吧。
#reqiure
许多测试在开始测试目标之前需要特定的输入需求。你可以使用带有 #expect 宏的常规断言来编写这些需求。例如,当我们有一个带有可选初始化式的 Person 结构时:
struct Person {
let firstName: String
let lastName: String
var fullName: String {
firstName + " " + lastName
}
init?(firstName: String, lastName: String) {
guard !lastName.isEmpty else {
return nil
}
self.firstName = firstName
self.lastName = lastName
}
}
我们可以编写一个测试 fullName 的需求,以确保构造的 person 不是 nil:
@Test func fullName() {
let person = Person(firstName: "Zhang", lastName: "San")
#expect(person != nil, "Zhang San")
#expect(person?.fullName == "Zhang San")
}
然而,#expect宏并没有使它变得可读性更高,也没有清楚地表明它是测试开始时的必要条件。自我解释的代码是健壮的,在项目中应该始终是你的目标。因此,我们可以使用#require宏重写上面的测试,如下所示:
@Test func fullName() throws {
let person = Person(firstName: "Zhang", lastName: "San")
try #require(person != nil, "Person 结构体未成功初始化")
#expect(person?.fullName == "Zhang San")
}
这是一个细微的差别,但测试变得更容易理解。我们可以通过使用#require宏的返回值进一步优化这个测试。
总结
Swift testing 框架可以让我们用新的 API 和像 #require 这样的宏来编写现代测试。虽然你不一定必须用 #require 宏来编写测试,但它将使你的代码自解释并且更加健壮。