尽管 XCTest 仍是在 Xcode 中创建测试的首选方式,但新的 Swift Testing 框架试图为测试的定义引入一个富有表达力且直观的 API,它适用于支持 Swift 的所有平台。该框架还支持参数化、并行化、分类以及将测试与缺陷关联起来。
Swift Testing 广泛使用了宏,以此来提供声明复杂行为的惯用方式。例如,我们可以像这样声明一个测试,其中包含了一个名称和一组要运行的备选输入:
import Testing
...
@Test("Sample test", arguments: [
"input string 1",
"input string 2",
"input string 3"
])
func sampleTest(sampleInput: String) {
...
}上述的测试会执行三次,每次调用都会通过sampleInput接受一个我们所提供的参数。在进行参数化测试时,还可以处理多个输入。在这种情况下,我们会为@Test的arguments提供一个集合列表,测试函数将在两个集合中选取每个集合中可能的参数,并将它们的值组合起来:
@Test("Multiple collections as test inputs", arguments: 0...100, ["a", ..., "z"])
func test(number: Int, letter: String) {
}在arguments的特定条件下,我们可以有选择性的运行参数化测试,所以当只有少量输入值失败时,没有必要对所有可能的输入值组合运行测试。
除了可以声明名称和参数列表之外,@Test宏还支持为测试函数 关联 trait。现有的 trait可以根据运行时条件启用或禁用测试、限制测试运行时间、串行或并行运行测试、将测试与缺陷关联等。例如,我们可以按照如下的方式,只有启用了特定的应用程序特性,才运行测试:
@Test(.enabled(if: App.ConditionToMatch))
func conditionalTest() {
...
}开发人员还可以通过实现符合 TestTrait 的类型来定义自己的 trait。
参数化测试的另一个好处在于,测试失败所产生的诊断结果会清楚地指出失败时的输入。
测试函数可以组织成测试套件(test suite)。传统的做法是将它们放在同一个测试class中。Swift Testing 还为此提供了一个特定的宏@Suite。属于测试套件的所有测试函数都继承套件的相同 trait,包括tags(_:)或disabled(_:sourceLocation:)。
为了校验测试结果,Swift Testing 提供了两个宏expect(_:_:sourceLocation:)和require(_:_:sourceLocation:)。require会在不满足条件时抛出异常停止测试的执行,而expect则会打印详细信息。
有一个重要的注意事项,在构建发布版本时,测试函数不会从二进制文件中剥离出来。因此,苹果强烈建议将测试库导入测试目标(test target),而不是与主可执行文件链接在一起。
Swift Testing 位于 GitHub 和 Swift Package Index 上,需要 Swift 6 环境。XCTest 和 Swift Testing 可以共存于同一项目中,因此如果你想采用新框架,不一定必须迁移现有的测试。
查看英文原文:
Swift Testing is a New Framework from Apple to Modernize Testing for Swift Across Platforms (https://www.infoq.com/news/2024/09/swift-testing-framework/)
声明:本文由 InfoQ 翻译,未经许可禁止转载。
热门跟贴