我试图在单元测试中使用一个资源文件,并使用Bundle.path
访问它,但它返回nil。
MyProjectTests.swift中的调用返回nil:
Bundle(for: type(of: self)).path(forResource: "TestAudio", ofType: "m4a")
这是我的项目层次结构。我还尝试将TestAudio.m4a
移动到Resources
文件夹:
├── Package.swift
├── Sources
│ └── MyProject
│ ├── ...
└── Tests
└── MyProjectTests
├── MyProjectTests.swift
└── TestAudio.m4a
以下是我的包描述:
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "MyProject",
products: [
.library(
name: "MyProject",
targets: ["MyProject"])
],
targets: [
.target(
name: "MyProject",
dependencies: []
),
.testTarget(
name: "MyProjectTests",
dependencies: ["MyProject"]
),
]
)
我使用的是Swift 4和Swift Package Manager Description API版本4。
8条答案
按热度按时间puruo6ea1#
Swift 5.3
请参阅Apple文档:"Bundling Resources with a Swift Package"
资源并不总是供包的客户端使用;资源的一种使用可以包括仅由单元测试需要的测试夹具。这样的资源不会与库代码沿着合并到包的客户端中,而只会在运行包的测试时使用。
target
和testTarget
API中添加新的resources
参数,以允许显式声明资源文件。SwiftPM使用文件系统约定来确定属于包中每个目标的源文件集:具体地说,目标的源文件是位于目标的指定“目标目录”下的那些文件。默认情况下,这是一个与目标同名的目录,位于“Sources”(对于常规目标)或“Tests”(对于测试目标)中,但可以在包清单中自定义此位置。
示例
报告的问题和可能的解决方法
Xcode
Bundle.module
是由SwiftPM生成的(参见Build/BuildPlan.swift SwiftTargetBuildDescription generateResourceAccessor()),因此在由Xcode构建时不会出现在Foundation.Bundle中。Xcode中的类似方法是:
1.手动将
Resources
引用文件夹添加到Xcode项目,1.添加Xcode构建阶段
copy
,将Resource
放入某个*.bundle
目录,1.添加一些自定义的
#ifdef XCODE_BUILD
编译器指令,以便Xcode构建使用资源。5lhxktic2#
SwiftPM(5.1)不支持原生资源yet,但是...
当单元测试运行时,可以预期存储库是可用的,因此只需使用从
#file
派生的内容加载资源。这适用于SwiftPM的所有现存版本。在测试之外的情况下,存储库在运行时不存在,仍然可以包含资源,尽管以二进制大小为代价。任何文件都可以通过将其表示为字符串字面量中的base 64数据来嵌入Swift源代码。Workspace是一个开源工具,可以自动化该过程:
$ workspace refresh resources
.(免责声明:我是作者)。tuwxkamq3#
Bundle.module在设置了正确的文件结构和依赖关系后开始为我工作。
测试目标文件结构:
Package.swift中的依赖设置:
在项目中的用法:
fjnneemd4#
Swift包管理器(SwiftPM)
可以在macOS和Linux的SwiftPM单元测试中使用资源,并提供一些额外的设置和自定义脚本。以下是对一种可能方法的描述:
TestResources/
的可行方法;和,还提供了一致的TestScratch/
目录,用于在需要时创建测试文件。*设置:
PackageName/
目录中添加测试资源目录TestResources/
。+
添加文件nano ~/bin/ swift-copy-testresources.swift
Bash别名
nano .bash_profile
*nano ~/.profile
。append结束。将/opt/swift/current更改为给定系统的Swift安装位置。*脚本:swift-copy-testresources.sh
chmod +x
测试实用代码
文件位置:
Linux
在
swift build
和swift test
期间,进程环境变量PWD
提供了一个程序包根目录…/PackageName
的路径。将PackageName/TestResources/
文件复制到$PWD/.buid/TestResources
。如果在测试运行时使用TestScratch/
目录,则在$PWD/.buid/TestScratch
中创建。macOS CLI
macOS Xcode
PackageName/TestResources/
文件作为构建阶段的一部分复制到测试包Contents/Resources
文件夹中。如果在测试过程中使用,TestScratch/
将放在*xctest
捆绑包旁边。我还在004.4'2 SW Dev Swift Package Manager (SPM) With Resources Qref上发布了一个相同方法的GitHubGist
5vf7fwbs5#
从Swift 5.3开始,由于SE-0271,您可以通过在
.target
声明中添加resources
来在Swift包管理器上添加bundle资源。示例:
如果您想了解更多,我已经写了一篇关于medium文章,讨论这个主题。我没有专门讨论
.testTarget
,但看看swift的提案,它看起来很像。a1o7rhls6#
我找到了另一个解决方案,看看this file。
可以使用路径创建一个bundle,例如:
这有点难看,但如果你想避免Makefile,它是有效的。
cigdeys37#
我正在使用:
然后调用locateFirst,它给出第一个项目。例如:
v64noz0r8#
A提出了一个简单的解决方案,适用于传统的Swift和未来的Swift:
1.在项目的根目录中添加资产
1.在Swift代码中:
ResourceHelper.projectRootURL(projectRef: #file, fileName: "temp.bundle/payload.json").path
1.在Xcode和Swift中运行,内置终端或github操作🎉https://eon.codes/blog/2020/01/04/How-to-include-assets-with-swift-package-manager/和https://github.com/eonist/ResourceHelper/