Section 2/121 menit

2. Teori: Desain Swift Testing

2. Teori: Desain Swift Testing

Prinsip Desain

Swift Testing didesain dengan prinsip-prinsip:

  1. Macro-based — menggunakan Swift macros (@Test, #expect) alih-alih runtime introspection
  2. Value-oriented — test bisa berupa struct atau class, tidak harus inherit
  3. Parallel by default — test dijalankan secara paralel kecuali ada hambatan eksplisit
  4. Expressive failures — pesan error yang kaya dengan nilai aktual dan ekspresi aslinya
  5. Composable traits — behavior test dikonfigurasi melalui traits, bukan override method

Cara Kerja Macro @Test

@Test adalah Swift macro yang di-expand oleh compiler. Secara konseptual:

swift
// Kamu tulis:
@Test("Login berhasil")
func loginSucceeds() async throws { ... }

// Compiler expand menjadi:
// (Simplistik — implementasi actual lebih kompleks)
func loginSucceeds() async throws { ... }
Testing.__registerTest(
    name: "Login berhasil",
    function: loginSucceeds,
    sourceLocation: .init(file: #file, line: #line)
)

Ini berbeda dari XCTest yang menggunakan Objective-C runtime introspection untuk menemukan func test*() — Swift Testing menggunakan compile-time registration. Artinya:

  • Lebih cepat (tidak perlu scan runtime)
  • Lebih portable (tidak bergantung Objective-C runtime)
  • Bisa berjalan di Linux dan Windows

Cara Kerja #expect

#expect adalah expression macro yang di-expand untuk menangkap informasi lengkap tentang ekspresi:

swift
// Kamu tulis:
#expect(user.age > 18 && user.isVerified)

// Compiler menangkap sub-expressions:
// - user.age → nilai aktual (misalnya 15)
// - user.isVerified → nilai aktual (misalnya true)
// - user.age > 18 → false
// - seluruh ekspresi → false

// Pesan gagal:
// Expectation failed: (user.age → 15) > 18 && (user.isVerified → true)
// Jelas terlihat bahwa 'age' yang jadi masalah, bukan 'isVerified'