Snappy Shrimp - 新的快照测试体验
Snappy Shrimp - 是一个用于快照测试的库。它基于FBSnapshotTestCase库,实际上,它做的是同样的事情——它记录你视图的参考图像,并在每次启动测试时验证它。但是,要知道在所有可能的设备和所有可能的朝向上运行测试需要多长时间?这个库允许你通过减少必要的设备数量至三台——iPhone、iPhone Plus和iPad来节省时间——你将看到原因。
特性
我们改进了以下内容,以提高快照测试体验
- 以编程方式显示所有设备,包括
实际尺寸
和外观的集合
; - 我们不使用
主机应用
,这使得我们的测试运行更快; - 改进了图像命名,通过向图像名称中添加:
设备
、方向
和操作系统版本
; - 实现了
iPhone X
的安全区域和遮罩,以捕获与实际设备外观完全相同的快照; - 您可以看到您的应用在所有方向和多任务模式下在iPad上看起来如何;
iPhone, iPhone SE 和 iPhone Plus 示例
支持多任务处理的 iPad 示例
iPhone X 示例
要求
- iOS 9.0+
- Xcode 9.0+
- Swift 3.2+
安装
我们使用 Carthage 来安装我们的框架。如果您不知道如何安装 Carthage,请点击链接。
使用 Carthage
- 在您的项目中创建
Cartfile
; - 将此仓库添加到文件中
github "AndriiDoroshko/SnappyShrimp"
- 用于获取我们的库
carthage update --platform iOS
- 将两个框架添加到
构建设置/与库链接二进制文件
- 在您的测试目标中添加
运行脚本
Shell: /bin/sh
/usr/local/bin/carthage copy-frameworks
输入文件
$(SRCROOT)/Carthage/Build/iOS/FBSnapshotTestCase.framework
$(SRCROOT)/Carthage/Build/iOS/SnappyShrimp.framework
使用 Cocoapods
- 创建 Podfile
- 向其中添加以下行
pod 'SnappyShrimp'
- 使用以下命令在你的 podfile 中安装此和其他依赖
pod install
配置
- 为测试目标创建两个方案 - 第一个用于
testing
,第二个用于recording
。 - 将环境变量添加到你的测试方案中
FB_REFERENCE_IMAGE_DIR
- 参考图像文件夹 -$(SOURCE_ROOT)/Tests/ReferenceImages
例如;IMAGE_DIFF_DIR
- 失败和差异图像文件夹 -$(SOURCE_ROOT)/Tests/FailureDiffs
例如。RECORD_MODE
- 决定是否应以此模式运行测试的变量。在Record
方案中,将此值设置为TRUE
,以记录新参考。
- 如果你想在具有不同显示色域(
P3
和sRGB
)的屏幕上拥有不同的快照,应将isGamutSupportEnabled
的值设置为 true。 - 如果你想使用某种自定义的
record mode
实现,只需设置recordMode
变量。
设置方法的示例
override open func setup() {
super.setup()
recordMode = #?@!&
isGamutSupportEnabled = #?@!&
}
注意:这是我们对快照测试的实现。安装后,你可以按自己的意愿进行配置。
如何编写测试
- 添加新的 单元测试 目标;
- 创建一个新的继承自
SnapshotTest
的类; - 在类内部,创建
test...()
方法; - 创建和设置你的
ViewController
以进行测试; - 使用需要你的
controller
和一个描述设备的Presentation
对象的方法verify
;
所有设备的表示都在 Device
枚举中指定。以下是一个示例
verify(controller, for: Device.iPadPro9.portrait.oneThird)
这个方法看起来像这样
verify(controller: UIViewController,
for presentation: Presentation)
其中
controller
- 你要测试的视图控制器;presentation
- 包含有关设备的信息,包括大小、特性集合、蒙版、安全区域和名称;
要创建具有自定义特性和大小的快照,只需创建一个属于自己的 Presentation
对象。
示例
public let smallViewController = Presentation(
name: "Custom small window",
size: CGSize(width: 250, height: 375),
traitCollection: UITraitCollection(
traitsFrom: [Display.InterfaceIdiom.phone,
Display.SizeClass.Vertical.compact,
Display.SizeClass.Horizontal.compact,
Display.Scale.x2]))
快照测试示例
我们对快照测试的示例有两种方案——一种用于记录,另一种用于测试。我们选择这种方式使事情更快、更简单。
要运行我们的测试示例,我们使用Fastlane。它允许您通过简单的命令进行测试或记录
fastlane test
或
fastlane record
在Fastfile中一切都很简单。一个带有所需方案和设备的scan
动作。
lane :test do
scan(
scheme: 'SnappyShrimpTests',
devices: ['iPhone 8', 'iPhone 8 Plus', 'iPad Pro (12.9-inch)']
)
end
lane :record do
scan(
scheme: 'SnappyShrimpRecord',
devices: ['iPhone 8', 'iPhone 8 Plus', 'iPad Pro (12.9-inch)']
)
end
这是一个快照测试类的示例。您需要做的就是设置您的控制器,并调用带有您想要测试的Presentation
的verify
方法。
import SnappyShrimp
class SnappyShrimpTests: SnapshotTest {
func testExample() {
let vc = ViewController()
verify(vc, for: Device.iPhone8.landscape)
verify(vc, for: Device.iPhone8.portrait)
verify(vc, for: Device.iPhoneSE.portrait)
verify(vc, for: Device.iPhone8Plus.landscape)
verify(vc, for: Device.iPhone8Plus.portrait)
verify(vc, for: Device.iPadPro12.portrait.fullScreen)
verify(vc, for: Device.iPadPro12.portrait.oneThird)
verify(vc, for: Device.iPadPro12.portrait.twoThirds)
verify(vc, for: Device.iPhoneX.portrait)
verify(vc, for: Device.iPhoneX.landscapeLeft)
verify(vc, for: Device.iPhoneX.landscapeRight)
}
自动化示例
我们使用快照测试来验证我们的应用程序在各种情况下看起来是否与预期完全一致。但显然,没有人想在推送之前运行测试,或者只是忘记了,所以我们把这些测试运行在CI上。但如果测试在CI上失败,您就看不到那里具体发生了什么,您就必须在自己的机器上运行测试。
所以我们找到了一种方法,我们把这些图片从Travis上传到云存储,然后,如果是拉取请求,它们将被发到PR评论中,如果不是,它们会直接发到我们的Slack频道。
我们使用的物品
-
Fastlane
- 如果您还没有使用fastlane,您最好开始使用。它允许您更轻松地运行测试,并且在构建和测试方面有很多选项。 -
AWS S3
- 最好的文件存储方式,但您可以使用任何您想要的。 -
Danger
- 允许您将评论、警告和失败发布到GitHub PR。它支持Swift
和Ruby
,因此您可以编写自己的脚本,将失败的图片插入PR评论中。有了Danger,您将始终只有一个会更新的评论。如果没有失败、警告或消息,它会删除评论。
为什么你需要三个设备而不是一个
主要思路是只使用一个iOS SDK的设备进行快照测试,当控制器拥有所有需要的特有集合时,包括尺寸类别、用户习惯界面、缩放比例等。但实际上,你无法覆盖特定设备的特有集合,如缩放比例、色域、用户习惯界面等。因此,当你在一台iPad上启动针对iPhone Plus的测试时,可能会出现错误行为,因为它将使用@2的缩放比例,而不是@3,用户习惯界面也是如此。这就是为什么你需要至少三台设备。如果你想测试@1缩放比例(旧款iPad或iPhone 3GS),显然你还需要更多。
关于快照测试的特别注意事项
根据我们自身的经验,有一些事情需要你注意。
1. 测试时总是使用相同的设备。
首先,因为我们没有为具有不同色域的设备添加差异,例如SRGB和P3。所以,当你在iPhone 6 Plus和iPhone 7 Plus上运行快照测试时,你可能会遇到失败的测试,但你会有空白的差异图像,参考图像和失败的图像看起来完全相同。但机器之间确实存在差异。所以,如果你在你的文件夹中看到一个空白的差异,首先要确保你在相同的设备上运行,这个设备是你编写这些引用时使用的。
2. 布局更新后的空空白差异问题
对于前面的注释有一个解释,而对于下一个我还没有找到。在我们更改视图层次结构后,我们遇到了一些问题,即空白的差异。我们只是简单地添加了一个空白的视图,作为容器,一些测试失败了。唯一的方法就是记录新的refs。问题可能出在原始框架的问题中,或者是在iOS SDK中。没有时间研究这个问题。请随时分享你的想法。
贡献
请随意为此框架做出贡献,使其更加出色。以下是一些你应该阅读的简短清单
- 首先阅读贡献指南;
- 检查已打开的问题和要求文件,如果提到你的问题或者正在进行中;
- 提出一个新问题;
- 如果你有任何修复或改进,创建一个PR;