Use when adding automated tests to CocoaPods libraries using test specs. Covers test spec configuration, app host requirements, and testing patterns that integrate with pod lib lint validation.
Limited to specific tools
Additional assets for this skill
This skill is limited to using the following tools:
name: cocoapods-test-specs description: Use when adding automated tests to CocoaPods libraries using test specs. Covers test spec configuration, app host requirements, and testing patterns that integrate with pod lib lint validation. allowed-tools:
Integrate automated tests into your CocoaPods library that run during validation.
Test specs define test targets that CocoaPods builds and runs automatically during pod lib lint and pod spec lint validation.
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
spec.version = '1.0.0'
# Main library source
spec.source_files = 'Source/**/*.swift'
# Test spec
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# Test dependencies
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'
# Unit tests that don't need app environment
test_spec.requires_app_host = false # Default
end
spec.test_spec 'UITests' do |test_spec|
test_spec.source_files = 'Tests/UITests/**/*.swift'
# Tests that need app environment (UIKit, storyboards, etc.)
test_spec.requires_app_host = true
test_spec.dependency 'MyLibrary'
end
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
# Unit tests (no app host)
spec.test_spec 'UnitTests' do |unit|
unit.source_files = 'Tests/Unit/**/*.swift'
unit.dependency 'Quick'
unit.dependency 'Nimble'
end
# Integration tests (with app host)
spec.test_spec 'IntegrationTests' do |integration|
integration.source_files = 'Tests/Integration/**/*.swift'
integration.requires_app_host = true
integration.dependency 'MyLibrary'
end
# UI tests (with app host)
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|
# Shared test files
test_spec.source_files = 'Tests/Shared/**/*.swift'
# iOS-specific tests
test_spec.ios.source_files = 'Tests/iOS/**/*.swift'
test_spec.ios.frameworks = 'XCTest'
# macOS-specific tests
test_spec.osx.source_files = 'Tests/macOS/**/*.swift'
test_spec.osx.frameworks = 'XCTest'
end
spec.test_spec 'Tests' do |test_spec|
# Quick/Nimble (BDD style)
test_spec.dependency 'Quick', '~> 7.0'
test_spec.dependency 'Nimble', '~> 12.0'
# Or traditional XCTest (no additional dependencies)
test_spec.frameworks = 'XCTest'
end
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# OCMock for Objective-C
test_spec.dependency 'OCMock', '~> 3.9'
# Cuckoo for Swift
test_spec.dependency 'Cuckoo', '~> 2.0'
# MockingKit for Swift
test_spec.dependency 'MockingKit', '~> 1.0'
end
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# Test resources (JSON fixtures, images, etc.)
test_spec.resources = 'Tests/Fixtures/**/*'
# Or test resource bundle
test_spec.resource_bundles = {
'MyLibraryTests' => ['Tests/Fixtures/**/*']
}
end
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
# Scheme name (optional - auto-generated if not specified)
test_spec.scheme = { :name => 'MyLibrary-Tests' }
# Code coverage
test_spec.scheme = {
:code_coverage => true
}
end
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
# Core subspec
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
# Tests for Core subspec
core.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/Core/**/*.swift'
test_spec.dependency 'Quick'
test_spec.dependency 'Nimble'
end
end
# Networking subspec
spec.subspec 'Networking' do |net|
net.source_files = 'Source/Networking/**/*.swift'
net.dependency 'MyLibrary/Core'
# Tests for Networking subspec
net.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/Networking/**/*.swift'
test_spec.dependency 'OHHTTPStubs', '~> 9.0'
end
end
end
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
test_spec.frameworks = 'XCTest'
# No additional dependencies needed
# Tests use import XCTest
end
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'
# Tests use QuickSpec and expect()
end
spec.test_spec 'NetworkTests' do |test_spec|
test_spec.source_files = 'Tests/Network/**/*.swift'
# Mock HTTP responses
test_spec.dependency 'OHHTTPStubs', '~> 9.0'
# Or URLProtocol-based mocking
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
# Snapshot testing framework
test_spec.dependency 'SnapshotTesting', '~> 1.15'
# Reference images
test_spec.resources = 'Tests/Snapshots/__Snapshots__/**/*'
end
# Tests run automatically
pod lib lint
# Skip tests (faster, but not recommended)
pod lib lint --skip-tests
# Verbose test output
pod lib lint --verbose
# In Example app
cd Example
pod install
xcodebuild test -workspace MyLibrary.xcworkspace -scheme MyLibrary-Tests
MyLibrary/
├── MyLibrary.podspec
├── Source/
│ └── MyLibrary/
├── Tests/
│ ├── Unit/ # Unit tests
│ ├── Integration/ # Integration tests
│ ├── UI/ # UI tests
│ └── Fixtures/ # Test data
└── Example/
└── MyLibraryExample.xcodeproj
# Organize by test type
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|
# Only test dependencies here
test_spec.dependency 'Quick'
test_spec.dependency 'Nimble'
# Main library dependencies go in main spec
# Not in test spec
end
❌ Skip tests during validation
pod lib lint --skip-tests # Defeats purpose of test specs
❌ Mix test and production code
spec.source_files = 'Source/**/*.swift', 'Tests/**/*.swift' # BAD
❌ Include test dependencies in main spec
# In main spec
spec.dependency 'Quick' # Should be in test_spec only
❌ Use requires_app_host unnecessarily
spec.test_spec 'Tests' do |test_spec|
# Pure unit tests don't need app host
test_spec.requires_app_host = true # Slower, unnecessary
end
✅ Run tests during every validation
pod lib lint # Includes tests by default
✅ Separate test and production code
spec.source_files = 'Source/**/*.swift'
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/**/*.swift'
end
✅ Keep test dependencies in test spec
spec.test_spec 'Tests' do |test_spec|
test_spec.dependency 'Quick' # Only for tests
end
✅ Use app host only when needed
spec.test_spec 'Tests' do |test_spec|
# Only if tests need UIKit, storyboards, etc.
test_spec.requires_app_host = true
end
Pod::Spec.new do |spec|
spec.name = 'MyAwesomeLibrary'
spec.version = '1.0.0'
spec.summary = 'An awesome library'
spec.homepage = 'https://github.com/username/MyAwesomeLibrary'
spec.license = { :type => 'MIT', :file => 'LICENSE' }
spec.authors = { 'Your Name' => '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'
# Unit tests
spec.test_spec 'UnitTests' do |unit|
unit.source_files = 'Tests/Unit/**/*.swift'
unit.dependency 'Quick', '~> 7.0'
unit.dependency 'Nimble', '~> 12.0'
end
# Integration tests with app host
spec.test_spec 'IntegrationTests' do |integration|
integration.source_files = 'Tests/Integration/**/*.swift'
integration.requires_app_host = true
integration.dependency 'OHHTTPStubs', '~> 9.0'
end
end