@AddPreviews
使基于预览的 快照测试 更容易。
当应用于预览提供程序时,它...
preview
。只需 import AddPreviews
并将 @AddPreviews
附加到您的预览结构体。
import AddPreviews
@AddPreviews
struct MyView_Previews: PreviewProvider {
static var stateOne: some View { MyView(state: .one) }
static var stateTwo: some View { MyView(state: .two) }
}
这将生成一个 previews
属性,其中包含您的每个视图状态,以及显示名称,以便轻松识别您在 Xcode 中查看的是哪个状态。
// (Generated)
static var previews: some View {
stateOne.previewDisplayName("stateOne")
stateTwo.previewDisplayName("stateTwo")
}
真正的神奇之处在于消除了 快照测试 中的样板代码。
@AddPreviews
使带注释的预览提供程序可迭代其每个视图属性,从而将快照测试从以下形式简化为:
import SnapshotTesting
import XCTest
final class MyViewTests: XCTestCase {
func testStateOne() {
assertSnapshot(of: MyView_Previews.stateOne, as: .image(layout: .device(config: .yourDevice)))
}
func testStateTwo() {
assertSnapshot(of: MyView_Previews.stateTwo, as: .image(layout: .device(config: .yourDevice)))
}
}
简化成这种形式 - 代码可以轻松地随着新预览状态的添加而扩展。
import SnapshotTesting
import XCTest
final class MyViewTests: XCTestCase {
func testPreviews() {
for preview in MyView_Previews() {
assertSnapshot(of: preview, as: .image(layout: .device(config: .yourDevice)), named: preview.name)
}
}
}
您所要做的就是在添加或更改时重新记录快照,或者在删除预览状态时删除未使用的参考图像。
这种模式使编写设备尺寸视图的 快照测试 变得轻而易举,如上面所示!
也就是说,这种模式最适合应该拥有自己的参考图像的屏幕大小的视图。 对于较小的视图,这种方法有点过头了,一个包含堆栈中多个状态的预览可以直接简单地编写和快照,如下所示
预览
struct RowView_Previews: PreviewProvider {
static var previews: some View {
VStack {
RowView(title: "Title")
RowView(title: "Title", subtitle: "Subtitle")
RowView(title: "Title", subtitle: "Subtitle") {
Image(systemSymbol: .envelopeFill)
}
}
}
}
快照
final class RowViewTests: XCTestCase {
func testPreviews() {
assertSnapshot(of: RowView_Previews.previews, as: .image(layout: .device(config: .yourDevice)))
}
}
#Preview 很棒、简洁,并且被定位为 Xcode 预览的未来,但它不支持 PreviewProvider
那样的方式进行快照测试,如上所示。
使用 #Preview
会生成一个带有乱码类型名称的结构体,如下所示: $s17<YourTarget>33_5594AE1E7369B73F633885FC4E970BA7Ll7PreviewfMf_15PreviewRegistryfMu_
虽然从技术上讲可以引用此类型名称(尽管不建议这样做),但仍然没有可以从中提取出来并插入到快照测试中的 View
。 关于 Xcode 如何将这些预览转换为视图,DeveloperToolsSupport 目前是一个黑盒。
该库在 MIT 许可证下发布。 有关详细信息,请参见 LICENSE。