测试目标中资产目录中的 NSImage
NSImage from Asset Catalog in Test Target
我的单元测试目标需要加载图像资源以用于某些测试,但我无法加载它。
- 我在测试目标中创建了一个资产目录。
- 我已将新的 图像集 资源添加到目录,选中 "Devices" 中的 "Mac" 框,并为两种分辨率设置其源图像(@1x 和@2x):
我检查了测试目标的 "copy bundle resource" 构建阶段,它确实包含资产目录。
我检查了资产目录和图像集的目标成员,确实是测试目标。
当 运行 测试时,我尝试使用如下代码加载图像:
guard let image = NSImage(named: NSImage.Name("TestSourceImage")) else {
fatalError("Test Resource is Missing.")
}
...但是守卫失败了。
我也试过:
let bundle = Bundle(for: MyClassTests.self)
guard let path = bundle.pathForImageResource(NSImage.Name("TestSourceImage")) else {
fatalError("Test Resource is Missing.")
}
guard let image = NSImage(contentsOfFile: path) else {
fatalError("Test Resource File is Corrupt.")
}
...但第一个守卫失败(无法检索资源路径)。
两种格式我都试过了
NSImage.Name("TestSourceImage")
和:
NSImage.Name(rawValue: "TestSourceImage")
我也试过Bundle.urlForImageResource(_)
,但也失败了。
我看过类似的问题和答案,但它们适用于 iOS 或 app 中的资源(主要)捆绑。
我错过了什么?
更新:
在这期间,我解决了这个问题,方法是将我的测试图像添加为独立的图像资源(不是使用资产目录),并使用以下代码加载它:
let bundle = Bundle(for: MyClassTests.self)
guard let url = bundle.url(forResource: "TestSourceImage", withExtension: "png") else {
fatalError("!!!")
}
guard let image = NSImage(contentsOf: url) else {
fatalError("!!!")
}
在这种情况下我不需要支持多种分辨率(我的图像是图像处理算法的来源;它已经被假定为所需的最高分辨率),即使我支持,我也会我猜只是从 .png 切换到 .tiff。
问题似乎是,NSImage
没有 有一个类似于 UIImage
的 init(named:in:compatibleWith:)
的初始值设定项,它可以让你指定要从中加载图像的 bundle(第二个参数)。
您可以要求特定的包(main
除外)创建资源 URL 并从中实例化图像(就像我在上面所做的那样),但这与资产目录似乎。 欢迎提供更多信息...
Bundle 上有一个扩展,允许从资产目录加载命名图像:
extension Bundle {
@available(OSX 10.7, *)
open func image(forResource name: NSImage.Name) -> NSImage?
}
参考您的示例,您可以在 XCTestCase 中使用以下内容来访问图像 (Swift 5):
guard let image = Bundle(for: type(of: self)).image(forResource: "TestSourceImage") else {
fatalError("Test Resource is Missing.")
}
在 macOS 10.14 上测试。
我的单元测试目标需要加载图像资源以用于某些测试,但我无法加载它。
- 我在测试目标中创建了一个资产目录。
- 我已将新的 图像集 资源添加到目录,选中 "Devices" 中的 "Mac" 框,并为两种分辨率设置其源图像(@1x 和@2x):
我检查了测试目标的 "copy bundle resource" 构建阶段,它确实包含资产目录。
我检查了资产目录和图像集的目标成员,确实是测试目标。
当 运行 测试时,我尝试使用如下代码加载图像:
guard let image = NSImage(named: NSImage.Name("TestSourceImage")) else {
fatalError("Test Resource is Missing.")
}
...但是守卫失败了。
我也试过:
let bundle = Bundle(for: MyClassTests.self)
guard let path = bundle.pathForImageResource(NSImage.Name("TestSourceImage")) else {
fatalError("Test Resource is Missing.")
}
guard let image = NSImage(contentsOfFile: path) else {
fatalError("Test Resource File is Corrupt.")
}
...但第一个守卫失败(无法检索资源路径)。
两种格式我都试过了
NSImage.Name("TestSourceImage")
和:
NSImage.Name(rawValue: "TestSourceImage")
我也试过Bundle.urlForImageResource(_)
,但也失败了。
我看过类似的问题和答案,但它们适用于 iOS 或 app 中的资源(主要)捆绑。
我错过了什么?
更新:
在这期间,我解决了这个问题,方法是将我的测试图像添加为独立的图像资源(不是使用资产目录),并使用以下代码加载它:
let bundle = Bundle(for: MyClassTests.self)
guard let url = bundle.url(forResource: "TestSourceImage", withExtension: "png") else {
fatalError("!!!")
}
guard let image = NSImage(contentsOf: url) else {
fatalError("!!!")
}
在这种情况下我不需要支持多种分辨率(我的图像是图像处理算法的来源;它已经被假定为所需的最高分辨率),即使我支持,我也会我猜只是从 .png 切换到 .tiff。
问题似乎是,NSImage
没有 有一个类似于 UIImage
的 init(named:in:compatibleWith:)
的初始值设定项,它可以让你指定要从中加载图像的 bundle(第二个参数)。
您可以要求特定的包(main
除外)创建资源 URL 并从中实例化图像(就像我在上面所做的那样),但这与资产目录似乎。 欢迎提供更多信息...
Bundle 上有一个扩展,允许从资产目录加载命名图像:
extension Bundle {
@available(OSX 10.7, *)
open func image(forResource name: NSImage.Name) -> NSImage?
}
参考您的示例,您可以在 XCTestCase 中使用以下内容来访问图像 (Swift 5):
guard let image = Bundle(for: type(of: self)).image(forResource: "TestSourceImage") else {
fatalError("Test Resource is Missing.")
}
在 macOS 10.14 上测试。