iOS快照测试
为iOS应用程序的用户界面编写测试非常麻烦。 由于进行基于视图的测试很困难,许多人不愿编写这些测试。 不幸的是,直到最近我还是遇到了验证我的观点的不同状态的问题。 为了实际查看结果,我需要在修改视图后多次运行该应用程序,这花费了很多时间。 因此,我试图寻求一种更有效的方式来处理这种情况,并且找到了一个完美的解决方案— FBSnapshotTestCase 。
它能做什么
快照测试用例采用已配置的UIView,并将其呈现为其内容的图像快照。 它将快照与存储在我的源代码存储库中的参考图像进行比较,如果两个图像不匹配,它将创建另一个参考图像。 通过将视图和现有快照都绘制到两个CGContextRef
,并使用C函数memcmp()
对它们进行内存比较,进行比较。 这使其非常快。
安装与设置
按照他们在GitHub页面上的说明,我将pod 'FBSnapshotTestCase'
添加到pod 'FBSnapshotTestCase'
的测试目标中。 另外,推荐的设置参考目录的方法是在我的方案中定义FB_REFERENCE_IMAGE_DIR
。 这应该指向我要存储参考图像的目录。 示例值为$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages
。
很方便吧? 让我们开始编写一些代码。
实作
为了演示如何利用FBSnapshotTestCase的优势,我创建了一个具有两种不同状态的简单视图控制器:空和正常。 一方面,当视图控制器的状态设置为空时,它应该显示一个文本标签。 另一方面,视图控制器在状态正常时应显示字符串列表。
enum State {
case empty
case normal([String])
}
让我们编写一些测试来验证它们。 首先,子类FBSnapshotTestCase而不是XCTestCase。 然后将recordMode = true
添加到setup
方法中。 它将使宏记录新的屏幕截图,而不是对照参考图像检查结果。 最后,添加以下两个测试功能,以存储我的视图控制器的图像并运行测试。
func testViewControllerEmpty() {
let vc = ViewController()
FBSnapshotVerifyView(vc.view)
}
func testViewControllerNormal() {
let vc = ViewController()
vc.state = .normal(["First", "Second", "Third"])
FBSnapshotVerifyView(vc.view)
}
完成运行后,测试应该会失败(很好。),控制台输出会告诉我已存储参考图像。 转到我在方案中设置的目录,视图控制器有两个处于不同状态的图像。
因此,我能够实际查看图像以验证视图控制器的修改,这节省了很多构建时间。 示例项目在这里。
结论
FBSnapshotTestCase还使我能够进行单个测试,并立即查看我对不同状态所做的更改。 无需点击我的应用即可获得正确的视图。 它为我提供了一种测试与视图相关的代码的方法,可用于可视化视图状态,而无需跳过模拟器或真实设备中的箍。 另一个优点是快照测试速度很快。 在应用程序的测试套件中进行很多测试是没有问题的。 如果您还没有使用过,请尝试一下。