Swift Snapshot Testing图片处理优化:两大管理难题咨询
解决方案
1. 基准与失败图片统一管理
Swift-Snapshot-Testing默认将失败快照存放在DerivedData目录,对比时需要跨目录查找,效率很低。你可以通过以下两种方式优化:
自定义统一存储路径
调用assertSnapshot时,通过fileUrl参数指定基准图和失败图的共同存储目录,失败时生成的对比图会直接放在基准图同目录下(带_failed后缀):
func testExampleSnapshot() { let view = CustomView(viewModel: .fixture()).background(Color.white) let controller = UIHostingController(rootView: view) controller.view.backgroundColor = .systemYellow // 创建与测试文件同层级的Snapshots目录 let snapshotDir = URL(fileURLWithPath: #file) .deletingLastPathComponent() .appendingPathComponent("Snapshots") try? FileManager.default.createDirectory(at: snapshotDir, withIntermediateDirectories: true) let targetFileUrl = snapshotDir.appendingPathComponent("\(#function).png") SnapshotTesting.diffTool = "ksdiff" assertSnapshot( matching: controller, as: .image, fileUrl: targetFileUrl ) }
这样无需切换目录,就能直接在同一文件夹下对比基准图和失败图。
用环境变量控制录制状态
不用手动修改isRecording的值,通过Scheme添加环境变量来切换录制/测试模式:
- 打开Xcode的Scheme编辑界面,切换到
Test阶段 - 添加环境变量
SNAPSHOT_RECORD,值设为true - 需要录制基准图时勾选该变量,正常测试时取消勾选
然后在测试类中读取环境变量控制录制:
override func setUp() { super.setUp() isRecording = ProcessInfo.processInfo.environment["SNAPSHOT_RECORD"] == "true" }
全程无需修改代码,同时保证失败图和基准图路径统一,对比更高效。
2. 规范快照图片组织方式
默认按测试文件分目录会导致结构零散,你可以通过以下方式优化:
按测试类/功能模块划分目录
在测试类中统一配置快照目录,将同一类或模块的快照归到同一路径下:
class CustomViewSnapshotTests: XCTestCase { // 为当前测试类创建独立的快照目录 private let snapshotDir = URL(fileURLWithPath: #file) .deletingLastPathComponent() .appendingPathComponent("Snapshots/CustomView") override func setUp() { super.setUp() try? FileManager.default.createDirectory(at: snapshotDir, withIntermediateDirectories: true) isRecording = ProcessInfo.processInfo.environment["SNAPSHOT_RECORD"] == "true" } func testCustomView_DefaultState() { let view = CustomView(viewModel: .fixture()).background(Color.white) let controller = UIHostingController(rootView: view) assertSnapshot( matching: controller, as: .image, fileUrl: snapshotDir.appendingPathComponent("\(#function).png") ) } func testCustomView_ErrorState() { let view = CustomView(viewModel: .fixture(error: true)).background(Color.white) let controller = UIHostingController(rootView: view) assertSnapshot( matching: controller, as: .image, fileUrl: snapshotDir.appendingPathComponent("\(#function).png") ) } }
这样所有CustomView相关的快照都会集中存放在Snapshots/CustomView目录下,结构清晰易维护。
全局配置默认快照目录
如果想统一所有快照的存储规则,可以在测试入口全局设置defaultSnapshotDirectory:
extension XCTestCase { override open class func setUp() { super.setUp() SnapshotTesting.defaultSnapshotDirectory = { let testBundle = Bundle(for: self) return testBundle.resourceURL? .appendingPathComponent("Snapshots") .path ?? "" }() } }
再结合name参数按模块/类命名快照文件,就能实现全局统一的组织规范。
Xcode目录分组优化
在Xcode中,将Snapshots目录以文件夹引用的方式加入项目,然后按模块/类创建子文件夹,这样在项目导航栏中就能直观看到分组后的快照,方便快速查找。
内容的提问来源于stack exchange,提问作者R.Davis
相关产品推荐
相关产品推荐

