# Testing — XCTest & Swift Testing — To'liq Darslik

## Mundarija
1. [Nega test yozish kerak?](#motivatsiya)
2. [Testing piramidasi](#testing-pyramid)
3. [XCTest asoslari (setUp, tearDown, Assert)](#xctest-basic)
4. [Unit Test yozish (ViewModel testlash)](#unit-testing)
5. [Mocking va Stubbing (Protocol-based)](#mocking)
6. [Async/Await funksiyalarini testlash](#async-testing)
7. [UI Testing (XCUITest)](#ui-testing)
8. [Swift Testing — Yangi framework (iOS 18+)](#swift-testing)
9. [TDD (Test Driven Development)](#tdd)
10. [Code Coverage (80% maqsad)](#code-coverage)
11. [Real misol: Login ViewModel test](#real-loyiha)
12. [Xulosa](#xulosa)

---

## 1. Nega test yozish kerak? {#motivatsiya}

"Mening kodim ishlayapti, nega test yozishim kerak?" — bu eng katta xato.
- **Xavfsiz Refactoring:** Kodni o'zgartirganda boshqa joylar buzilmaganiga ishonch hosil qilish.
- **Bug'larni erta aniqlash:** Foydalanuvchi xato topishidan oldin uni tuzatish.
- **Hujjatlashtirish:** Testlar kodingiz qanday ishlashi kerakligini ko'rsatib beradi.

---

## 2. Testing piramidasi {#testing-pyramid}

1. **Unit Tests (Asos):** Eng ko'p va eng tez testlar. Alohida funksiya yoki klassni testlaydi.
2. **Integration Tests:** Modullar bir-biri bilan qanday ishlashini testlaydi.
3. **UI Tests:** Ilovani foydalanuvchi kabi ishlatib ko'radi (Eng sekin).

---

## 3. XCTest asoslari {#xctest-basic}

XCTest — Apple'ning klassik testing framework'i.

```swift
import XCTest

class MathTests: XCTestCase {
    // Har bir testdan oldin ishlaydi
    override func setUp() { super.setUp() }
    
    // Har bir testdan keyin ishlaydi
    override func tearDown() { super.tearDown() }
    
    func testAddition() {
        let result = 2 + 2
        XCTAssertEqual(result, 4, "2+2 to'rtga teng bo'lishi kerak")
    }
}
```

---

## 4. Unit Test yozish (ViewModel testlash) {#unit-testing}

MVVM arxitekturasida biznes logika ViewModel'da bo'ladi, shuning uchun uni testlash juda oson.

```swift
func testCounterIncrement() {
    let vm = CounterViewModel()
    vm.increment()
    XCTAssertEqual(vm.count, 1)
}
```

---

## 5. Mocking va Stubbing (Protocol-based) {#mocking}

API dan ma'lumot kelishini kutib o'tirmaymiz. Biz "soxta" (mock) servis yaratamiz.

```swift
protocol NetworkService {
    func fetchData() async throws -> [String]
}

class MockService: NetworkService {
    func fetchData() async throws -> [String] {
        return ["Rasm 1", "Rasm 2"] // Doim tayyor natija qaytaradi
    }
}
```

---

## 6. Async/Await funksiyalarini testlash {#async-testing}

Swift 5.5 dan keyin asinxron kodni testlash juda osonlashdi:

```swift
func testFetchData() async throws {
    let service = MockService()
    let data = try await service.fetchData()
    XCTAssertFalse(data.isEmpty)
}
```

---

## 7. UI Testing (XCUITest) {#ui-testing}

Ilovani haqiqiy simulyatorda ishga tushirib, tugmalarni bosib ko'radi.

```swift
func testLoginFlow() {
    let app = XCUIApplication()
    app.launch()
    
    let emailField = app.textFields["email_field"]
    emailField.tap()
    emailField.typeText("test@mail.com")
    
    app.buttons["login_button"].tap()
    
    XCTAssertTrue(app.staticTexts["Welcome"].exists)
}
```

---

## 8. Swift Testing — Yangi framework (iOS 18+) {#swift-testing}

Apple yangi, zamonaviy va sodda framework chiqardi. `#expect` macro'si va `@Test` atributi bilan ishlaydi.

```swift
import Testing

@Test func checkMath() {
    let result = 2 + 2
    #expect(result == 4)
}

@Suite struct UserTests {
    @Test(arguments: ["Ali", "Vali"])
    func checkUserNames(name: String) {
        #expect(!name.isEmpty)
    }
}
```

---

## 9. TDD (Test Driven Development) {#tdd}

Avval test yozish, keyin kod yozish.
1. **Red:** Test yozing (u o'tmaydi — qizil).
2. **Green:** Test o'tishi uchun eng minimal kodni yozing (yashil).
3. **Refactor:** Kodni chiroyli qiling.

---

## 10. Code Coverage (80% maqsad) {#code-coverage}

Xcode'da "Edit Scheme" → "Test" → "Options" → "Gather Coverage" yoqing. Bu sizga kodingizning necha foizi test bilan qoplanganini ko'rsatadi. Professional ilovalar uchun **80%** yaxshi natija.

---

## 11. Real misol: Login ViewModel test {#real-loyiha}

Darslikda biz login tugmasini aktiv bo'lishi, hato email kiritilganda error chiqishi va muvaffaqiyatli login jarayonini to'liq testlab chiqamiz.

---

## 12. Xulosa {#xulosa}

Test yozadigan dasturchi — professional dasturchi hisoblanadi.
- **Unit test** lardan boshlang.
- **ViewModel** dagi biznes logikani har doim testlang.
- **Swift Testing** framework'ini o'rganishni boshlang (kelajak shunda).

**Vazifa:** O'zingizning kichik funksiyangiz (masalan, yoshni hisoblovchi) uchun 3 ta Unit Test yozing! 🧪
