Section 15/201 menit

15. Testing Model ML

15. Testing Model ML

Unit Test untuk ML Feature

swift
// Testing: unit test untuk ML inference

import Testing
import CoreML
@testable import MyApp

@Suite("ML Feature Tests")
struct MLTests {

    @Test("Image classifier returns valid results")
    func testImageClassifier() async throws {
        let classifier = try ImageClassifier()
        let testImage = UIImage(named: "test_cat")!

        let results = try await classifier.classify(image: testImage)

        #expect(!results.isEmpty, "Harus ada setidaknya satu hasil")
        #expect(results.first?.confidence ?? 0 > 0.5, "Confidence harus > 50%")
        #expect(results.allSatisfy { $0.confidence >= 0 && $0.confidence <= 1 },
                "Semua confidence harus dalam range 0-1")
    }

    @Test("Text analyzer detects sentiment correctly")
    func testSentimentAnalysis() {
        let analyzer = TextAnalyzer()

        let positiveText = "Produk ini luar biasa! Kualitas sangat bagus dan pengiriman cepat."
        let negativeText = "Sangat mengecewakan. Barang rusak dan tidak sesuai deskripsi."

        let positiveSentiment = analyzer.analyzeSentiment(of: positiveText)
        let negativeSentiment = analyzer.analyzeSentiment(of: negativeText)

        if case .positive = positiveSentiment { } else {
            Issue.record("Teks positif seharusnya terdeteksi sebagai positif")
        }

        if case .negative = negativeSentiment { } else {
            Issue.record("Teks negatif seharusnya terdeteksi sebagai negatif")
        }
    }

    @Test("Semantic search returns relevant results", arguments: [
        ("kamera foto", "Produk A: kamera profesional"),
        ("lensa wide", "Produk B: lensa wide-angle"),
    ])
    func testSemanticSearch(query: String, expectedResult: String) throws {
        let engine = try #require(SemanticSearchEngine())
        engine.addDocument(id: "1", text: "Produk A: kamera profesional")
        engine.addDocument(id: "2", text: "Produk B: lensa wide-angle")
        engine.addDocument(id: "3", text: "Produk C: tripod portabel")

        let results = engine.search(query: query, topK: 1)

        #expect(!results.isEmpty, "Harus ada hasil untuk query: \(query)")
        #expect(results.first?.document.text == expectedResult,
                "Query '\(query)' harus menemukan '\(expectedResult)'")
    }

    @Test("Model inference performance")
    func testInferencePerformance() async throws {
        let classifier = try ImageClassifier()
        let testImage = UIImage(named: "test_image")!

        let iterations = 10
        var totalTime: TimeInterval = 0

        for _ in 0..<iterations {
            let start = Date()
            _ = try await classifier.classify(image: testImage)
            totalTime += Date().timeIntervalSince(start)
        }

        let averageTime = totalTime / Double(iterations)
        print("Average inference time: \(averageTime * 1000)ms")

        #expect(averageTime < 0.5, "Inference harus selesai dalam 500ms")
    }
}