Section 1/121 menit
1. Masalah yang Dipecahkan
1. Masalah yang Dipecahkan
XCTest: Warisan Objective-C yang Mulai Menua
XCTest didesain pada era Objective-C dan membawa banyak pattern dari sana ke Swift, menciptakan beberapa friction:
1. Harus pakai class dan mewarisi XCTestCase
swift
// XCTest: boilerplate inheritance dan class requirement
class UserServiceTests: XCTestCase {
var sut: UserService! // harus var + implicitly unwrapped Optional
override func setUp() { super.setUp() // harus panggil super
sut = UserService()
}
override func tearDown() {
sut = nil
super.tearDown() // harus panggil super
}
func testLogin() { // harus prefix 'test' — konvensi runtime, bukan compile-time
// ...
}
}
2. Assertion messages yang buruk
swift
// XCTest: pesan error tidak informatif
XCTAssertEqual(user.name, "Ari Supriatna")
// Gagal: XCTAssertEqual failed: ("Ari") is not equal to ("Ari Supriatna")
// Tidak ada konteks: di mana? Nilai yang ada apa?
// Swift Testing: pesan yang kaya informasi
#expect(user.name == "Ari Supriatna")
// Gagal: Expectation failed: (user.name → "Ari") == "Ari Supriatna"
// Jelas: kita tahu nilai aktual dan yang diharapkan
3. Tidak ada parameterized test built-in
swift
// XCTest: harus tulis manual atau pakai library eksternal
func testValidateEmail_valid() { XCTAssertTrue(validate("a@b.com")) }
func testValidateEmail_noAt() { XCTAssertFalse(validate("ab.com")) }
func testValidateEmail_noDomain() { XCTAssertFalse(validate("a@")) }
// Banyak fungsi, banyak duplikasi
// Swift Testing: satu fungsi dengan banyak input
@Test("Email validation", arguments: ["a@b.com", "x@y.z", "user@domain.org"])
func validateValidEmails(email: String) {
#expect(isValidEmail(email))
}
4. Async testing yang verbose
swift
// XCTest: expectation + wait + timeout
func testAsyncFetch() {
let expectation = self.expectation(description: "fetch completes")
service.fetch { result in
XCTAssertNotNil(result)
expectation.fulfill()
}
wait(for: [expectation], timeout: 5.0)
}
// Swift Testing: native async/await
@Test
func fetchUser() async throws {
let user = try await service.fetch(id: "123")
#expect(user.id == "123")
}