Wikipedia: CI is intended to be used in combination with automated unit tests written through the practices of test-driven development
Some CI tools I’ve used in production apps in the past are BuddyBuild, Travis, and Bitrise.
Today we will be taking a look and using Github Actions as our CI. I knew Github Actions existed but never got to using it until starting the iOS Lead Essentials Program.
The main benefit we’re after here is being able to push our code to Github and having our automated tests run on the server and send us an email or showing a failing badge if any of our tests fail. But our goal is to always strive for green β
Create an Xcode Framework
Create an Xcode Framework and name it DemoApp.

Ensure test and documentation are unchecked
Keep the test unchecked as we will create this explicitly next.

New Test Target
Create a new test target.


Add a Unit test class DemoAppTests to the Target.

Edit the DemoApp Scheme to add the newly added Test

Adding a System to be tested
In this demo we will create a file called ArrayProblems.swift and add a method called mergeArrays(). This will be the system under test, or the SUT.
public final class ArrayProblems {
public init() {}
public func mergeArrays(_ arr1: [Int], arr2: [Int]) -> [Int] {
if arr1.isEmpty && arr2.isEmpty { return [] }
var result = [Int]()
var leftIndex = 0
var rightIndex = 0
while leftIndex < arr1.count && rightIndex < arr2.count {
let leftElement = arr1[leftIndex]
let rightElement = arr2[rightIndex]
if leftElement < rightElement {
result.append(leftElement)
leftIndex += 1
} else if leftElement > rightElement {
result.append(rightElement)
rightIndex += 1
} else {
result.append(leftElement)
leftIndex += 1
result.append(rightElement)
rightIndex += 1
}
}
if leftIndex < arr1.count {
result.append(contentsOf: arr1[leftIndex...])
}
if rightIndex < arr2.count {
result.append(contentsOf: arr2[rightIndex...])
}
return result
}
}
Unit Tests
From the target, we created earlier create the following tests in the DemoAppTests.swift class:
import XCTest
import DemoApp
class DemoAppTests: XCTestCase {
func test_mergeArrays_bothArraysAreEmpty() {
let array1 = [Int]()
let array2 = [Int]()
let sut = ArrayProblems()
let resultsArray = sut.mergeArrays(array1, arr2: array2)
XCTAssertEqual(resultsArray, [])
}
func test_mergeArrays_bothArraysHaveValues() {
let array1 = [1, 3, 4, 5]
let array2 = [2, 4, 6, 8]
let mergedArray = [1, 2, 3, 4, 4, 5, 6, 8]
let sut = ArrayProblems()
let receivedArray = sut.mergeArrays(array1, arr2: array2)
XCTAssertEqual(mergedArray, receivedArray)
}
}
Run all tests (command + U), and ensure all tests are passing β . At this point push all your code to Github and we will move on to the heart of this article – adding Github Actions for continuous integration.
Adding Github Actions as our CI
Navigate to your Github repository and select Actions in the top menu as seen below. You should now be seeing a screen similar to screenshot. Actions does a great job of recognizing your file types and provides workflow suggestions. Here we see, Swift, Xcode…iOS.

Select the Configure option under the Swift workflow. You should now be viewing a YAML file similar to below:
name: Swift
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v
We will be editing this file as seen in this iOS Essentials video to suit our particular Xcode build and testing needs.
Verify the following build and test command in a Terminal window prior to adding it to the YAML file below. Navigate to your project in Terminal and run this command, ensure your Project name is edited as needed if it’s different from the naming below:
xcodebuild clean build test -project DemoApp/DemoApp.xcodeproj -scheme "DemoApp" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
If all tests succeeded from the command above, then we are good to continue with editing and committing the YAML file below on Github.
View and edit the YAML file below as per your project.
name: Github Action Demo CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Select Xcode
run: sudo xcode-select -switch /Applications/Xcode_13.2.1.app
- name: Build and Test
run: xcodebuild clean build test -project DemoApp/DemoApp.xcodeproj -scheme "DemoApp" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
Once you are done editing the YAML file above commit. At this time Github will run the newly configured workflow. Click on Actions in the top menu to observe the workflow running all of the configured steps from the YAML file.

A final touch is adding a status badge to the repo’s README.
Navigate to Actions, select the workflow e.g Github Actions Demo CI, and the “…” menu button as seen below.

Select Create status badge and copy the status badge Markdown. Paste this Markdown to your README and you should now have a badge present on your page.

You can now enjoy pushing and testing more Data Structures and Algorithms to your repo if you so choose ππΎ. Hope you enjoyed this tutorial on using Github Actions. Feel free to leave any comments or feedback. Happy coding!