Als je wilt dat Xcode de test markeert die een gedeelde XCTest-helper heeft aangeroepen, geef de helper dan standaardparameters #filePath en #line en geef beide door aan de assertions. Deze handleiding laat de oplossing, geneste helpers en het equivalent in Swift Testing zien.

Waarom markeert Xcode de helper?

Een gedeelde assertion introduceert een extra bronlocatie. De test roept je helper aan en de helper roept een XCTest-assertion aan. Als die assertion de standaardlocatieargumenten gebruikt, is de gerapporteerde locatie de assertion in de helper. Apple documenteert file: StaticString = #filePath en line: UInt = #line voor zowel XCTAssertEqual als XCTFail.

Leg de locatie van de aanroeper vast bij de grens van de helper en geef die waarden vervolgens door. De standaardwaarden voor bronlocaties in Swift leggen de aanroepplaats vast; het Swift-project licht dit gedrag toe in SE-0274: Concise magic file names. Apple laat dit exacte XCTest-helperpatroon ook zien in Migrate to Swift Testing, waarbij Xcode de fout aan de helperaanroep toeschrijft.

Voor een ontwikkelaar die op een Mac in Xcode werkt, is de concrete taak om herbruikbare controles te behouden en ervoor te zorgen dat elke fout terugleidt naar de relevante testinvoer. De voorbeelden hieronder gebruiken alleen kleine arrays met gehele getallen. Bij het uitvoeren ervan zijn geen appmodel, servicevervanging, gedownloade afhankelijkheid of netwerktoegang nodig.

Voeg locatieparameters van de aanroeper toe aan een XCTest-helper

Gebruik een bestaande macOS-unit-testtarget. Als het project er een nodig heeft, kies je File > New > Target, filter je op Test en selecteer je Unit Testing Bundle. Kies File > New > New File From Template en selecteer XCTest Unit Test om een testbestand toe te voegen. Dit zijn de door Apple gedocumenteerde paden in Adding tests to your Xcode project.

Plaats dit volledige testbestand in die unit-testtarget. De tweede test geeft bewust een onjuist verwacht totaal op, zodat je de foutlocatie kunt inspecteren.

import XCTest

private func assertTotal(
    _ values: [Int],
    equals expected: Int,
    file: StaticString = #filePath,
    line: UInt = #line
) {
    let actual = values.reduce(0, +)
    XCTAssertEqual(
        actual,
        expected,
        "Unexpected total for \(values)",
        file: file,
        line: line
    )
}

final class TotalHelperTests: XCTestCase {
    func testMatchingTotal() {
        assertTotal([2, 3, 4], equals: 9)
    }

    func testDeliberatelyIncorrectTotal() {
        assertTotal([2, 3, 4], equals: 10)
    }
}

De belangrijke onderdelen zijn de parametertypen, de standaardwaarden en het expliciet doorgeven. StaticString en UInt komen overeen met de assertion-signatuur van XCTest. Laat #filePath en #line rechtstreeks in de standaardwaarden van de helper staan. De test roept de helper vervolgens aan zonder een van beide locatieargumenten handmatig op te geven. Zie de gedocumenteerde XCTAssertEqual-parameters.

De berekening is ter illustratie: 2 + 3 + 4 is 9, dus de eerste vergelijking klopt en de tweede niet. Deze rekenvoorbeelden zijn lokaal gecontroleerd met Python. In de onderzoeksomgeving was geen Swift-executable beschikbaar, dus de Swift-voorbeelden zijn bekeken maar hier niet gecompileerd of uitgevoerd.

Controleer de locatie en het testresultaat

Kies Product > Test of voer de afzonderlijke test uit met de afspeelknop naast de declaratie. Selecteer daarna de mislukte test in de Test navigator en inspecteer de diagnose. Apple beschrijft deze bedieningselementen en de foutdetails in Running tests and interpreting results.

Controleer voor dit voorbeeld twee afzonderlijke resultaten: testDeliberatelyIncorrectTotal() mislukt en de assertion-diagnose verwijst naar de aanroep assertTotal([2, 3, 4], equals: 10). De verwachte toeschrijving aan de aanroeper volgt het door Apple getoonde patroon voor het doorgeven van locatiegegevens. Wijzig na controle 10 in 9 en voer de tests opnieuw uit; de opzettelijke mismatch hoort niet in de uiteindelijke testsuite.

Als de diagnose nog steeds naar de helper wijst, inspecteer dan de laatste assertion-aanroep. Het declareren van locatieparameters is niet voldoende als de helper file: file of line: line weglaat bij de aanroep die de fout registreert.

Behoud de locatie in elke helperlaag

Geneste helpers moeten de locatie op dezelfde manier expliciet doorgeven. Stel dat een test een domeinhelper aanroept, die vervolgens een assertion-helper op lager niveau aanroept. Als de buitenste helper de locatieargumenten weglaat, legt de helper op lager niveau de tussenliggende aanroepplaats vast.

Dit is een taalgrens die controle verdient: standaardwaarden voor bronlocaties gaan niet automatisch mee in willekeurige helperaanroepen. SE-0285: Ease the transition to concise magic file strings bespreekt expliciet dat deze standaardwaarden niet transitief zijn.

Het volgende is een volledig alternatief testbestand. Het laat zien hoe een helper een andere helper aanroept en daarbij de oorspronkelijke testlocatie behoudt.

import XCTest

private func assertIntegerEqual(
    _ actual: Int,
    _ expected: Int,
    file: StaticString = #filePath,
    line: UInt = #line
) {
    XCTAssertEqual(actual, expected, file: file, line: line)
}

private func assertRowTotal(
    _ row: [Int],
    equals expected: Int,
    file: StaticString = #filePath,
    line: UInt = #line
) {
    assertIntegerEqual(
        row.reduce(0, +),
        expected,
        file: file,
        line: line
    )
}

final class NestedTotalHelperTests: XCTestCase {
    func testRowTotal() {
        assertRowTotal([2, 3, 4], equals: 9)
    }
}

Gebruik bij het nalopen van een langere helperketen een eenvoudige traceeroefening: begin bij de testaanroep, volg elke helper en controleer of dezelfde vastgelegde locatie de assertion bereikt. Leg standaardwaarden vast op de grens die in het resultaat moet verschijnen; geef de bestaande waarden door aan de overige lagen. Verberg het vastleggen niet achter een andere functie die als standaardargument wordt gebruikt; dat is de valkuil die SE-0285 illustreert.

Stopt het registreren van een fout de aanroepende test?

Fouttoeschrijving en programmaverloop zijn afzonderlijke beslissingen. XCTest’s continueAfterFailure heeft standaard de waarde true, dus na een mislukte assertion gaat de uitvoering normaal gesproken door. Het wijzigen van het gerapporteerde bestand en de regel verandert die eigenschap niet. Apple documenteert dit gedrag in continueAfterFailure.

Als de helper een voorwaarde detecteert waardoor de rest van zijn eigen werk ongeldig wordt, geef die helper dan een expliciet exitpad. Registreer bijvoorbeeld de fout met de doorgegeven locatie en keer daarna terug uit de helper. Houd er rekening mee dat terugkeren uit een helper de controle aan de aanroeper teruggeeft; stem het vervolgwerk van de aanroeper daarop af. Apples migratiehandleiding laat een onvoorwaardelijke fout gevolgd door een return zien.

Houd de eerste verificatie synchroon en klein. Controleer dat een opzettelijk onjuiste berekening op de verwachte aanroepplaats mislukt voordat je uitgebreidere setup of asynchroon gedrag toevoegt. Zo kun je een fout bij het doorgeven van de locatie onderscheiden van andere problemen met de testuitvoering.

Gebruik een ondersteunde bronlocatie in Swift Testing

Gebruik voor een helper die door Swift Testing-tests wordt aangeroepen #expect met een expliciete SourceLocation. Apple documenteert sourceLocation als de locatie waaraan verwachtingen en issues worden toegeschreven, en geeft aan dat een onjuiste voorwaarde een issue registreert voor de test die in de huidige taak wordt uitgevoerd. Zie expect(_:_:sourceLocation:).

Dit volledige alternatieve bestand vereist Swift Testing, beschikbaar met Xcode 16 en Swift 6.0. Het legt de vier locatiecomponenten vast als afzonderlijke standaardwaarden en construeert vervolgens de gedocumenteerde SourceLocation-initializer.

import Testing

private func expectTotal(
    _ values: [Int],
    equals expected: Int,
    fileID: String = #fileID,
    filePath: String = #filePath,
    line: Int = #line,
    column: Int = #column
) {
    let location = SourceLocation(
        fileID: fileID,
        filePath: filePath,
        line: line,
        column: column
    )
    let actual = values.reduce(0, +)
    #expect(actual == expected, sourceLocation: location)
}

@Test func matchingTotal() {
    expectTotal([2, 3, 4], equals: 9)
}

@Test func deliberatelyIncorrectTotal() {
    expectTotal([2, 3, 4], equals: 10)
}

De initializer vereist een correct opgemaakte, niet-lege bestands-ID en positieve regel- en kolomnummers. Door de door de compiler aangeleverde componenten vast te leggen, hoef je deze waarden niet zelf te verzinnen. Geef bij het nesten van deze helpers alle vier vastgelegde argumenten door, net zoals de XCTest-versie zijn twee argumenten doorgeeft. Corrigeer ook hier de opzettelijke verwachting 10 nadat je de toeschrijving hebt gecontroleerd.

Wat verandert er als XCTest en Swift Testing een helper delen?

Beide frameworks kunnen naast elkaar in één testbundle worden gebruikt, maar een helper die de grens tussen frameworks overschrijdt, vereist een versieafhankelijke aanpak. Apples actuele migratiehandleiding documenteert de interoperabiliteit en de standaardinstellingen: toolchains ouder dan Swift 6.4 gebruiken none; Swift 6.4 of hoger gebruikt standaard limited voor packages die een eerdere tools-versie declareren en complete voor packages die tools-versie 6.4 of hoger declareren.

Interoperabiliteitsmodus Mislukte XCTest-assertion binnen een Swift Testing-test
none Cross-library-issue wordt genegeerd
limited Gerapporteerd als waarschuwing, met aanwijzingen voor modernisering
complete Behoudt de ernst van een fout, met aanwijzingen voor modernisering
strict Gerapporteerd met fatalError

Deze modi verklaren waarom een helper de juiste tekst kan rapporteren terwijl een Swift Testing-test toch slaagt. In Apples WWDC26-migratiesessie wordt dit exacte resultaat getoond; vervolgens wordt de interoperabiliteitsinstelling van het testplan onder Test Execution op Complete gezet om de ernst van de fout te behouden. Controleer je geïnstalleerde toolchain voordat je op deze functie vertrouwt.

Houd bij oudere toolchains de foutmelding native aan elk framework en deel de deterministische berekening eronder. Voor ondersteunde interoperabiliteitsconfiguraties laat Apple ook zien hoe je de XCTFail van een helper vervangt door Swift Testing’s Issue.record. Het doorgeven van de bronlocatie moet tijdens die migratie behouden blijven.

Diagnoseer het resterende symptoom

Wat je ziet Wat je vervolgens controleert
De fout wijst naar de assertion-helper Controleer of de assertion de vastgelegde locatieargumenten ontvangt
De fout wijst naar een buitenste helper Controleer of die buitenste helper de locatie van de aanroeper doorgeeft
Een Swift Testing-test slaagt ondanks een XCTest-assertion Controleer de ondersteuning van de toolchain en de interoperabiliteitsmodus
Code wordt uitgevoerd nadat een XCTest-assertion mislukt Controleer het beoogde programmaverloop en continueAfterFailure
Er verschijnt geen voorbeeldtest in de testuitvoering Controleer of het bestand bij de unit-testtarget hoort en of het actieve testplan de test bevat

Voor het ontdekken en selecteren van tests beschrijven Apples testconfiguratiehandleiding en handleiding voor testuitvoering testtargets en actieve plannen. Raadpleeg bij een test die frameworks combineert eerst de hierboven beschreven interoperabiliteitsregels voordat je locatieargumenten wijzigt.

Een bruikbare gedeelde helper behoudt drie dingen: een betekenisvolle vergelijking, een diagnose die aan de bedoelde aanroeper is gekoppeld en het beoogde testresultaat. Controleer die met één opzettelijke mismatch, verwijder die mismatch en blijf de vastgelegde locatie doorgeven wanneer er een helperlaag bijkomt.

Bronnen