Using Xcode Frameworks with macOS targets for fast test running and CI integration.
Introduction
When building software is a good idea to write tests.
For the sake of simplicity (you’ll see why later), I’m going to put unit, integration and system tests into the same tests
folder. We will leave end-to-end tests (e2e tests from now on) in a separate folder.
Warning: This post was intended for Xcode 13.4.1
The idea of this post is to show how to:
- Setup an Xcode Framework with macOS target for rapid test execution.
- Setup CircleCI to run the tests.
Xcode Framework
Create a Framework project.
Observe that My Mac (Mac Catalyst) is selected. This prevents iOS Simulator from booting every time we need to kick off our test suite. This is very important because it dramatically reduces the execution time.
Create a New Scheme
You can name it whatever you want. I choose CI
for this example.
Then, Edit
your brand new Scheme and click Add Test Target
that you want your CI to run.
You may also enable Test Execution Randomization
if you want to prevent order execution coupling.
Let’s take the CI for a spin
At this point, the setup is complete. We just need to test our run command
before deploying this to CI.
xcodebuild clean build test -scheme "CI" -sdk macosx12.3 CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
CircleCI YML Configuration File
Add the below YML configuration file inside .circleci/config.yml
in your project’s root directory and push the code to your VCS. Then configure your project in CircleCI and trigger a build.
version: 2.1
jobs:
build:
macos:
xcode: 13.4.1
steps:
- checkout
- run:
name: "Run CI Scheme"
command: xcodebuild clean build test -scheme "CI" -sdk macosx12.3 CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
Hopefully you will end up with a screen like the next one.
Conclusion
It takes a few specific steps to build a starter Framework library that can be used for any iOS, iPad, and/or macOS app and be integrated into CircleCI. This allows you and your team to start coding a project without even having to test on real devices or emulators. The best part is that this solution escalates very quickly.
Bonus Track
By the way, do you remember when I told you at the beginning that I was gonna split unit, integration and system tests into one folder and e2e into another? Watch this …
Add another testing target: MyFrameworkE2ETests
. It could be anything you want.
Now edit your CI
scheme and add the newly created target.
Final thoughts …
By now you may have realized that the CI
Scheme allows you to add multiple Targets
. In this case, you could use it to specialize your different types of tests: Unit, Integration (and System) tests on one hand and E2E tests on the other; It all depends on how you want to structure the whole project.