avatarSwiftos

Summary

The provided content serves as a cheat sheet for unit testing assertions in Swift using the XCTest framework, detailing various assertion functions and their use cases for developers.

Abstract

The article "Week 1: Unit Testing Assertions Cheat Sheet in Swift" is a comprehensive guide aimed at Swift developers who utilize the XCTest framework for unit testing. It introduces a range of assertion functions, such as XCTAssert, XCTAssertTrue, XCTAssertFalse, XCTAssertNil, XCTAssertNotNil, XCTAssertEqual, XCTAssertNotEqual, XCTAssertLessThan, XCTAssertGreaterThan, XCTAssertLessThanOrEqual, XCTAssertGreaterThanOrEqual, XCTAssertNoThrow, and XCTAssertThrowsError, explaining the conditions under which each assertion generates success or failure. The article also demonstrates practical examples of how to implement these assertions in test cases, including handling floating-point comparisons and error throwing scenarios. Additionally, it touches on customizing error messages with the optional message argument to provide more descriptive feedback when an assertion fails.

Week 1: Unit Testing Assertions Cheat Sheet in Swift

Photo by Dominik Vanyi on Unsplash

Building apps is hard, and it’s even harder to debug. Since Xcode 5.0, Apple introduced the XCTest framework, which allows developers to build test automation for apps. Unit Testing automates the testing process, catches errors before the apps run, and saves developers a lot of time. In this story, let’s talk about all the assertions that are available for writing Unit Tests.

XCTAssert(expression: Bool)

This function generates success when the expression is true.

func testAssertion() {
    let number = 2
    XCTAssert(number > 1) // success
    XCTAssert(number == 1) // failure
}

XCTAssertTrue(expression: Bool)

This function is very similar to the XCTAssert(expression: Bool), it generates success when the expression is true.

func testAssertion() {
    let number = 2
    XCTAssertTrue(number > 1) // success
    XCTAssertTrue(number == 1) // failure
}

XCTAssertFalse(expression: Bool)

This function is the opposite of the XCTAssertTrue(expression: Bool) , it generates failure when the expression is true.

func testAssertion() {
    let number = 2
    XCTAssertFalse(number > 1) // failure
    XCTAssertFalse(number == 1) // success
}

XCTAssertNil(expression: Any?)

This function generates success when the expression is nil .

func testAssertion() { 
    let name: String? = nil
    let number = 2
    XCTAssertNil(name) // success
    XCTAssertNil(number) // failure
}

XCTAssertNotNil(expression: Any?)

This function is the opposite of the XCTAssertNil(expression: Any?) , it generates failure when the expression is nil.

func testAssertion() { 
    let name: String? = nil
    let number = 2
    XCTAssertNotNil(name) // failure
    XCTAssertNotNil(number) // success
}

XCTAssertEqual(expression1: Equatable, expression2: Equatable)

This function generates success when the both expressions are equal.

func testAssertion() {
    let number = 2
    XCTAssertEqual(number, 2) // success
    XCTAssertEqual(number, 1) // failure
}

XCTAssertNotEqual(expression1: Equatable, expression2: Equatable)

This function is the opposite of the XCTAssertEqual(expression1: Equatable, expression2: Equatable), it generates success when the both expressions are NOT equal.

func testAssertion() {
    let number = 2
    XCTAssertNotEqual(number, 1) // success
    XCTAssertNotEqual(number, 2) // failure
}

XCTAssertEqual(expression1: FloatingPoint, expression2: FloatingPoint, accuracy: FloatingPoint)

This function is similar to XCTAssertEqual(expression1: Equatable, expression2: Equatable) , but it compares two FloatingPoints with an accuracy.

func testAssertion() {
    let number = 2
    XCTAssertEqual(0.01, 0.02, accuracy: 0.01) // success
    XCTAssertEqual(0.01, 0.02, accuracy: 0.001) // failure
}

XCTAssertNotEqual(expression1: FloatingPoint, expression2: FloatingPoint, accuracy: FloatingPoint)

This function is the opposite of XCTAssertEqual(expression1: FloatingPoint, expression2: FloatingPoint, accuracy: FloatingPoint) , it compares two FloatingPoints with an accuracy. But it generates success when they are NOT equal.

func testAssertion() {
    let number = 2
    XCTAssertNotEqual(0.01, 0.02, accuracy: 0.001) // success
    XCTAssertNotEqual(0.01, 0.02, accuracy: 0.01) // failure
}

XCTAssertLessThan(expression1: Comparable, expression2: Comparable)

This function generates success when the expression1 is less than the expression2.

func testAssertion() {
    let number = 2
    XCTAssertLessThan(number, 3) // success
    XCTAssertLessThan(number, 1) // failure
}

XCTAssertGreaterThan(expression1: Comparable, expression2: Comparable)

This function is the opposite of XCTAssertLessThan(expression1: Comparable, expression2: Comparable) , it generates success when the expression1 is greater than the expression2.

func testAssertion() {
    let number = 2
    XCTAssertGreaterThan(number, 1) // success
    XCTAssertGreaterThan(number, 3) // failure
}

XCTAssertLessThanOrEqual(expression1: Comparable, expression2: Comparable)

This function generates success when the expression1 is less than or equal to the expression2.

func testAssertion() {
    let number = 2
    XCTAssertLessThan(number, 3) // success
    XCTAssertLessThan(number, 2) // success
    XCTAssertLessThan(number, 1) // failure
}

XCTAssertGreaterThanOrEqual(expression1: Comparable, expression2: Comparable)

This function is the opposite of XCTAssertLessThan(expression1: Comparable, expression2: Comparable) , it generates success when the expression1 is greater than or equal to the expression2.

func testAssertion() {
    let number = 2
    XCTAssertGreaterThanOrEqual(number, 1) // success
    XCTAssertGreaterThanOrEqual(number, 2) // success
    XCTAssertGreaterThanOrEqual(number, 3) // failure
}

XCTAssertNoThrow(expression: T)

This function generates success if the expression doesn't throw errors.

struct User: Decodable {
    let firstname: String
    let lastname: String
    let age: Int
}
func testAssertion() {
    let JSONOne = """
    {
        "firstname": "Dylan",
        "lastname": "Chen",
        "age": 28
    }
    """
    let JSONTwo = """
    {
        "firstname": "Dylan",
        "lastname": "Chen",
        "age": "28"
    }
    """
    let jsonDataOne = JSONOne.data(using: .utf8)!
    let jsonDataTwo = JSONTwo.data(using: .utf8)!   
 
    XCTAssertNoThrow(try JSONDecoder().decode(User.self, from: jsonDataOne)) // Success
    XCTAssertNoThrow(try JSONDecoder().decode(User.self, from: jsonDataTwo)) // Failure, because "age" is supposed to be an integer.
}

XCTAssertThrowsError(expression: T)

This function is the opposite of the XCTAssertNoThrow(expression: T) , it generates success when the expression throws errors.

struct User: Decodable {
    let firstname: String
    let lastname: String
    let age: Int
}
func testAssertion() {
    let JSONOne = """
    {
        "firstname": "Dylan",
        "lastname": "Chen",
        "age": 28
    }
    """
    let JSONTwo = """
    {
        "firstname": "Dylan",
        "lastname": "Chen",
        "age": "28"
    }
    """
    let jsonDataOne = JSONOne.data(using: .utf8)!
    let jsonDataTwo = JSONTwo.data(using: .utf8)!   
 
    XCTAssertNoThrow(try JSONDecoder().decode(User.self, from: jsonDataOne)) // Failure
    XCTAssertNoThrow(try JSONDecoder().decode(User.self, from: jsonDataTwo)) // Success because "age" is supposed to be an integer.
}

XCTAssertThrowsError(expression: T, message: String, errorHandler: (Error) -> Void)

This function is similar to XCTAssertThrowsError(expression: T) , in addition, the errorHandler allows us to catch the error and perform additional testing.

struct User: Decodable {
    let firstname: String
    let lastname: String
    let age: Int
}
func testAssertion() {
    let JSON = """
    {
        "firstname": "Dylan",
        "lastname": "Chen",
        "age": "28"
    }
    """
    let jsonData = JSON.data(using: .utf8)!  
 
    XCTAssertThrowsError(try JSONDecoder().decode(User.self, from: jsonData), "") { (error) in
        print(error.localizedDescription) // The data couldn’t be read because it isn’t in the correct format.
    } // failure
}

All these assertion functions accept an optional argument message that customs the error description. For example,

XCTAssert(expression: Bool, message: String)

func testAssertion() {
    let number = 2
    XCTAssert(number == 1, "Number does NOT equal to 1 :)") 
    // failure, description: "Number does NOT equal to 1 :)"
XCTAssert(number == 1) 
    // failure, description: "Test Case failed"
}
Medium Claps — Made in Flinto by Thuy Gia Nguyen on Dribbble

Please clap if you enjoyed this article. Follow me. I’ll see you in subsequent articles :)

You may also be interested in:

iOS App Development
iOS Development
iOS
Swift Programming
Swift
Recommended from ReadMedium