Swift Academy · Oppitunti

Async-koodin testaaminen (XCTest)

Kirjoittakaa async tests -testejä XCTestillä: merkitkää testit async -määritteellä, käyttäkää await - ja throws -määritteitä, testatkaa virheet ja aikakatkaisut sekä tarkistakaa rakenteisen rinnakkaisuuden tulokset.

Oppitunti 3/38 vaihetta

Async-koodin testaaminen (XCTest) on ilmainen Swift Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/3. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Swift Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Swift Academy-kurssilla on yhteensä 3 oppituntia.

Async-testit: perusteet

XCTest tukee async-testejä. Pitäkää testit pieninä ja deterministisinä:

  • Määritelkää async-testejä ja käyttäkää await-sanaa
  • Käyttäkää throws-määrettä ja do/catch-rakennetta virheisiin
  • Korvatkaa sleep-kutsut pienillä fake-objekteilla tai stub-objekteilla

Async-testin onnistumistapaus

Merkitkää testi async-testiksi ja kutsukaa SUT:ia await-sanalla. Kirjoittakaa tavallisia tarkistuksia, kuten XCTAssertEqual.

import XCTest
import Foundation

// System Under Test (SUT)
func fetchValue() async -> Int {
    try? await Task.sleep(nanoseconds: 50_000_000)
    return 42
}

final class AsyncBasicsTests: XCTestCase {
    func testFetchValue_returns42() async {
        let v = await fetchValue()
        XCTAssertEqual(v, 42)
    }
}

Async throws ja tarkistukset

Käyttäkää async throws -testejä. Pyydystäkää tietyt virheet ja tehkää niille pattern matching, jotta testin tarkoitus pysyy selkeänä.

import XCTest

enum NetError: Error { case offline }

func loadNumber(online: Bool) async throws -> Int {
    try await Task.sleep(nanoseconds: 30_000_000)
    if !online { throw NetError.offline }
    return 7
}

final class AsyncThrowingTests: XCTestCase {
    func testLoadNumber_success() async throws {
        let n = try await loadNumber(online: true)
        XCTAssertEqual(n, 7)
    }

    func testLoadNumber_offline_throws() async {
        do {
            _ = try await loadNumber(online: false)
            XCTFail("Expected error")
        } catch NetError.offline {
            // expected
        } catch {
            XCTFail("Unexpected error: \\(error)")
        }
    }
}

Rinnakkaiset tulokset

Strukturoitua samanaikaisuutta on helppo testata: käyttäkää async let -määrettä ja tarkistakaa lopullinen tulos. Pitäkää viiveet hyvin lyhyinä, jotta testit eivät muutu epävakaiksi.

import XCTest

func compute(_ x: Int) async -> Int {
    try? await Task.sleep(nanoseconds: 10_000_000)
    return x * x
}

final class ParallelTests: XCTestCase {
    func testParallel_asyncLet_sumsSquares() async {
        async let a = compute(2)
        async let b = compute(3)
        let sum = await (a + b)
        XCTAssertEqual(sum, 13) // 4 + 9
    }
}

Aikakatkaisujen testaaminen

Testatkaa aikakatkaisuja kilpailuttamalla operaatio lyhyen sleepin kanssa. Käyttäkää hyvin pieniä kestoja, jotta testit pysyvät nopeina ja vakaina.

import XCTest

enum TimeoutError: Error { case timedOut }

func withTimeout<T>(
    seconds: Double,
    operation: @escaping () async throws -> T
) async throws -> T {
    try await withThrowingTaskGroup(of: T.self) { group in
        group.addTask { try await operation() }
        group.addTask {
            try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
            throw TimeoutError.timedOut
        }
        let first = try await group.next()!
        group.cancelAll()
        return first
    }
}

final class TimeoutTests: XCTestCase {
    func testTimeout_timesOutFast() async {
        do {
            _ = try await withTimeout(seconds: 0.01) {
                try await Task.sleep(nanoseconds: 50_000_000) // slower than timeout
                return "OK"
            }
            XCTFail("Expected timeout")
        } catch TimeoutError.timedOut {
            // expected
        } catch {
            XCTFail("Unexpected error: \\(error)")
        }
    }
}

Odotukset (vanha tapa)

Vanhojen callbackien kanssa voitte edelleen käyttää expectation/wait-rakenteita. Suosikaa uusissa toteutuksissa async-testejä.

import XCTest

// Legacy API with a completion handler
func legacyFetch(_ completion: @escaping (String) -> Void) {
    Task { try? await Task.sleep(nanoseconds: 20_000_000); completion("done") }
}

final class ExpectationTests: XCTestCase {
    func testLegacy_withExpectation() {
        let exp = expectation(description: "legacy finishes")
        legacyFetch { value in
            XCTAssertEqual(value, "done")
            exp.fulfill()
        }
        wait(for: [exp], timeout: 1.0)
    }
}

Nykyaikainen async-testityyli

Pikatarkistus: Mikä on paras käytäntö async-funktion testaamiseen?

Kertaus

Kertaus: Käyttäkää async-muotoisia XCTest-metodeja ja await-sanaa, tarkistakaa onnistumis- ja virhepolut, pitäkää viiveet hyvin lyhyinä ja varatkaa expectation-rakenteet vanhoille callbackeille.

Aloita maksutta

Opi Swift tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
122
Oppitunnit
409

Usein kysytyt kysymykset

Onko oppitunti ”Async-koodin testaaminen (XCTest)” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Swift Academy-oppimispolun 3 oppituntia, myös oppitunnin “Async-koodin testaaminen (XCTest)”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Swift Academy-kurssilla on yhteensä 3 oppituntia.

Mitä opin oppitunnilla ”Async-koodin testaaminen (XCTest)”?

Kirjoittakaa async tests -testejä XCTestillä: merkitkää testit async -määritteellä, käyttäkää await - ja throws -määritteitä, testatkaa virheet ja aikakatkaisut sekä tarkistakaa rakenteisen rinnakkai… Harjoittelet Swift Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Swift Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Swift Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/3.

Kuinka kauan ”Async-koodin testaaminen (XCTest)”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Swift Academy-oppitunnilla?

Kyllä. Jokainen Swift Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Tuottaja–kuluttaja, putket ja aikakatkaisut
  2. Vanhojen callbackien ja Combin yhdistäminen async/awaitiin
  3. Async-koodin testaaminen (XCTest)
← Takaisin: Swift Academy