用于 XCTest 的断言,可防止致命错误导致进程终止。
支持以下断言。这些函数构建于 CwlPreconditionTesting 之上,该库由 Cocoa with Love 的 Matt Gallagher 创建。 该软件包允许拦截致命错误的信号,以防止进程终止。
XCTAssertThrowFatalError
XCTAssertNoThrowFatalError
此软件包包含演示如何使用这些函数的测试。 请注意,底层软件包目前仅支持 iOS 和 macOS。 对于在 tvOS 和 watchOS 上运行的测试,将抛出一个 XCTSkip
错误,表明测试已跳过,因此它不会直接失败。 这些函数接受一个闭包运行。第一个函数期望抛出致命错误,第二个函数则不期望。 如果引发了致命异常,则第一个断言函数将通过;如果没有,则第二个断言函数将通过。 这些断言函数镜像了 XCTest 中包含的非致命错误断言函数。
将 Swift 包添加到 Xcode 项目时,通常会通过主目标链接它,这通常是预期的构建行为。 但是,正常的构建目标不是测试目标,不应链接 Hela,也不会链接 XCTest。 删除作为链接目标的 Hela 也会从项目中删除 Swift 包,因此首先将 Hela 作为目标依赖项添加到您的测试目标并链接它。 然后,将其作为链接依赖项从主目标中删除。 然后,您的构建应该可以工作。
类型安全可以在编译器的支持下提供很多保护,使许多错误或无效条件变得不可能。 前置条件允许开发人员在运行时施加严格的要求,以补充类型安全。 Apple 倾向于在问题是由程序员错误导致时终止应用程序。 在代码中放置前置条件来验证假设和强制要求可以帮助开发人员了解他们的代码为何无法正常运行,远在它到达生产环境之前。 下面是一个必须在主线程上运行的代码示例,并且需要同步到主线程,但前提是它尚未在主线程上。 在离开当前代码块之前,可能需要在主线程上完成此工作,并且文档会注明运行此代码应在主线程之外进行。
precondition(Thread.isMainThread, "Must not run on main thread")
DispatchQueue.main.sync {
// run code on main thread
}
此前提条件也可以由 Dispatch 框架中的特殊函数处理。 dispatchPrecondition
的一个优点是您还可以检查执行是否在您自己的队列之一上或之外。 以下代码要求执行不在 .main
队列上运行,而是在 serialQueue
上运行。
dispatchPrecondition(condition: .notOnQueue(.main))
dispatchPrecondition(condition: .onQueue(serialQueue))
如果已经在主线程上操作,两者都不允许继续执行。 如果应用程序设法在主线程上运行此代码,则会导致运行时异常,使应用程序崩溃并生成崩溃报告。 该崩溃报告将直接指向此行并显示导致崩溃的代码,这对于诊断崩溃非常有帮助。 如果应用程序继续运行并在以后崩溃,则可能会产生误导,并且需要更多时间来诊断问题。
另一个常见的场景是解包 `self`,该 `self` 在转义闭包中使用捕获列表设置为 *weak*。 在引用闭包范围之外的任何内容时,必须使用 *self*,并且使用 *weak self* 会打破潜在的保留周期。 为了避免保留周期,许多开发人员会进行弱 self 操作,并使用 guard 语句立即解包,该语句需要从 *else* 语句返回。
guard let self = self else { fatalError() }
幸运的是,fatalError
返回 Never,这意味着它永远不会返回。 这是编译器支持的一种特殊类型,它形式化了这种情况。 任何返回 Never
的函数都不会返回,因为该进程应该被终止。 可以在相同的情况下使用 preconditionFailure
,因为它也返回 Never
。 precondition
和 dispatchPrecondition
都不返回 Never
,因为它们有条件地运行。
断言和前提条件之间的一个主要区别是,断言在发布版本中被抑制。 在正常的运行时代码中放置许多断言可以支持开发过程,如果任何断言失败,则会暂停执行,使开发人员可以立即看到代码已达到不良状态。 这些断言无需设置断点,可以保留在代码中以进行持续开发,同时在发布版本中将其删除。 前提条件可以检查绝对要求,例如应用程序正常运行所必需的配置,该配置应包含在应用程序包中。 它还可以要求 Documents 或 Caches 目录存在,除非发生了严重错误,否则它应该存在。 触发崩溃并收集崩溃报告将有助于了解发布版本中的此类问题。 理想情况下,您将在应用程序可供用户使用之前通过早期测试来发现这些问题。
对于测试自动化,断言是 Arrange、Act 和 Assert 周期的一部分。
为什么叫 Hela? Hela 是 Marvel 中的一个角色,她是一位可以复活死者的死灵法师。 一旦引发致命错误,通常进程将会终止。 在 Hela 的帮助下,该进程可以从死亡中复活并继续运行您的测试。