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还使我能够进行单个测试,并立即查看我对不同状态所做的更改。 无需点击我的应用即可获得正确的视图。 它为我提供了一种测试与视图相关的代码的方法,可用于可视化视图状态,而无需跳过模拟器或真实设备中的箍。 另一个优点是快照测试速度很快。 在应用程序的测试套件中进行很多测试是没有问题的。 如果您还没有使用过,请尝试一下。