Intro to iOS Development
  • Welcome
    • ☀️Introduction
    • 🐣Getting Started
    • 🐦Course Staff
  • Logistics
    • 📜Syllabus
    • 🗓️Schedule
    • 🖊️Grading
    • 🙋‍♂️Office Hours
    • Ed Discussion
  • Assignments
    • 🍼A1: Swift Basics
    • 🧑A2: Profile
    • 💬A3: ChatDev
    • 👨‍🍳A4: ChefOS
    • 👨‍🍳A4: ChefOS - SwiftUI
    • 📱Hack Challenge
      • 🏆FA23 Winners
  • Lectures
    • 1️⃣Logistics + Swift Basics
    • 2️⃣UIKit + AutoLayout
  • 3️⃣MVC + Navigation + Delegation
  • 4️⃣UITableView
  • 5️⃣UICollectionView
  • 6️⃣Networking I
  • 7️⃣Networking II
  • 8️⃣SwiftUI I
  • 9️⃣SwiftUI II
  • 🔟Persistence + SnapKit
  • 🔔(11) Notifications
  • 🌎(12) Deployment and MapKit
  • Chapters
    • 🖐️Introduction
    • ☁️Git + GitHub
      • 1️⃣Git Installation
      • 2️⃣Git Basics
      • ➕Git+
    • 🐣Swift Basics
      • 1️⃣Variables and Constants
      • 2️⃣Data Types
      • 3️⃣Operators
      • 4️⃣Data Structures
      • 5️⃣Conditionals
      • 6️⃣Loops
      • 7️⃣Functions
      • 8️⃣Closures
      • 9️⃣Optionals
    • 🧰UIKit + AutoLayout
      • 1️⃣Classes
      • 2️⃣UIKit
      • 3️⃣AutoLayout
    • 📺MVC + Navigation + Delegation
      • 1️⃣MVC
      • 2️⃣Navigation
      • 3️⃣Delegation
    • 🏓UITableView
      • 1️⃣What is a UITableView?
      • 2️⃣UITableView Setup
    • 📚UICollectionView
      • 1️⃣What is a UICollectionView?
      • 2️⃣UICollectionView Setup
    • 🌐Networking I
      • 1️⃣HTTP Requests
      • 2️⃣Callbacks
      • 3️⃣Codable
    • 🌍Networking II
      • 1️⃣Alamofire
      • 2️⃣GET Requests
      • 3️⃣POST Requests
      • 4️⃣URLSession
    • 💾Persistence + SnapKit
      • 1️⃣Persistence
      • 2️⃣SnapKit
    • 🕊️SwiftUI
      • 1️⃣Introduction to SwiftUI
      • 2️⃣Getting Started with SwiftUI
      • 3️⃣Views + Modifiers
      • 4️⃣Layouts
      • 5️⃣Navigation
      • 6️⃣Property Wrappers
    • 🎛️Widgets
      • 1️⃣Introduction to Widgets
      • 2️⃣Setting Up Widgets
      • 3️⃣Building Widgets
      • 4️⃣Configuring Widgets
    • 🧱Project Foundation
    • ✅Testing
      • 1️⃣Unit Testing
    • 👣Debugging
      • 1️⃣OSLog
      • 2️⃣Crashlytics
      • 3️⃣Analytics
    • ☁️CI/CD
      • 1️⃣Xcode Cloud
      • 2️⃣AppStore Shipping
  • Guides
    • 🔨Xcode Project Setup
    • 🎨Figma
    • 📬Postman
    • 🥥CocoaPods
    • 🧰UIKit Handbook
    • 📑Tab Views
      • UITabBarController
      • TabView
  • Work in progress
    • 🧵Concurrency
    • 2️⃣UI Testing
    • 🕐Reactive Programming
    • 🧠Memory Management
      • 🔁ARC
    • 📦Storage
    • 📣Notifications
  • Archived
    • SP24
      • Logistics
        • 📜Syllabus
        • 🗓️Schedule
        • 🖊️Grading
        • 🙋‍♂️Office Hours
      • Assignments
        • 🍼A1: Swift Basics
        • 🧑A2: Profile
        • 💬A3: ChatDev
        • 👨‍🍳A4: ChefOS
        • 📱Hack Challenge
          • 🏆FA23 Winners
      • Lecture
        • 0️⃣Course Intro + Logistics + Git Setup
        • 1️⃣Swift Basics
        • 2️⃣UIKit + AutoLayout
        • 3️⃣MVC + Navigation + Delegation
        • 4️⃣UITableView
        • 5️⃣UICollectionView
        • 6️⃣Networking I
        • 7️⃣Networking II
        • 8️⃣Persistence + SnapKit
        • 🔟SwiftUI
        • 🔢TabViews
    • FA23
      • Logistics
        • 🐣Getting Started
        • 🐦Course Staff
        • 📜Syllabus
        • 🗓️Schedule
        • 🖊️Grading
        • 🙋‍♂️Office Hours
      • Assignments
        • 🍼A1: Swift Basics
        • 🧑A2: Profile
        • 💬A3: ChatDev
        • 👨‍🍳A4: ChefOS
        • 📱Hack Challenge
          • 🏆FA23 Winners
      • Lectures
        • 0️⃣Course Intro + Logistics
        • 1️⃣Swift Basics
        • 2️⃣UIKit + AutoLayout
        • 3️⃣MVC + Navigation + Delegation
        • 4️⃣UITableView
        • 5️⃣UICollectionView
        • 6️⃣Networking I
        • 7️⃣Networking II
        • 8️⃣Persistence + SnapKit
        • 🎛️Widgets
          • 👼Introduction to Widgets
          • ⚒️Setting Up Widgets
          • 🧱Building Widgets
          • 👨‍💻Configuring Widgets
        • 🔟SwiftUI
    • SP23
      • Logistics
        • Lecture Schedule
        • Syllabus
        • Grading
        • SP23 Office Hours
      • Chapters
        • 1. Intro to Swift & Xcode
          • Lecture Handout
          • Lecture Demo
          • 🍼Project: Swift Basics
        • 2. UIKit and AutoLayout
          • Lecture Handout
          • Lecture Demo
          • 🛒Project: UIKit + AutoLayout
        • 3. Navigation, MVC, and Delegation
          • Lecture Handout
          • Lecture Demo
          • Project: Navigation + Delegation
        • 4. UITableView
          • Lecture Handout
          • Lecture Demo
          • Project: UITableView
        • 5. UICollectionView
          • Lecture Handout
          • Lecture Demo
          • Project: UICollectionView
        • 6. Networking I
          • Lecture Handout
          • Lecture Demo
          • Project: Persistence
        • 7. Networking II
          • Lecture Handout
          • Lecture Demo
            • Message Board
          • Project: Networking II
        • 8. Swift UI
        • 9. CocoaPods
          • 🍫Lecture Handout
          • 🧑‍🍳Lecture Demo
      • Cheat Sheets
        • Setting Up a New Xcode Project
        • Submitting Your Projects
        • Setting Up CocoaPods
    • 2022
      • SwiftUI
    • 2021
      • Adding Flare
      • Project: UIView Animations (Optional - Extra Credit)
      • UIView Animations
      • Xcode Tips and Tricks
    • 2019
      • Firebase
      • Persistence: UserDefaults
  • Swift Guide (ARCHIVED)
    • About this Textbook
    • Documentation
    • Constants and Variables
      • Variable Properties
      • Lazy and Static Variables
    • Functions
    • Ranges
    • Arrays
      • Basic Array Operations
      • Iteration and Enumeration
      • Advanced Array Operations
    • Tuples
    • Conditions and While Loops
    • For Loops
    • Enums and Switches
      • Enums with Associated Values
      • Indirect Enums
    • Classes and Structs
    • Optionals
    • Dictionaries
      • Dictionary Implementation
    • Closures
    • Constraints
    • Generics
    • Protocols
      • Protocols With Associated Types
    • Casting
    • Errors
    • Networking
      • Result
    • Inout
Powered by GitBook
On this page
  • Getting Started
  • Testing File
  • Writing Test Cases
  • Running the Test Procedure
  • When to Write Unit Tests

Was this helpful?

Export as PDF
  1. Chapters
  2. Testing

Unit Testing

Spring 2024 | Vin Bui

When creating any application, it’s very important that we ensure our apps function properly and maintains that proper functionality for as long as possible. However, this can be quite difficult when working with larger codebases and more complex applications as adding new code may cause undesirable changes to our app. To maintain functionality, we often write unit tests to ensure that our code works properly after making changes to our codebase. In the iOS world, we typically write unit tests for the smallest, yet important, functions that control the logic of our app.

Getting Started

There are multiple ways to create our testing suite.

  1. If creating a brand new project, we can check the box labeled Include Tests.

  2. For an existing project, go to File > New > Target > Unit Testing Bundle. Select the project name and the target to test.

Testing File

In this chapter, we will be writing unit tests for an app called Sample. Notice that a new group gets created outside of our original project. In our case, it is called SampleTests. In this folder, we will create a new Swift file called SampleTests.swift.

In a larger, more realistic application, it’s more likely that we will have multiple screens/views. In this case, it’s common to create multiple test files, one for each screen. For example, if our Sample app contained a home page, we can have a HomeSampleTests.swift file. This keeps our codebase neat and easier to read for other developers.

Let’s analyze the code below:

import XCTest
@testable import Sample

/// Test suite for Sample.
final class SampleTests: XCTestCase {
    // Test procedures go here.
}
  1. In order to use Xcode’s testing functionality, we must import the XCTest library.

  2. We import the name of our main module, which in this case is Sample. Note that we must mark it with @testable.

  3. We create the class representing our test suite. The name of this class should match the name of our file. This class must conform to the XCTestCase protocol and is marked with final to prevent any unwanted changes to the instances of this class.

Writing Test Cases

Let’s say we wanted to test a function that counts the number of even numbers in an array. If this function is called countEvens, we can call our testing procedure testCountEvens.

func testCountEvens() {
    var result: Int
    
    // Test empty array
    result = countEvens([])
    XCTAssertEqual(result, 0)
    
    // Test array with one even number
    result = countEvens([2])
    XCTAssertEqual(result, 1)
    
    // Test array with more than one even number
    result = countEvens([2,2])
    XCTAssertEqual(result, 2)
    
    // Test array with multiple even and odd numbers
    result = countEvens([1,2,3,4,5,6,6])
    XCTAssertEqual(result, 4)
}

However, this code assumes that the Sample module that we imported has a publicly accessible function called countEvens. If this function was declared as a method inside of a class, we must first instantiate an object of that class and then call the function.

In our example, we are testing for equality so we use the XCTAssertEqual function, and pass both values as arguments.

Running the Test Procedure

There are multiple ways to run the test procedure. The most simple way is to click on the play button next to the name of the function we just created. If we want to run the entire testing suite, we can click on the play button next to the name of our testing class.

Xcode will then build our application and launch the Simulator. If our build succeeds, there will be a popup stating Build Succeeded. Note that this DOES NOT mean that our test cases have passed. If our test cases have passed, there will be a Green checkmark next to each assertion call. Otherwise, there will be a Red cross indicating a failure.

When to Write Unit Tests

The difficult part in writing unit tests is knowing when to write them. It would be OD to test every single function in our entire codebase, so it’s important that we only test functions that contain complex logic. For example, if we had a function that removes spaces from a String, that may be unnecessary because we can see that when viewing the app. However, if we had a more complex function that contains many edge cases and is difficult or impossible to view through the app, then writing unit tests can help us handle those unseen cases.

PreviousTestingNextDebugging

Last updated 1 year ago

Was this helpful?

✅
1️⃣