SwiftUI’ni testlash


Xatti-harakat va jarayonlarni tekshirish uchun view model’lar uchun unit testlar, SwiftUI view’lar uchun esa UI testlar yozing.


ULASHISH

ViewModel’ni unit test qilish

Biznes mantiqni ViewModel’ga joylashtiring va uni XCTestCase yordamida tekshiring.

Sintaksis:

  • final class MyTests: XCTestCase { ... }
  • XCTAssertEqual, XCTAssertTrue kabi tasdiqlashlar (assertions)

Misol

import SwiftUI
import Combine

final class CounterViewModel: ObservableObject {
  @Published private(set) var count = 0
  func increment() { count += 1 }
}

struct CounterView: View {
  @StateObject private var vm = CounterViewModel()
  var body: some View {
    VStack(spacing: 12) {
      Text("Count: \(vm.count)")
      Button("Increment") { vm.increment() }
    }
  }
}
import SwiftUI

struct ContentView: View {
  var body: some View { CounterView() }
}
import SwiftUI

@main
struct MyApp: App {
  var body: some Scene { WindowGroup { ContentView() } }
}
import XCTest

final class CounterViewModelTests: XCTestCase {
  func testIncrement() {
    let vm = CounterViewModel()
    vm.increment()
    XCTAssertEqual(vm.count, 1)
  }
}

Ushbu misol increment() chaqirilishi e’lon qilingan (published) count qiymatini yangilashini tekshiradi.



Dastlabki talablar (UI Testing target’i)

  • UI Testing Bundle target’ini qo‘shing (File → New → Target → UI Testing Bundle).
  • Elementlarni ko‘rinadigan matn bo‘yicha emas, balki accessibility identifikatorlari bo‘yicha topishni afzal ko‘ring.
  • Testlar uchun ilova holatini boshqarish maqsadida ishga tushirish argumentlari va environment qiymatlarini uzating (masalan, ma’lumotlarni tozalash, soxta obyektlardan (fakes) foydalanish).

SwiftUI view’ni UI test qilish

Ilovani XCUIApplication yordamida boshqaring va elementlarni accessibility orqali toping.

Sintaksis:

  • let app = XCUIApplication(); app.launch()
  • app.buttons["Label"].tap()

Misol

import SwiftUI

struct UITestDemo: View {
  @State private var count = 0
  var body: some View {
    VStack(spacing: 12) {
      Text("Count: \(count)").accessibilityIdentifier("countLabel")
      Button("Increment") { count += 1 }
        .accessibilityIdentifier("incrementButton")
    }
  }
}
import SwiftUI

struct ContentView: View {
  var body: some View { UITestDemo() }
}
import SwiftUI

@main
struct MyApp: App {
  init() {
    let args = ProcessInfo.processInfo.arguments
    let env = ProcessInfo.processInfo.environment
    if args.contains("-ui-testing") || env["UITEST_RESET"] == "1" {
      // Reset state, use mock stores/services, disable animations, etc.
      // UIView.setAnimationsEnabled(false) can be used where applicable.
    }
  }
  var body: some Scene { WindowGroup { ContentView() } }
}
import XCTest

final class MyUITests: XCTestCase {
  func testIncrementButton() {
    let app = XCUIApplication()
    app.launchArguments = ["-ui-testing"]
    app.launchEnvironment = ["UITEST_RESET": "1"]
    app.launch()

    let button = app.buttons["incrementButton"]
    XCTAssertTrue(button.waitForExistence(timeout: 2))
    button.tap()

    let label = app.staticTexts["countLabel"]
    XCTAssertTrue(label.waitForExistence(timeout: 2))
    XCTAssertTrue(label.label.contains("Count: 1"))
  }
}

Ushbu misol ilovani ishga tushiradi, tugmani bosadi va yorliq mavjudligini uning accessibility identifikatori orqali tasdiqlaydi.

Maslahat: Unit testlashni osonlashtirish uchun mantiqni view model’larda saqlang; navigatsiya va o‘zaro ta’sir jarayonlari uchun UI testlardan foydalaning.

Testlarni ishonchliroq qilish uchun waitForExistence dan foydalaning va oldindan aniq (deterministik) holatni o‘rnatish uchun ishga tushirish bayroqlarini uzating.



W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!