UI Tests中如何向模拟器Camera roll添加测试图片?
如何编程将测试图片导入iOS模拟器Camera Roll用于自动化测试
针对你的CoreML应用测试需求,有两种高效的方案可以实现自动化导入测试图片,完全无需手动操作:
方案1:在XCTest代码中直接导入(适合单元/UI测试内嵌)
这种方法让测试代码自行完成图片导入,完全集成在测试流程里,其他人运行测试时一键就能搞定所有准备工作。
步骤:
- 配置测试target权限:在测试target的
Info.plist中添加NSPhotoLibraryAddUsageDescription键,值填类似"需要访问相册以导入测试图片"的描述,避免权限弹窗阻塞测试流程。 - 将测试图片加入测试bundle:把你的测试图片拖到Xcode的测试target中,勾选"Copy items if needed",并确保图片出现在
Build Phases > Copy Bundle Resources列表里。 - 编写测试代码:用Photos框架的API完成图片导入,示例代码如下:
import XCTest import Photos class CoreMLImageTests: XCTestCase { private let testImageName = "sample_test_image" private let testImageExtension = "jpg" override func setUpWithError() throws { // 可选:每次测试前清理相册(避免重复导入堆积) try clearTestImagesFromCameraRoll() } func testImportTestImageToCameraRoll() { // 1. 请求相册添加权限 let authExpectation = expectation(description: "Photo library authorization") PHPhotoLibrary.requestAuthorization { status in XCTAssertEqual(status, .authorized, "必须授予相册访问权限才能导入测试图片") authExpectation.fulfill() } waitForExpectations(timeout: 5) // 2. 获取测试bundle中的图片URL guard let imageURL = Bundle(for: type(of: self)) .url(forResource: testImageName, withExtension: testImageExtension) else { XCTFail("测试图片未在测试bundle中找到,请检查文件引用") return } // 3. 导入图片到Camera Roll let importExpectation = expectation(description: "Image import completion") PHPhotoLibrary.shared().performChanges({ let creationRequest = PHAssetCreationRequest.forAsset() creationRequest.addResource(with: .photo, fileURL: imageURL, options: nil) }) { success, error in if let error = error { XCTFail("图片导入失败:\(error.localizedDescription)") } else { XCTAssertTrue(success, "测试图片成功导入Camera Roll") } importExpectation.fulfill() } waitForExpectations(timeout: 10) } // 辅助方法:清理测试图片(可选) private func clearTestImagesFromCameraRoll() throws { let fetchOptions = PHFetchOptions() fetchOptions.predicate = NSPredicate(format: "filename == %@", "\(testImageName).\(testImageExtension)") let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions) guard assets.count > 0 else { return } let deleteExpectation = expectation(description: "Delete test images") PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.deleteAssets(assets as NSFastEnumeration) }) { success, error in if let error = error { XCTFail("清理测试图片失败:\(error.localizedDescription)") } deleteExpectation.fulfill() } waitForExpectations(timeout: 5) } }
方案2:用simctl命令行提前导入(适合CI/测试前准备)
如果希望在测试运行前就把图片导入模拟器,可以用Xcode自带的simctl工具,把命令加到测试的前置操作中,这样每次运行测试时会自动执行准备工作。
步骤:
- 确认测试图片路径:比如你的测试图片放在项目根目录的
TestImages文件夹下,路径为${PROJECT_DIR}/TestImages/sample_test_image.jpg。 - 添加前置操作:
- 打开Xcode,点击顶部菜单栏的
Product > Scheme > Edit Scheme - 选择
Test选项卡,切换到Pre-actions标签 - 点击"+"按钮,选择
New Run Script Action - 在脚本框中输入以下命令:
# 获取当前启动的模拟器UDID SIMULATOR_UDID=$(xcrun simctl list devices booted | grep -Eo '[0-9A-F-]{36}') if [ -z "$SIMULATOR_UDID" ]; then echo "No booted simulator found" exit 1 fi # 授予应用相册权限(替换成你的应用Bundle ID) xcrun simctl privacy $SIMULATOR_UDID grant photos com.yourcompany.yourapp # 导入测试图片到Camera Roll xcrun simctl addmedia $SIMULATOR_UDID "${PROJECT_DIR}/TestImages/sample_test_image.jpg"
- 打开Xcode,点击顶部菜单栏的
- 保存Scheme:这样每次点击"Run Test"时,会先执行这个脚本,自动完成权限授权和图片导入。
注意事项:
- 确保
simctl命令能正确找到模拟器,如果你需要指定特定模拟器,可以把SIMULATOR_UDID替换成固定的模拟器ID。 - 命令中的应用Bundle ID要和你CoreML应用的Bundle ID完全一致。
内容的提问来源于stack exchange,提问作者Mailo Světel
相关产品推荐
相关产品推荐

