Unit Test vs Integration Test
Das Fundament der iOS-Teststrategie: Unit-Tests, die eine Einheit isolieren, oder Integrationstests, die das Zusammenspiel von Komponenten prüfen? Wie baut man die Testpyramide richtig auf?
Apples neue Open-Source-Testbibliothek — makrobasiert, nativ in Swift Concurrency integriert
Das rund 13 Jahre alte, kampferprobte Framework — die einzige Adresse für UI- und Performance-Tests
Es gibt einen klaren Trend, aber eine komplette Migration ist ein unnötiges Risiko. Schreibe neue Unit- und Integrationstests mit Swift Testing — das bringt weniger Code, automatisches Erfassen von Werten, eingebaute parametrisierte Tests und Parallelität mit sich. Lass UI- und Performance-Tests in XCTest; die Apple-Dokumentation verlangt das. Da beide Frameworks im selben Target koexistieren können und Swift 6.4 ein Cross-Framework-Reporting eingeführt hat, ist eine komplette Migration unnötig — gehe Datei für Datei vor.
| Kategorie | Swift Testing | XCTest |
|---|---|---|
| Performance | 8/10 | 8/10 |
| Erlernbarkeit | 7/10 | 6/10 |
| Ökosystem | 6/10 | 8/10 |
| Community | 6/10 | 8/10 |
| Arbeitsmarkt | 5/10 | 7/10 |
| Zukunftssicherheit | 9/10 | 6/10 |
// Swift Testing — parametrisierter asynchroner Unit-Test
import Testing
@testable import PaymentKit
@Suite("Preisberechnung")
struct PriceCalculatorTests {
@Test("Rabatt wird bei gültigen Gutscheincodes korrekt berechnet",
arguments: [
("SAVE10", 100.0, 90.0),
("SAVE20", 100.0, 80.0),
("NONE", 100.0, 100.0)
])
func discountIsApplied(code: String, base: Double, expected: Double) async throws {
let calculator = PriceCalculator()
let result = try await calculator.applyDiscount(code: code, to: base)
#expect(result == expected, "Für \(code) erwartet: \(expected), erhalten: \(result)")
}
@Test("Ungültiger Gutschein wirft einen Fehler")
func invalidCouponThrows() async throws {
let calculator = PriceCalculator()
await #expect(throws: CouponError.invalid) {
try await calculator.applyDiscount(code: "XXX", to: 100.0)
}
}
@Test("Warenkorbsumme ist erforderlich", .disabled("Warenkorb-Service noch nicht migriert"))
func cartTotalRequired() async throws {
let calculator = PriceCalculator()
try #require(calculator.cartTotal > 0)
}
}// XCTest — gleiches Szenario (Preisberechnung) + UI-Test
import XCTest
@testable import PaymentKit
final class PriceCalculatorTests: XCTestCase {
var calculator: PriceCalculator!
override func setUpWithError() throws {
calculator = PriceCalculator()
}
func testDiscountIsAppliedForKnownCoupons() async throws {
let cases: [(String, Double, Double)] = [
("SAVE10", 100.0, 90.0),
("SAVE20", 100.0, 80.0),
("NONE", 100.0, 100.0)
]
for (code, base, expected) in cases {
let result = try await calculator.applyDiscount(code: code, to: base)
XCTAssertEqual(result, expected, "Gutschein: \(code)")
}
}
// XCTAssertThrowsError ist synchron; bei async-Aufrufen do/catch + XCTFail verwenden
func testInvalidCouponThrows() async throws {
do {
_ = try await calculator.applyDiscount(code: "XXX", to: 100.0)
XCTFail("Fehler wurde erwartet")
} catch {
XCTAssertEqual(error as? CouponError, .invalid)
}
}
}
// UI-Test — nur mit XCTest/XCUITest möglich
final class CheckoutUITests: XCTestCase {
func testApplyCouponButtonUpdatesTotal() throws {
let app = XCUIApplication()
app.launch()
app.textFields["couponField"].tap()
app.textFields["couponField"].typeText("SAVE10")
app.buttons["applyCouponButton"].tap()
XCTAssertEqual(app.staticTexts["totalLabel"].label, "$90.00")
}
}Es gibt einen klaren Trend, aber eine komplette Migration ist ein unnötiges Risiko. Schreibe neue Unit- und Integrationstests mit Swift Testing — das bringt weniger Code, automatisches Erfassen von Werten, eingebaute parametrisierte Tests und Parallelität mit sich. Lass UI- und Performance-Tests in XCTest; die Apple-Dokumentation verlangt das. Da beide Frameworks im selben Target koexistieren können und Swift 6.4 ein Cross-Framework-Reporting eingeführt hat, ist eine komplette Migration unnötig — gehe Datei für Datei vor.
Kostenlose Beratung erhaltenNein. Swift Testing ist Apples empfohlener Standard für neue Unit- und Integrationstests, aber XCTest wurde nicht entfernt; XCUITest (UI-Automatisierung) und XCTMetric (Performance-Tests) gibt es weiterhin nur in XCTest. Beide können im selben Target koexistieren und arbeiten seit Swift 6.4 dank Cross-Framework-Reporting zusammen.