Om du vill att Xcode ska markera testet som anropade en delad XCTest-hjälpfunktion ger du hjälpfunktionen standardparametrarna #filePath och #line och skickar vidare båda till dess påståenden. Den här genomgången visar lösningen, nästlade hjälpfunktioner och motsvarigheten i Swift Testing.

Varför markerar Xcode hjälpfunktionen?

Ett delat påstående introducerar ytterligare en källkodsplats. Testet anropar din hjälpfunktion, och hjälpfunktionen anropar ett XCTest-påstående. Om det påståendet använder sina standardargument för platsen är den rapporterade platsen påståendet inuti hjälpfunktionen. Apple dokumenterar file: StaticString = #filePath och line: UInt = #line för både XCTAssertEqual och XCTFail.

Fånga anroparens plats vid hjälpfunktionens gräns och skicka sedan värdena vidare. Swifts standardvärden för källplatser fångar anropsplatsen; Swift-projektet förklarar det här beteendet i SE-0274: Concise magic file names. Apple visar också exakt detta mönster för XCTest-hjälpfunktioner i Migrate to Swift Testing, där Xcode hänför felet till anropet av hjälpfunktionen.

För en utvecklare som arbetar i Xcode på en Mac är den konkreta uppgiften att bevara återanvändbara kontroller och samtidigt se till att varje fel leder tillbaka till relevant testindata. Exemplen nedan använder bara små heltalsmatriser. De kräver ingen appmodell, tjänstersättning, nedladdad dependency eller nätverksåtkomst när de körs.

Lägg till parametrar för anroparens plats i en XCTest-hjälpfunktion

Använd ett befintligt macOS-mål för enhetstester. Om projektet behöver ett väljer du File > New > Target, filtrerar på Test och väljer Unit Testing Bundle. Om du vill lägga till en testfil väljer du File > New > New File From Template och sedan XCTest Unit Test. Det här är Apples dokumenterade sökvägar i Adding tests to your Xcode project.

Placera den här kompletta testfilen i målet för enhetstester. Det andra testet anger avsiktligt en felaktig förväntad totalsumma så att du kan granska felplatsen.

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 viktiga delarna är parametertyperna, standardvärdena och den uttryckliga vidarebefordringen. StaticString och UInt matchar signaturen för XCTest-påståendet. Behåll #filePath och #line direkt i hjälpfunktionens standardvärden. Testet anropar sedan hjälpfunktionen utan att manuellt ange något av platsargumenten. Se de dokumenterade XCTAssertEqual-parametrarna.

Aritmetiken är illustrativ: 2 + 3 + 4 är 9, så den första jämförelsen stämmer och den andra gör det inte. De här aritmetiska fallen kontrollerades lokalt med Python. En Swift-körbar fil var inte tillgänglig i forskningsmiljön, så Swift-exemplen granskades men kompilerades eller kördes inte här.

Kontrollera platsen och testresultatet

Välj Product > Test eller kör det enskilda testet med uppspelningsknappen bredvid dess deklaration. Markera sedan det misslyckade testet i Test navigator och granska diagnostiken. Apple beskriver de här reglagen och feldetaljerna i Running tests and interpreting results.

Kontrollera två separata resultat för det här exemplet: testDeliberatelyIncorrectTotal() misslyckas, och dess påståendediagnostik pekar på anropet assertTotal([2, 3, 4], equals: 10). Den förväntade hänföringen till anroparen följer Apples visade vidarebefordringsmönster. Ändra 10 till 9 när du har kontrollerat detta och kör testerna igen; den avsiktliga felaktigheten ska tas bort från den färdiga testsviten.

Om diagnostiken fortfarande pekar inuti hjälpfunktionen granskar du det slutliga påståendeanropet. Det räcker inte att deklarera platsparametrar om hjälpfunktionen utelämnar file: file eller line: line på den plats där felet registreras.

Bevara platsen genom varje lager av hjälpfunktioner

Nästlade hjälpfunktioner behöver samma uttryckliga vidarebefordring. Anta att ett test anropar en domänhjälpfunktion, som sedan anropar en påståendehjälpfunktion på lägre nivå. Om den yttre hjälpfunktionen utelämnar platsargumenten fångar hjälpfunktionen på lägre nivå den mellanliggande anropsplatsen.

Det här är en språkgräns som är värd att kontrollera: standardvärden för källplatser förs inte automatiskt vidare genom godtyckliga hjälpfunktionsanrop. SE-0285: Ease the transition to concise magic file strings tar uttryckligen upp att de här standardvärdena inte är transitiva.

Följande är en komplett alternativ testfil. Den visar hur en hjälpfunktion kan anropa en annan samtidigt som den ursprungliga testplatsen bevaras.

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)
    }
}

Gör en enkel spårningsövning när du granskar en längre kedja av hjälpfunktioner: börja vid testanropet, följ varje hjälpfunktion och kontrollera att samma fångade plats når påståendet. Fånga standardvärden vid den gräns som ska visas i resultatet och vidarebefordra befintliga värden genom de återstående lagren. Dölj inte fångsten bakom en annan funktion som används som standardargument; det är fallgropen som illustreras av SE-0285.

Avbryts det anropande testet när ett fel rapporteras?

Felattribuering och kontrollflöde är separata beslut. XCTest-metoden continueAfterFailure har standardvärdet true, så körningen fortsätter normalt efter ett misslyckat påstående. Att ändra den rapporterade filen och raden ändrar inte det beteendet. Apple dokumenterar detta i continueAfterFailure.

Om en hjälpfunktion upptäcker ett villkor som gör att dess återstående arbete blir ogiltigt ger du hjälpfunktionen en uttrycklig utgång. Du kan till exempel registrera felet med den vidarebefordrade platsen och sedan returnera från hjälpfunktionen. Tänk på att en retur från en hjälpfunktion återför kontrollen till anroparen; utforma anroparens efterföljande arbete därefter. Apples migreringsguide visar ett ovillkorligt fel följt av en retur.

Håll den första kontrollen synkron och liten. Kontrollera att en avsiktligt felaktig beräkning misslyckas vid den förväntade anropsplatsen innan du lägger till mer avancerad konfiguration eller asynkront beteende. Den ordningen skiljer ett fel i platsvidarebefordringen från andra problem vid testkörning.

Använd en källplats som stöds i Swift Testing

För en hjälpfunktion som anropas av Swift Testing-tester använder du #expect med en uttrycklig SourceLocation. Apple dokumenterar sourceLocation som platsen dit förväntningar och problem hänförs och anger att ett falskt villkor registrerar ett problem för testet som körs i den aktuella uppgiften. Se expect(_:_:sourceLocation:).

Den här kompletta alternativa filen kräver Swift Testing, som är tillgängligt med Xcode 16 och Swift 6.0. Den fångar de fyra platskomponenterna som separata standardvärden och skapar sedan den dokumenterade SourceLocation-instansen.

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)
}

Initieraren kräver ett korrekt formaterat, icke-tomt fil-ID samt positiva rad- och kolumnnummer. Om du fångar kompilatorns angivna komponenter slipper du hitta på dessa värden. När du nästlar de här hjälpfunktionerna vidarebefordrar du alla fyra fångade argument, precis som XCTest-versionen vidarebefordrar sina två argument. Korrigera återigen det avsiktligt felaktiga 10-förväntningsvärdet när du har kontrollerat hänföringen.

Vad ändras när XCTest och Swift Testing delar en hjälpfunktion?

Båda ramverken kan finnas i samma testpaket, men en hjälpfunktion som går över ramverksgränserna behöver hanteras utifrån version. Apples aktuella migreringsguide dokumenterar interoperabilitet och standardvärden: verktygskedjor före Swift 6.4 använder none; Swift 6.4 eller senare har som standard limited för paket som anger en tidigare verktygsversion och complete för paket som anger verktygsversion 6.4 eller senare.

Interoperabilitetsläge XCTest-påståendefel inuti ett Swift Testing-test
none Problem mellan bibliotek ignoreras
limited Rapporteras som en varning med vägledning om modernisering
complete Behåller felallvaret med vägledning om modernisering
strict Rapporteras med fatalError

De här lägena förklarar varför en hjälpfunktion kan rapportera rätt text men ändå låta ett Swift Testing-test godkännas. Apples migreringssession på WWDC26 visar exakt detta utfall och ändrar sedan testplanens interoperabilitetsinställning under Test Execution till Complete för att bevara felallvaret. Kontrollera den installerade verktygskedjan innan du förlitar dig på den funktionen.

För äldre verktygskedjor bör felrapporteringen hanteras av respektive ramverk, medan den deterministiska beräkningen delas. För konfigurationer med interoperabilitet som stöds visar Apple också hur man ersätter en hjälpfunktions XCTFail med Swift Testings Issue.record. Platsvidarebefordringen behöver fortfarande bevaras under migreringen.

Felsök kvarstående symptom

Det du ser Vad du bör granska härnäst
Felet pekar inuti påståendehjälpfunktionen Bekräfta att påståendet får de fångade platsargumenten
Felet pekar inuti en yttre hjälpfunktion Bekräfta att den yttre hjälpfunktionen vidarebefordrar anroparens plats
Swift Testing-testet godkänns trots ett XCTest-påstående Kontrollera stöd i verktygskedjan och interoperabilitetsläge
Kod körs efter att ett XCTest-påstående misslyckas Kontrollera det avsedda kontrollflödet och continueAfterFailure
Inget exempeltest visas i körningen Bekräfta att filen tillhör målet för enhetstester och att den aktiva testplanen innehåller den

För testupptäckt och urval beskriver Apples guide för testkonfiguration och guide för testkörning testmål och aktiva planer. Vid en kontroll över ramverksgränserna följer du de dokumenterade interoperabilitetsreglerna ovan innan du ändrar platsargumenten.

En användbar delad hjälpfunktion bevarar tre saker: en meningsfull jämförelse, diagnostik kopplad till avsedd anropare och avsett testresultat. Kontrollera dem med en avsiktlig felaktighet, ta bort den och fortsätt vidarebefordra den fångade platsen varje gång ett nytt lager av hjälpfunktioner läggs till.

Källor