✨ Swift 测试:#expect 和 #require 的使用场景

为您每周带来有关 Swift 和 SwiftUI 的精选资讯!

TL;DR: 在 Swift 测试中,#expect 适合非关键断言,失败后继续测试;#require 用于关键条件,需 try 调用,支持解包可选值,失败时终止测试。

#expect#require 是 Swift Testing 框架中常用的断言宏,二者的功能虽有相似之处,但在行为和应用场景上存在重要差异。

主要区别

1. 必须使用 try 关键字

#require 无论布尔值表达式是否会抛出错误,都需要使用 try 调用。 示例代码:

Swift
@Test func person() throws {
    let person = Person(name: "Fat", age: 10)
    try #require(person.age == 10) // 必须使用 try
    #expect(person.name == "Fat") // 不需要 try
}

2. 兼具解包功能

#require 支持直接解包可选值(类似 XCTUnwrap),当解包失败时测试会自动失败。例如:

Swift
@Test func notOptional() throws {
    let person: Person? = Person(name: "Fat", age: 10)
    let unwrappedPerson = try #require(person) // 解包成功
    #expect(unwrappedPerson.name == "Fat")
}

3. 断言失败后的行为

#expect

  • 行为:即使断言失败,测试用例会继续执行。
  • 示例:
Swift
@Test func example() async throws {
    #expect(3 < 0) // 断言失败
    print("next line") // 仍然会执行
}

输出:

◇ Test run started.
✘ Expectation failed: 3 < 0
↳ next line
✘ Test example() failed after 0.001 seconds with 1 issue.

#require

  • 行为:断言失败会直接终止测试用例,后续代码不会执行。
  • 示例:
Swift
@Test func example() async throws {
    try #require(3 < 0) // 断言失败并终止
    print("next line") // 不会执行
}

输出:

◇ Test run started.
✘ Expectation failed: 3 < 0
✘ Test example() failed after 0.002 seconds with 1 issue.

总结

  • #expect:适合不影响测试后续流程的断言。
  • #require:用于关键条件,失败时终止测试。

延伸阅读