Demo for CI/CD pipeline for iOS Native app(SwiftUI) using CircleCI.
You can see config file here.
- Use macOS large resource class(8CPU, 16GB RAM) to optimise build speed
- Use Ruby Orb to install Fastlane with cache easily.
- Fastlane is used to
- Code signing with fastlane match
- Upload to Firebase app distribution
- Fastlane is used to
- Use macOS Orb to preboot iOS Simulator for UITests.
- Use Context for storing secrets(this time token for Firebase) for across projects.
- Upload test results & visualize in Test Insights.
If you just want to run Xcode UITests(XCUITests), below fastlane is enough.
desc "Run all UITests"
lane :ui_test_all do
run_tests(
scheme: "CircleCIDemoUITests",
devices: ["iPhone 13 (15.4)"]
)
endHowever, since UITests takes time, you want to split these tests and run them in multiple macOS VMs and iOS Simulators.
Here's how to create that pipeline.
First, you have to build iOS application, including test files.
Fastlane's run_test provides build_for_testing and enables just for building the app and tests, not runnning tests.
You can specify output path in derived_data_path
desc "Run all UITests"
lane :build_for_ui_test do
run_tests(
scheme: "CircleCIDemoUITests",
devices: ["iPhone 13 (15.4)"],
derived_data_path: "dist",
build_for_testing: true
)
endThen you can upload this path to workspace.
build_for_ui_test:
macos:
xcode: 13.3.1
resource_class: macos.x86.medium.gen2
steps:
- checkout
- ruby/install-deps
- run: bundle exec fastlane build_for_ui_test
- persist_to_workspace:
root: .
paths:
- distNext step, we will split tests and run them in multiple macOS VMs and iOS Simulators
Since we alredy built the app and tests in previous step, we can download them from workspace and use.
You should specify derived_data_path and test_without_building in fastlane's run_tests.
desc "Run specific UITests"
lane :ui_test_without_building do |options|
run_tests(
scheme: "CircleCIDemoUITests",
devices: ["iPhone 13 (15.4)"],
only_testing: options[:tests],
derived_data_path: "dist",
test_without_building: true
)
endrun_tests also provides only_testing options, so you can split test files in CircleCI and pass parameters.
ui_test_parallel:
parallelism: 2
macos:
xcode: 13.3.1
resource_class: macos.x86.medium.gen2
steps:
- checkout
- macos/preboot-simulator:
device: iPhone 13
version: "15.4"
- attach_workspace:
at: .
- ruby/install-deps
- run:
name: Split tests and run UITests
command: |
CLASSNAMES=$(circleci tests glob "CircleCIDemoUITests/*.swift" \
| sed 's@/@.@g' \
| sed 's/.swift//' \
| circleci tests split --split-by=timings --timings-type=classname)
FASTLANE_ARGS=$(echo $CLASSNAMES | sed -e 's/\./\//g' -e 's/ /,/g')
bundle exec fastlane ui_test_without_building tests:$FASTLANE_ARGS
- store_test_results:
path: fastlane/test_output/report.junit