Unit testlash — bu dasturiy ta’minotni tekshirish usuli bo‘lib, unda alohida modullar yoki kod funksiyalarining to‘g‘ri ishlashi qolgan tizimdan ajratilgan holda tekshiriladi. Martin Fowler, 2026 ma’lumotlariga ko‘ra, unit testlar CI/CD va refaktoringning asosi bo‘lib, kodning ishlash qobiliyati haqida tezkor qayta aloqani ta’minlaydi. Modul testlash rivojlanishning dastlabki bosqichlarida xatolarni aniqlashga yordam beradi va ularni tuzatish xarajatlarini o‘nlab marta kamaytiradi.
Asosiy
Unit testlash — bu dastur kodining alohida birliklarini — funksiyalar, metodlar, sinflar — dasturning qolgan qismidan ajratilgan holda tekshirish jarayonidir. Har bir test moduldan foydalanishning muayyan stsenariysini ishga tushiradi va natija kutilganiga mos kelishini tekshiradi. Unit testlar asosiy kod bilan bir xil dasturlash tilida yoziladi va rivojlanish muhitida yoki CI/CD pipeline da avtomatik ravishda bajariladi. Integratsion testlardan farqli o‘laroq, unit testlar haqiqiy ma’lumotlar bazalari, fayl tizimi yoki tarmoq xizmatlari bilan o‘zaro aloqada bo‘lmaydi.
Asosiy maqsad — o‘zgarishlardan so‘ng kodning to‘g‘riligi haqida tezkor qayta aloqa olish. Dasturchi metodni refaktoring qilsa, unit testlar to‘plami xatti-harakatning buzilmaganligini tasdiqlaydi. Google Testing Blog (2025) ma’lumotlariga ko‘ra, unit testlar bilan qamrovi 60% dan yuqori bo‘lgan loyihalarda ishlab chiqarish hodisalari 2,5 baravar kam uchraydi. Qo‘shimcha afzalliklar: kod hujjatlari (testlar API dan qanday foydalanishni ko‘rsatadi), refaktoringni soddalashtirish (xatti-harakatni saqlab, amalga oshirishni o‘zgartirish mumkin) va regressiyalarni tezkor diagnostika qilish.
Har bir avtomatik test unit test emas. Mezonlar: bitta modul (sinf yoki funksiya) tekshiriladi, tashqi bog‘liqliklar moklar yoki stublar bilan almashtiriladi, test millisekundlarda bajariladi, server yoki ma’lumotlar bazasini ishga tushirishni talab qilmaydi. Haqiqiy ma’lumotlar bazasiga murojaat qiladigan test — bu integratsion test. Brauzerni ochadigan test — bu E2E test. Test turlari orasidagi chegaralarni tushunish test piramidasida kuchlarni to‘g‘ri taqsimlash uchun muhimdir.
Sifatli unit testlar Robert C. Martin tomonidan shakllantirilgan FIRST tamoyillariga amal qiladi. Har bir test Fast (tezkor — millisekundlar), Isolated (ajratilgan — boshqa testlarga bog‘liq emas), Repeatable (takrorlanadigan — har qanday mashinada bir xil natija), Self-validating (o‘zini tekshiruvchi — natija “passed” yoki “failed”, qo‘lda tekshirishsiz) va Timely (o‘z vaqtida — koddan oldin yoki bir vaqtda yozilgan) bo‘lishi kerak. Har qanday tamoyilning buzilishi test qiymatini pasaytiradi.
Unit testlarni yozish uchun standart andoza. Arrange — ma’lumotlar va bog‘liqliklarni tayyorlash: obyektlarni yaratish, moklarni sozlash, kirish parametrlarini belgilash. Act — tekshirilayotgan harakatni bajarish: metod yoki funksiyani chaqirish. Assert — natijani tekshirish: haqiqiy qiymatni kutilgan bilan solishtirish. Uch blokga bo‘linish testni o‘qiladigan va tushunarli qiladi. Agar Assert bloki murakkab mantiqni talab qilsa, test bir vaqtning o‘zida juda ko‘p narsani tekshirayotgan bo‘lishi mumkin.
// Kotlin da JUnit 5 bilan AAA andozasi bo'yicha unit test namunasi
class CalculatorTest {
private lateinit var calculator: Calculator
@BeforeEach
fun setUp() {
// ARRANGE — test qilinadigan obyektni yaratamiz
calculator = Calculator()
}
@Test
fun addition_shouldReturnCorrectSum() {
// ACT — harakatni bajaramiz
val result = calculator.add(2, 3)
// ASSERT — natijani tekshiramiz
Assertions.assertEquals(5, result)
}
}
Test nomi nima tekshirilayotganini va qanday natija kutilayotganini tavsiflashi kerak. Format: [methodName]_[scenario]_[expectedResult]. Misol: calculateTotal_whenDiscountApplied_shouldReturnDiscountedTotal. Yaxshi test nomi sharhni o‘rnini bosadi va muvaffaqiyatsizlikda qaysi funksionallik buzilganini darhol ko‘rsatadi. test1, checkSomething yoki verify kabi nomlardan saqlaning — ular ma’lumot bermaydi va diagnostikani qiyinlashtiradi.
Tekshirilayotgan modulni tashqi bog‘liqliklardan ajratish uchun test dublerlari (test doubles) ishlatiladi. Asosiy turlari: moklar (mocks) — ma’lum bir metodning to‘g‘ri parametrlar bilan chaqirilganligini tekshiradi; stublar (stubs) — metod chaqirilganda belgilangan qiymatlarni qaytaradi; feyklar (fakes) — real komponentning soddalashtirilgan amalga oshirilishi (masalan, ma’lumotlar bazasi bilan ishlaydigan UserRepository o‘rniga InMemoryUserRepository). Tanlov nimani tekshirish kerakligiga bog‘liq: holatni (stub) yoki o‘zaro aloqani (mok).
| Dubler | Nimani tekshiradi | Misol |
|---|---|---|
| Mok | Metodning to‘g‘ri parametrlar bilan chaqirilishi | userRepository.save(user) roppa-rosa 1 marta chaqirildi |
| Stub | Qaytariladigan qiymat | repository.findById(1) User(id=1, name=“Test”) qaytaradi |
| Feyk | Soddalashtirilgan amalga oshirish orqali mantiq | Ma’lumotlar bazasi o‘rniga HashMap bilan InMemoryMapUserRepository |
| Ayg‘oqchi | Haqiqiy obyektni qisman moklash | spy(repo).when(findById).thenReturn(user) |
Mockito Java va Kotlin da moklash uchun eng mashhur freymvorkdir. mock() orqali moklar yaratish, when().thenReturn() orqali qiymatlarni qaytarishni sozlash va verify() orqali chaqiruvlarni tekshirish imkonini beradi. Mockito ning zamonaviy versiyalari (5.x) statik moklarni (mockStatic) va BDDMockito (given-willReturn) orqali soddalashtirilgan sintaksisni qo‘llab-quvvatlaydi. Muhim qoida: sizga tegishli bo‘lmagan narsani moklamang — qiymat obyektlari va standart kutubxonalar uchun moklar yaratmang.
// Kotlin da Mockito bilan unit test namunasi
class OrderServiceTest {
@Mock
private lateinit var paymentGateway: PaymentGateway
@Mock
private lateinit var userRepository: UserRepository
private lateinit var orderService: OrderService
@BeforeEach
fun init() {
MockitoAnnotations.openMocks(this)
orderService = OrderService(paymentGateway, userRepository)
}
@Test
fun processOrder_whenPaymentFails_shouldThrowException() {
// given
val user = User(id = 1, balance = 100.0)
val order = Order(amount = 200.0)
Mockito.`when`(paymentGateway.charge(any())).thenReturn(false)
Mockito.`when`(userRepository.findById(1)).thenReturn(user)
// when & then
assert Throws<PaymentException> {
orderService.processOrder(user.id, order)
}
// verify
Mockito.verify(paymentGateway).charge(any())
}
}
TDD (Test-Driven Development) — test kodni amalga oshirishdan oldin yoziladigan metodologiya. “Red-Green-Refactor” sikli: muvaffaqiyatsiz test yozing (Red), testdan o‘tish uchun minimal kod yozing (Green), xatti-harakatni o‘zgartirmasdan kodni yaxshilang (Refactor). TDD barcha kod testlar bilan qoplanganligini (yozilgan funksionallik uchun qamrov = 100%) va kodning test qilinishini kafolatlaydi — agar kodni test qilish qiyin bo‘lsa, bu arxitektura yaxshilanishi kerakligini anglatadi.
IBM (2006-2026, uzunlamına tadqiqot) ma’lumotlariga ko‘ra, TDD dan foydalanadigan jamoalar koddan keyin test yozadigan jamoalarga nisbatan ishlab chiqarishda 40-80% kamroq nuqsonlarga yo‘l qo‘yadi. TDD arxitekturani ham yaxshilaydi: dasturchi amalga oshirishdan oldin API dizayni haqida o‘ylashi kerak, bu esa zaif bog‘lanish (loose coupling) va yuqori uyg‘unlikka (high cohesion) olib keladi. Qo‘shimcha ta’sir — jonli kod bilan hujjatlashtirish: testlar modulning har doim dolzarb bo‘lgan xatti-harakat spetsifikatsiyasi sifatida xizmat qiladi.
TDD har doim ham optimal emas. UI komponentlarini ajratilgan holda test qilish qiyin — ular uchun snapshot testlari yoki vizual regressiya testlari (Percy, Chromatic) samaraliroq. Prototiplash va tadqiqot (spike solutions) testlarni talab qilmaydi. Testsiz legacy kodni TDD bilan qoplash qiyin — bu yerda avval refaktoringdan oldin characterization tests (joriy xatti-harakatni qayd qiluvchi testlar) kerak. Bunday hollarda TDD butunlay bekor qilinmaydi, balki moslashtiriladi — butun legacy kod uchun emas, balki o‘zgartirilayotgan funksionallik uchun testlar yoziladi.
Mobil rivojlanish o‘ziga xos xususiyatga ega: biznes mantig’i ko‘pincha UI kod bilan aralashadi (Activity, ViewController, ViewModel), bu unit testlashni qiyinlashtiradi. Eng yaxshi amaliyot — yupqa ko‘rinishlar, qalin ViewModel lar: barcha mantiqni UI komponentlaridan emulatorsiz osongina test qilinadigan alohida sinflarga (UseCase, Repository, ViewModel) ko‘chiring. Android va iOS uchun qurilmani ishga tushirmasdan JVM/Native da ishlaydigan mahalliy unit test freymvorklari mavjud.
Android unit testlari emulatorsiz mahalliy JVM da bajariladi, bu bajarish tezligini ta’minlaydi — odatdagi test 100ms dan kam vaqt oladi. JUnit 5 asosiy runnerdir. ViewModel testlari uchun korutinlarni test qilish uchun kotlinx-coroutines-test va StateFlow ni test qilish uchun Turbine dan foydalaning. Robolectric shadow sinflarni yuklab, Android ga bog‘liq komponentlarni (Context, Resources) emulatorsiz test qilish imkonini beradi. Compose testlari uchun Compose UI Test dan foydalaning — lekin bu allaqachon UI testlari, unit emas.
iOS unit testlari Swift da XCTest bilan (Xcode ga o‘rnatilgan) yoziladi. Quick + Nimble — yanada o‘qiladigan testlar uchun BDD freymvorklari (describe/context/it). Moklash uchun Cuckoo (moklarni generatsiya qilish) yoki SwiftyMocky dan foydalaning. Swift protokollar va dependency injection ni qo‘llab-quvvatlaydi, bu bog‘liqliklarni almashtirishni osonlashtiradi. Asosiy jihat: iOS unit testlari haqiqiy qurilmada emas, balki macOS simulyatorida bajariladi. Uskuna funksiyalarini (kamera, Bluetooth) talab qiladigan testlar — bu integratsion testlar.
Flutter unit testlari flutter_test paketidan foydalanadi va emulatorsiz Dart VM da bajariladi. Moklash uchun mockito paketi kod generatori (build_runner) bilan birga ishlatiladi. Widget testlari (bir xil paketda) alohida vidjetlarni test qiladi, lekin renderlashni talab qiladi va sekinroq ishlaydi — ularni faqat UI mantig’ini tekshirish uchun ishlating. Sof Dart mantig’i (modellar, repozitoriyalar, bloklar) flutter_test ni import qilmasdan oddiy Dart testlari kabi test qilinadi.
// Flutter da mockito bilan unit test namunasi
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
@GenerateMocks([ApiClient])
import 'user_repository_test.mocks.dart';
void main() {
late MockApiClient mockApi;
late UserRepository repository;
setUp(() {
mockApi = MockApiClient();
repository = UserRepository(mockApi);
});
test('fetchUser returns user when API succeeds', () async {
// Arrange
final expectedUser = User(id: 1, name: 'Test');
when(mockApi.getUser(1))
.thenAnswer((_) async => expectedUser);
// Act
final result = await repository.fetchUser(1);
// Assert
expect(result, expectedUser);
verify(mockApi.getUser(1)).called(1);
});
}
Samarali unit testlash intizomni talab qiladi. Asosiy qoida: xatti-harakatni sinang, amalga oshirishni emas. Test modulning ichki qanday amalga oshirilganligini bilmasligi kerak (qanday xususiy metodlar chaqiriladi, qanday tartibda). Agar test amalga oshirishga bog‘liq bo‘lsa, u har bir refaktoringda buziladi va qiymatini yo‘qotadi. Test shartnomani tekshiradi: X kirishida Y chiqishi bo‘lishi kerak. Istisno — chaqiruvlar tartibi muhim bo‘lgan kritik samaradorlikdagi algoritmlar uchun testlar.
100% qamrov — erishib bo‘lmaydigan va keraksiz maqsad. Google Testing Blog (2025) ma’lumotlariga ko‘ra, unit testlar uchun optimal qamrov darajasi kod satrlarining 70-80% ini tashkil qiladi. 100% qamrov ko‘pincha getterlar, setterlar va konstruktorlarni test qilish hisobiga erishiladi, bu qiymat keltirmaydi. Kritik biznes mantig‘iga e’tibor qarating: murakkab hisob-kitoblar, validatsiya, xatolarni boshqarish, chekka holatlar. O‘lchash uchun JaCoCo (Java), Coverage.py (Python), Istanbul (JS) dan foydalaning va CI da chegara belgilang — qamrov 60% dan past bo‘lganda qurilishning buzilishi.
Unit testlar har qanday CI/CD pipeline ning birinchi bosqichidir. Ular har bir push da, qurilish va joylashtirishdan oldin bajariladi. Loyihada unit testlarning o‘rtacha bajarilish vaqti 5 daqiqadan oshmasligi kerak — agar uzoqroq bo‘lsa, testlar “tezkor” bo‘lishdan to‘xtaydi va dasturchilar ularni mahalliy ravishda ishga tushirishni to‘xtatadilar. Testlarni tezkor (unit) va sekin (integratsion) ga ajrating va ularni pipeline ning turli bosqichlarida ishga tushiring. Tezlashtirish uchun parallel bajarish va fail-fast dan foydalaning.
Tez-tez so‘raladigan savollar
Unit test bitta modulni ajratilgan holda tekshiradi, tashqi bog‘liqliklarni moklar bilan almashtiradi. Integratsion test bir nechta real komponentlarning (ma’lumotlar bazasi, API, fayl tizimi) o‘zaro aloqasini tekshiradi. Unit testlar millisekundlarda, integratsion testlar soniyalarda bajariladi. Test piramidasida unit testlar 70% ni egallaydi.
Tanlov platformaga bog‘liq: Java/Kotlin uchun JUnit 5, iOS/Swift uchun XCTest, Python uchun pytest, JavaScript/TypeScript uchun Jest/Vitest, Flutter uchun flutter_test. Moklash uchun Mockito (Java), Cuckoo (iOS), unittest.mock (Python) yoki vitest.mock (JS) dan foydalaning. Barcha zamonaviy freymvorklar parametrlangan testlar, o‘rnatilgan assertlar va parallel ishga tushirishni qo‘llab-quvvatlaydi.
Fast — test millisekundlarda bajariladi. Isolated — boshqa testlar va tashqi tizimlarga bog‘liq emas. Repeatable — har qanday mashinada bir xil natijani beradi. Self-validating — natijani avtomatik tekshiradi. Timely — koddan oldin yoki sinxron yoziladi. Birorta tamoyilning buzilishi test samaradorligini pasaytiradi.
Ha, majburiy. ViewModel biznes mantig‘ini o‘z ichiga oladi — hodisalarni qayta ishlash, ma’lumotlarni transformatsiya qilish, holatni boshqarish. Android da korutinlar uchun kotlinx-coroutines-test va StateFlow ni test qilish uchun Turbine dan foydalaning. iOS da ViewModel da Combine Publishers yoki async/await ni test qiling. ViewModel testlari — emulatorsiz JVM/macOS da ishlaydigan sof unit testlar.
Tarmoq so‘rovlari unit testlarda bajarilmaydi — ular HTTP moklari bilan almashtiriladi. Android da MockWebServer (OkHttp) dan foydalaning — u mahalliy HTTP serverini ishga tushiradi, bu moklardan afzal, chunki real tarmoq o‘zaro aloqasini aks ettiradi. MockWebServer realizmni yo‘qotmasdan ajratishni ta’minlaydi. iOS uchun — javoblarni tutib olish va almashtirish uchun OHHTTPStubs yoki URLProtocol.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.
Shuningdek o'qing