iOS - Unit Testing
Module unit tests should live inside the Swift package for the module. The Q2DevApp should only include the minimum project wiring needed to discover and run that Swift package test target through the shared DevApp scheme.
This keeps module test code close to the module source and avoids adding each test file directly to the Q2DevApp Xcode project.
Recommended Structure
Add a Tests folder inside the module package folder, next to Sources.
q2-example-ios
├── Package.swift
├── q2-example-ios
│ ├── Sources
│ │ └── Q2Example
│ └── Tests
│ └── Q2ExampleTests
│ └── Q2ExampleTests.swift
└── Q2DevApp
├── Q2DevApp.xcworkspace
└── Q2DevApp.xctestplan
Add the Swift Package Test Target
Add a .testTarget entry in the module Package.swift file. Set the test target path
to the module package test folder.
.testTarget(
name: "Q2ExampleTests",
dependencies: [
.target(name: "Q2Example")
],
path: "q2-example-ios/Tests/Q2ExampleTests"
)
Use a test target name that clearly maps to the module, for example Q2ExampleTests.
Make the Package Available to Q2DevApp
The Q2DevApp workspace must reference the package root so Xcode can discover the Swift
package test target. From Q2DevApp/Q2DevApp.xcworkspace, the package root is the parent
folder, so the workspace entry should point to group:...
<FileRef
location = "group:..">
</FileRef>
Do not point the workspace at the nested source folder. Xcode needs the folder that
contains Package.swift.
Add the Test Target to the Q2DevApp Test Plan
Create or update Q2DevApp/Q2DevApp.xctestplan so it references the Swift package test
target.
{
"configurations": [
{
"id": "Default Configuration",
"name": "Default Configuration",
"options": {}
}
],
"defaultOptions": {},
"testTargets": [
{
"target": {
"containerPath": "container:..",
"identifier": "Q2ExampleTests",
"name": "Q2ExampleTests"
}
}
],
"version": 1
}
The shared Q2DevApp scheme should use this test plan. After that, running tests for the
Q2DevApp scheme also runs the module Swift package test target.
Run Tests Locally
Run the Q2DevApp scheme from Xcode or use xcodebuild from the module repository root.
xcodebuild test \
-workspace Q2DevApp/Q2DevApp.xcworkspace \
-scheme Q2DevApp \
-destination 'platform=iOS Simulator,name=iPhone 16' \
CODE_SIGNING_ALLOWED=NO
To collect local code coverage, enable code coverage for the same test run.
xcodebuild test \
-workspace Q2DevApp/Q2DevApp.xcworkspace \
-scheme Q2DevApp \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-enableCodeCoverage YES \
CODE_SIGNING_ALLOWED=NO
Until CI coverage is available for module repositories, include the local test command and result summary in the merge request so reviewers can verify that the module tests ran through Q2DevApp.