Android Dev peep on iOS Unit Test

As an Android Developer, if you are curious about iOS unit test and it’s setup, this would be for you. In this blog, I will show you how to import the Quick
and Nimble
test framework (a popular Behavior Driven Test for iOS) as well as the XCode provided XCTestCase
Pre-requitesite
I would not touch on open XCode and setup a basic project. You could refer to my previous blog for that.
But if you just like to know the term, but not actual hands on, just read on. Don’t worry about starting it on XCode.
Cocoapods — the Gradle of iOS
In Android Studio, we are bless to have Gradle embedded in Android Studio, so that import external libraries is made so easy.
However in XCode, life is harder. The Cocoapods doesn’t come with it.
One have to go to terminal and install the Cocoapods if it need to import libraries (which is called Pods
for iOS).
To get Cocoapods install, type the following command in terminal (obviously on Mac machine)
sudo gem install cocoapods
Import Pods (Library) to your project
To import library to your project, you’ll need to first
- Run
pod init
in the project folder to generate all the pod files. - Add the needed pods (in our case
Quick
andNimble
pods) toPodfile
target 'yourprojectTest' do
inherit! :search_paths
# Pods for testing
pod "Quick"
pod "Nimble"
end
Note: by default XCode provide us a test framework named
XCTestCase
, but I’ll be showing you also another way of testing (Behavioral Driven Test) that is commonly used by iOS developer
- Run
pod` install
to download theQuick
andNimble
pods to your project - Open the
yourproject.xcworkspace
, you’ll see theQuick
andNimble
has been added to the project

XCTestCase — JUnit like test in iOS
When you create a project in iOS, this is given to you be default.
The test class given is as below.
import XCTest
@testable import yourprojectclass yourprojectTests: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert to verify your tests produce.
} func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
This looks very familiar with JUnit, as it has setup()
and teardown()
.
For each test, just need to prefix the test
keyword on the function name, it would be a test function. If it is not prefix with test
, it would be a normal function. No annotation needed.
There’s one very interesting item there, which is self.measure
, where any code that is place under this function, will have it’s execution performance measured.
In Kotlin, you could use the following function to measure time
measureNanoTime { /**Code to measure time**/ }
To execute the test, just like Android Studio, click on the green check box on the left (on top of the line number), or use Command+u

P/S: I try to run individual test function, it always execute the entire class instead.
What is Quick & Nimble?
It’s a Swift and Objective-C Testing Framework, that is popular among iOS community, partly due to the more powerful matcher (by Nimble
) and also it support Behavior Driven Test (by Quick
).
What’s Behavior Driven Test
There’s a lot of site out there give a good description on it, but I’m going to simplify it by stating, it is basically breaking your test into 3 categories i.e.
- Given (what’s the condition)
- When (what’s the action)
- Then (what’s the expected result)
In Android JUnit Test, you could do it as below…
@Test
fun `given some condition when trigger action then expect result`() {
// Given
whenever(testMock()).thenReturn(fixedMockedValue)
// When
testClass.testTrigger()
// Then
verify(testObject).testExpectCall()
}
The iOS Way
With Quick
and Nimble
, iOS has a framework that allow one to describe the test, better using the describe
, context
and it
functions that was provided by Quick
as could be seen below.
import Foundation
import Quick
import Nimble
@testable import yourprojectclass myTestSpec: QuickSpec {
override func spec() { beforeEach { /** Code execute for every Describe **/ }
describe("Given some condition") { beforeEach { /** Code execute for every Context **/ }
context("When some action") { beforeEach { /** Code execute for every It **/ }
it("Then some expected result") {
expect(true).to(beTrue())
} } }
}
}
Several notes:
- You’ll need to have the
@testable import yourProject
to enable access to your project classes for test. - You’ll need to inherit from the
QuickSpec
protocol so that we could write thespec
function detail. - There could be more than one
describe
,context
andit
, to allow multiple test scenarios, test actions or test results triggered, yet individually is evaluated as a unit. - The
beforeEach
is to encapsulate the code that needed on it’s designated scope (i.e.describe
,context
orit
). This is similar tosetup
but more powerful as it could have a different level scope of setup.
There are several good tutorial out there on it. Below is one
With this, hopes this provide some insight of how iOS perform Unit Test. It’s always interesting to know how the other part of the world function.
I hope this post is helpful to you. You could check out my other interesting topics here.
Follow me on medium, Twitter or Facebook for little tips and learning on Android, Kotlin etc related topics. ~Elye~