Nimble 匹配器用于 iOSSnapshotTestCase。最初源自 Expecta Matchers for FBSnapshotTestCase。
安装
CocoaPods
您需要使用CocoaPods 0.36 Beta 1或更高版本。您的Podfile应如下所示。
platform :ios, '10.0'
source 'https://github.com/CocoaPods/Specs.git'
# Whichever pods you need for your app go here.
target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do
pod 'Nimble-Snapshots'
pod 'Quick' # if you want to use it with Quick
end
然后运行
$ pod install
Carthage
您需要使用Carthage 0.18或更高版本。您的Cartfile(或Cartfile.private)应如下所示。
github "Quick/Quick" ~> 4.0
github "Quick/Nimble" ~> 9.2
github "uber/ios-snapshot-test-case" "8.0.0"
github "ashfurrow/Nimble-Snapshots"
然后运行
$ carthage bootstrap --use-xcframeworks --platform iOS
Swift Package Manager
要将 Nimble-Snapshots
添加为依赖项,您需要在您的 Package.swift
文件的依赖项中添加它,并在您的目标中引用此依赖项。
import PackageDescription
let package = Package(
name: "<Your Product Name>",
dependencies: [
.package(url: "https://github.com/ashfurrow/Nimble-Snapshots", .upToNextMajor(from: "9.0.0"))
],
targets: [
.target(
name: "<Your Target Name>",
dependencies: ["Nimble-Snapshots"]),
]
)
使用方法
您的测试可能会类似于以下内容。
import Quick
import Nimble
import Nimble_Snapshots
import UIKit
class MySpec: QuickSpec {
override func spec() {
describe("in some context") {
it("has valid snapshot") {
let view = ... // some view you want to test
expect(view).to( haveValidSnapshot() )
}
}
}
}
有一些选项可以用于测试快照的有效性。快照可以指定名称。
expect(view).to( haveValidSnapshot(named: "some custom name") )
我们还提供了一种自定义命名快照的更简洁语法。
expect(view) == snapshot("some custom name")
要记录快照,只需将 haveValidSnapshot()
替换为 recordSnapshot()
,并将 haveValidSnapshot(named:)
替换为 recordSnapshot(named:)
。我们还提供了一个方便的emoji操作符。
📷(view)
📷(view, "some custom name")
默认情况下,该pod会将参考图像放在一个名为 ReferenceImages
的目录中;我们尽力将其放置在一个有意义的地点(在您的单元测试目录内)。如果我们无法找出这一点,或者如果您想使用自己的目录,请用单元测试路径中应使用的目录名调用 setNimbleTestFolder()
。例如,如果测试位于 App/AppTesting/
,您可以用 AppTesting
调用它。
如果您有任何问题或遇到任何困难,请随意在此repo上打开一个问题。
动态类型
手动测试动态类型很无聊,而且似乎没有人记得在实现视图/屏幕时进行此操作,因此您可以根据内容大小类别进行快照测试。
为了使用动态类型测试,请确保在您的测试目标中提供了有效的 Host Application
。
然后,您可以使用 haveValidDynamicTypeSnapshot
和 recordDynamicTypeSnapshot
匹配器。
// expect(view).to(recordDynamicTypeSnapshot()
expect(view).to(haveValidDynamicTypeSnapshot())
// You can also just test some sizes:
expect(view).to(haveValidDynamicTypeSnapshot(sizes: [UIContentSizeCategoryExtraLarge]))
// If you prefer the == syntax, we got you covered too:
expect(view) == dynamicTypeSnapshot()
expect(view) == dynamicTypeSnapshot(sizes: [UIContentSizeCategoryExtraLarge])
请注意,这将发布一个 UIContentSizeCategoryDidChangeNotification
,因此您的视图/视图控制器需要观察它并更新自己。
有关更多信息,请参阅动态类型测试。
动态大小
测试同一视图的多种大小很简单,但容易出错。更改测试时很容易修复一个并忘记其他所有测试。为此,我们创建了一种简单的方法来同时测试所有大小。
您可以使用新的 haveValidDynamicSizeSnapshot
和 recordDynamicSizeSnapshot
匹配器一次测试多个大小。
let sizes = ["SmallSize": CGSize(width: 44, height: 44),
"MediumSize": CGSize(width: 88, height: 88),
"LargeSize": CGSize(width: 132, height: 132)]
// expect(view).to(recordDynamicSizeSnapshot(sizes: sizes))
expect(view).to(haveValidDynamicSizeSnapshot(sizes: sizes))
// You can also just test some sizes:
expect(view).to(haveValidDynamicSizeSnapshot(sizes: sizes))
// If you prefer the == syntax, we got you covered too:
expect(view) == snapshot(sizes: sizes)
expect(view) == snapshot(sizes: sizes)
默认情况下,大小将通过frame属性设置在视图上。要更改此行为,您可以使用 ResizeMode
类别。
public enum ResizeMode {
case frame
case constrains
case block(resizeBlock: (UIView, CGSize) -> Void)
case custom(viewResizer: ViewResizer)
}
要使用枚举,可以使用expect(view) == dynamicSizeSnapshot(sizes: sizes, resizeMode: newResizeMode)
。对于自定义行为,可以使用ResizeMode.block
。在每个调整大小操作时都会调用该block。你也可以实现ViewResizer
协议来自定义调整大小。自定义行为还可以用于记录视图。
有关使用信息的更多信息,请查看动态调整大小测试。