Swift Testing: Getting Began | Kodeco

Swift Testing: Getting Began | Kodeco


In 2021, Apple launched Swift concurrency to an adoring viewers; lastly, builders might write Swift code to implement concurrency in Swift apps! At WWDC 2024, builders acquired one other recreation changer: Swift Testing. It’s so a lot enjoyable to make use of, you’ll be leaping off the bed each morning, keen to put in writing extra unit exams for all of your apps! No extra gritting your tooth over XCTAssert-this-and-that. You get to put in writing in Swift, utilizing Swift concurrency, no much less. Swift Testing is a factor of magnificence, and Apple’s testing workforce is rightfully pleased with its achievement. You’ll be capable to write exams sooner and with higher management, your exams will run on Linux and Home windows, and Swift Testing is open supply, so you may also help to make it even higher.

Swift Testing vs. XCTest

Right here’s a fast record of variations:

  • You mark a operate with @Check as a substitute of beginning its identify with take a look at.
  • Check capabilities might be occasion strategies, static strategies, or international capabilities.
  • Swift Testing has a number of traits you need to use so as to add descriptive details about a take a look at, customise when or whether or not a take a look at runs, or modify how a take a look at behaves.
  • Exams run in parallel utilizing Swift concurrency, together with on units.
  • You utilize #anticipate(...) or attempt #require(...) as a substitute of XCTAssertTrue, ...False, ...Nil, ...NotNil, ...Equal, ...NotEqual, ...Similar, ...NotIdentical, ...GreaterThan, ...LessThanOrEqual, ...GreaterThanOrEqual or ...LessThan.

Preserve studying to see extra particulars.

Getting Began

Observe: You want Xcode 16 beta to make use of Swift Testing.

Click on the Obtain Supplies button on the high or backside of this text to obtain the starter initiatives. There are two initiatives so that you can work with:

Migrating to Swift Testing

To start out, open the BullsEye app in Xcode 16 beta and find BullsEyeTests within the Check navigator.

Test Navigator Screen

These exams verify that BullsEyeGame computes the rating accurately when the person’s guess is larger or decrease than the goal.

First, remark out the final take a look at testScoreIsComputedPerformance(). Swift Testing doesn’t (but) help UI efficiency testing APIs like XCTMetric or automation APIs like XCUIApplication.

Return to the highest and change import XCTest with:

import Testing

Then, change class BullsEyeTests: XCTestCase { with:

struct BullsEyeTests {

In Swift Testing, you need to use a struct, actor, or class. As normal in Swift, struct is inspired as a result of it makes use of worth semantics and avoids bugs from unintentional state sharing. In the event you should carry out logic after every take a look at, you may embody a de-initializer. However this requires the kind to be an actor or class — it’s the commonest cause to make use of a reference sort as a substitute of a struct.

Subsequent, change setUpWithError() with an init methodology:

init() {
  sut = BullsEyeGame()
}

This allows you to take away the implicit unwrapping from the sut declaration above:

var sut: BullsEyeGame

Remark out tearDownWithError().

Subsequent, change func testScoreIsComputedWhenGuessIsHigherThanTarget() { with:

@Check func scoreIsComputedWhenGuessIsHigherThanTarget() {

and change the XCTAssertEqual line with:

#anticipate(sut.scoreRound == 95)

Equally, replace the second take a look at operate to:

@Check func scoreIsComputedWhenGuessIsLowerThanTarget() {
  // 1. given
  let guess = sut.targetValue - 5

  // 2. when
  sut.verify(guess: guess)

  // 3. then
  #anticipate(sut.scoreRound == 95)
}

Then, run BullsEyeTests within the normal method: Click on the diamond subsequent to BullsEyeTests within the Check navigator or subsequent to struct BullsEyeTests within the editor. The app builds and runs within the simulator, after which the exams full with success:

Completed Tests

Now, see how simple it’s to alter the anticipated situation: In both take a look at operate, change == to !=:

#anticipate(sut.scoreRound != 95)

To see the failure message, run this take a look at after which click on the pink X:

Failure Message

And click on the Present button:

Failure Message

It exhibits you the worth of sut.scoreRound.

Undo the change again to ==.

Discover the opposite take a look at teams are nonetheless there, and so they’re all XCTests. You didn’t should create a brand new goal to put in writing Swift Testing exams, so you may migrate your exams incrementally. However don’t name XCTest assertion capabilities from Swift Testing exams or use the #anticipate macro in XCTests.

Including Swift Testing

Shut BullsEye and open TheMet. This app has no testing goal, so add one:

Choosing a Template for the Target

Testing System defaults to Swift Testing:

Swift Testing is the Default Option.

Now, take a look at your new goal’s Common/Deployment Information:

Target Information

Not surprisingly, it’s iOS 18.0. However TheMet’s deployment is iOS 17.4. You may change one or the opposite, however they should match. I’ve modified TheMet’s deployment to iOS 18.

Open TheMetTests within the Check navigator to see what you bought:

import Testing

struct TheMetTests {

    @Check func testExample() async throws {
        // Write your take a look at right here and use APIs like `#anticipate(...)` to verify anticipated situations.
    }

}

You’ll want the app’s module, so import that:

@testable import TheMet

You’ll be testing TheMetStore, the place all of the logic is, so declare it and initialize it:

var sut: TheMetStore

init() async throws {
  sut = TheMetStore()
}

Press Shift-Command-O, sort the, then Choice-click TheMetStore.swift to open it in an assistant editor. It has a fetchObjects(for:) methodology that downloads at most maxIndex objects. The app begins with the question “rhino”, which fetches three objects. Substitute testExample() with a take a look at to verify that this occurs:

@Check func rhinoQuery() async throws {
  attempt await sut.fetchObjects(for: "rhino")
  #anticipate(sut.objects.depend == 3)
}

Run this take a look at … success!

Successful Test

Write one other take a look at:

@Check func catQuery() async throws {
  attempt await sut.fetchObjects(for: "cat")
  #anticipate(sut.objects.depend <= sut.maxIndex)
}

Parameterized Testing

Once more, it succeeds! These two exams are very related. Suppose you need to take a look at different question phrases. You might preserve doing copy-paste-edit, however among the finest options of Swift Testing is parameterized exams. Remark out or change your two exams with this:

@Check("Variety of objects fetched", arguments: [
        "rhino",
        "cat",
        "peony",
        "ocean",
    ])
func objectsCount(question: String) async throws {
  attempt await sut.fetchObjects(for: question)
  #anticipate(sut.objects.depend <= sut.maxIndex)
}

And run the take a look at:

the Test Navigator Shows Each Label and Argument Tested.

The label and every of the arguments seem within the Check navigator. The 4 exams ran in parallel, utilizing Swift concurrency. Every take a look at used its personal copy of sut. If one of many exams had failed, it would not cease any of the others, and also you’d be capable to see which of them failed, then rerun solely these to search out the issue.

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 
rooshohttps://www.roosho.com
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here


Latest Articles

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog.