名称:cocoapods-test-specs 用户可调用:false 描述:在使用测试规范为CocoaPods库添加自动化测试时使用。涵盖测试规范配置、应用主机需求和与pod lib lint验证集成的测试模式。 允许的工具:
- 读取
- 写入
- 编辑
- Bash
- Grep
- Glob
CocoaPods - 测试规范
将自动化测试集成到您的CocoaPods库中,这些测试在验证期间运行。
什么是测试规范?
测试规范定义测试目标,CocoaPods在pod lib lint和pod spec lint验证期间自动构建和运行。
好处
- 自动测试:测试在每次lint验证期间运行
- 信心:在发布前验证库按预期工作
- CI集成:在所有环境中一致的测试
- 文档:测试作为使用示例
基本测试规范
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
spec.version = '1.0.0'
# 主库源代码
spec.source_files = 'Source/**/*.swift'
# 测试规范
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# 测试依赖
test_spec.dependency 'Quick', '~> 7.0'
test_spec.dependency 'Nimble', '~> 12.0'
end
end
应用主机需求
没有应用主机的测试
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# 不需要应用环境的单元测试
test_spec.requires_app_host = false # 默认
end
有应用主机的测试
spec.test_spec 'UITests' do |test_spec|
test_spec.source_files = 'Tests/UITests/**/*.swift'
# 需要应用环境的测试(UIKit、故事板等)
test_spec.requires_app_host = true
test_spec.dependency 'MyLibrary'
end
多个测试规范
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
# 单元测试(无应用主机)
spec.test_spec 'UnitTests' do |unit|
unit.source_files = 'Tests/Unit/**/*.swift'
unit.dependency 'Quick'
unit.dependency 'Nimble'
end
# 集成测试(有应用主机)
spec.test_spec 'IntegrationTests' do |integration|
integration.source_files = 'Tests/Integration/**/*.swift'
integration.requires_app_host = true
integration.dependency 'MyLibrary'
end
# UI测试(有应用主机)
spec.test_spec 'UITests' do |ui|
ui.source_files = 'Tests/UI/**/*.swift'
ui.requires_app_host = true
ui.dependency 'MyLibrary'
ui.ios.frameworks = 'XCTest'
end
end
平台特定测试规范
spec.test_spec 'Tests' do |test_spec|
# 共享测试文件
test_spec.source_files = 'Tests/Shared/**/*.swift'
# iOS特定测试
test_spec.ios.source_files = 'Tests/iOS/**/*.swift'
test_spec.ios.frameworks = 'XCTest'
# macOS特定测试
test_spec.osx.source_files = 'Tests/macOS/**/*.swift'
test_spec.osx.frameworks = 'XCTest'
end
测试依赖
测试框架
spec.test_spec 'Tests' do |test_spec|
# Quick/Nimble(BDD风格)
test_spec.dependency 'Quick', '~> 7.0'
test_spec.dependency 'Nimble', '~> 12.0'
# 或传统的XCTest(无额外依赖)
test_spec.frameworks = 'XCTest'
end
模拟框架
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# Objective-C的OCMock
test_spec.dependency 'OCMock', '~> 3.9'
# Swift的Cuckoo
test_spec.dependency 'Cuckoo', '~> 2.0'
# Swift的MockingKit
test_spec.dependency 'MockingKit', '~> 1.0'
end
测试资源
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# 测试资源(JSON夹具、图像等)
test_spec.resources = 'Tests/Fixtures/**/*'
# 或测试资源包
test_spec.resource_bundles = {
'MyLibraryTests' => ['Tests/Fixtures/**/*']
}
end
方案配置
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# 方案名称(可选 - 未指定则自动生成)
test_spec.scheme = { :name => 'MyLibrary-Tests' }
# 代码覆盖率
test_spec.scheme = {
:code_coverage => true
}
end
测试子规范
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
# 核心子规范
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
# 核心子规范的测试
core.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/Core/**/*.swift'
test_spec.dependency 'Quick'
test_spec.dependency 'Nimble'
end
end
# 网络子规范
spec.subspec 'Networking' do |net|
net.source_files = 'Source/Networking/**/*.swift'
net.dependency 'MyLibrary/Core'
# 网络子规范的测试
net.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/Networking/**/*.swift'
test_spec.dependency 'OHHTTPStubs', '~> 9.0'
end
end
end
常见测试模式
XCTest模式
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
test_spec.frameworks = 'XCTest'
# 不需要额外依赖
# 测试使用import XCTest
end
Quick/Nimble模式
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
test_spec.dependency 'Quick', '~> 7.0'
test_spec.dependency 'Nimble', '~> 12.0'
# 测试使用QuickSpec和expect()
end
网络模拟模式
spec.test_spec 'NetworkTests' do |test_spec|
test_spec.source_files = 'Tests/Network/**/*.swift'
# 模拟HTTP响应
test_spec.dependency 'OHHTTPStubs', '~> 9.0'
# 或基于URLProtocol的模拟
test_spec.dependency 'Mocker', '~> 3.0'
end
快照测试模式
spec.test_spec 'SnapshotTests' do |test_spec|
test_spec.source_files = 'Tests/Snapshots/**/*.swift'
test_spec.requires_app_host = true
# 快照测试框架
test_spec.dependency 'SnapshotTesting', '~> 1.15'
# 参考图像
test_spec.resources = 'Tests/Snapshots/__Snapshots__/**/*'
end
运行测试
在Lint验证期间
# 测试自动运行
pod lib lint
# 跳过测试(更快,但不推荐)
pod lib lint --skip-tests
# 详细测试输出
pod lib lint --verbose
独立测试执行
# 在示例应用中
cd Example
pod install
xcodebuild test -workspace MyLibrary.xcworkspace -scheme MyLibrary-Tests
最佳实践
目录结构
MyLibrary/
├── MyLibrary.podspec
├── Source/
│ └── MyLibrary/
├── Tests/
│ ├── Unit/ # 单元测试
│ ├── Integration/ # 集成测试
│ ├── UI/ # UI测试
│ └── Fixtures/ # 测试数据
└── Example/
└── MyLibraryExample.xcodeproj
测试组织
# 按测试类型组织
spec.test_spec 'UnitTests' do |unit|
unit.source_files = 'Tests/Unit/**/*.swift'
unit.dependency 'Quick'
unit.dependency 'Nimble'
end
spec.test_spec 'IntegrationTests' do |integration|
integration.source_files = 'Tests/Integration/**/*.swift'
integration.requires_app_host = true
end
依赖管理
spec.test_spec 'Tests' do |test_spec|
# 仅测试依赖在这里
test_spec.dependency 'Quick'
test_spec.dependency 'Nimble'
# 主库依赖放在主规范中
# 不在测试规范中
end
反模式
不要
❌ 在验证期间跳过测试
pod lib lint --skip-tests # 违背测试规范的目的
❌ 混合测试和生产代码
spec.source_files = 'Source/**/*.swift', 'Tests/**/*.swift' # 错误
❌ 在主规范中包含测试依赖
# 在主规范中
spec.dependency 'Quick' # 应仅在test_spec中
❌ 不必要地使用requires_app_host
spec.test_spec 'Tests' do |test_spec|
# 纯单元测试不需要应用主机
test_spec.requires_app_host = true # 更慢,不必要
end
要做
✅ 每次验证期间运行测试
pod lib lint # 默认包括测试
✅ 分离测试和生产代码
spec.source_files = 'Source/**/*.swift'
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
end
✅ 将测试依赖保持在测试规范中
spec.test_spec 'Tests' do |test_spec|
test_spec.dependency 'Quick' # 仅用于测试
end
✅ 仅在需要时使用应用主机
spec.test_spec 'Tests' do |test_spec|
# 仅当测试需要UIKit、故事板等时
test_spec.requires_app_host = true
end
示例:完整的测试规范设置
Pod::Spec.new do |spec|
spec.name = 'MyAwesomeLibrary'
spec.version = '1.0.0'
spec.summary = '一个很棒的库'
spec.homepage = 'https://github.com/username/MyAwesomeLibrary'
spec.license = { :type => 'MIT', :file => 'LICENSE' }
spec.authors = { '你的名字' => 'email@example.com' }
spec.source = { :git => 'https://github.com/username/MyAwesomeLibrary.git', :tag => spec.version.to_s }
spec.ios.deployment_target = '13.0'
spec.swift_versions = ['5.7', '5.8', '5.9']
spec.source_files = 'Source/**/*.swift'
# 单元测试
spec.test_spec 'UnitTests' do |unit|
unit.source_files = 'Tests/Unit/**/*.swift'
unit.dependency 'Quick', '~> 7.0'
unit.dependency 'Nimble', '~> 12.0'
end
# 集成测试有应用主机
spec.test_spec 'IntegrationTests' do |integration|
integration.source_files = 'Tests/Integration/**/*.swift'
integration.requires_app_host = true
integration.dependency 'OHHTTPStubs', '~> 9.0'
end
end
相关技能
- cocoapods-podspec-fundamentals
- cocoapods-subspecs-organization
- cocoapods-publishing-workflow