TDD: bu nədir, test prinsipləri və metodologiyası

Müəllif: IT Sectr Dərc olunub: 2026-04-09 Oxuma vaxtı: 9 dəq

Test-Driven Development (TDD) — kodun icrasından əvvəl testlərin yazıldığı inkişaf metodologiyasıdır. Proqramçı əvvəlcə gözlənilən davranışı uğursuz test şəklində formullaşdırır, sonra onu keçmək üçün minimal kod yazır və bundan sonra nəticəni refaktor edir. Martin Fowler (2023)-ə görə, TDD test texnikası deyil — bu, arxitekturanı nizamlayan və kod yazma mərhələsində qüsurların sayını azaldan dizayn texnikasıdır.

Əsas

  • TDD — testin icradan sonra deyil, əvvəl yazıldığı metodologiyadır
  • Red-Green-Refactor dövrü — TDD-nin əsası: qırmızı test, yaşıl test, refaktorinq
  • JUnitMockito — Android inkişafında TDD üçün əsas alətlər
  • Kod əhatəsi TDD layihələrində „hər şeydən əvvəl test" intizamı sayəsində tez-tez 90%-i keçir
  • Refaktorinq funksionallığı pozmaq qorxusu olmadan — TDD yanaşmasının əsas üstünlüyüdür

TDD nədir?

Test-Driven Development — avtomatlaşdırılmış testlərin istehsal kodunun yazılmasını müəyyən etdiyi proqram təminatı inkişaf etdirmə təcrübəsidir. Ənənəvi yanaşmadan fərqli olaraq, kod əvvəlcə yazılır, sonra test edilir, TDD ardıcıllığı tərsinə çevirir: əvvəlcə test yazılır, sonra bu testi keçən kod.

TDD-nin banisi Kent Beck hesab olunur, o, bu təcrübəni 1990-cı illərin sonunda Extreme Programming (XP) metodologiyası çərçivəsində formullaşdırmışdır. „Test-Driven Development: By Example" (2002) kitabında Bek TDD-nin beş qaydasını təsvir etmişdir: istehsal kodundan əvvəl test yaz, testi keçmək üçün lazım olan qədər kod yaz və hər dövrdən sonra refaktor et.

TDD-nin əsas prinsipləri

Birinci prinsip — test interfeysi müəyyən edir. Proqramçı komponentin necə icra edildiyini düşünməzdən əvvəl onun necə istifadə ediləcəyini düşünməyə məcbur olur. Bu, ən əvvəldən təmiz API formalaşdırır.

Dizayn texnikası kimi TDD

İkinci prinsip — minimal icra. Test yazıldıqda, proqramçı onu keçmək üçün lazım olan qədər istehsal kodu yazır — bir sətir də artıq deyil. Bu, Martin Fowlerin Speculative Generality adlandırdığı vaxtından əvvəl abstraksiyanın və həddindən artıq mürəkkəbliyin qarşısını alır.

TDD-nin adi testdən fərqi

TDD ilə „fakt sonra" test arasındakı əsas fərq — ardıcıllıq intizamıdır. TDD-də test təkcə kodu yoxlamır — onun strukturunu istiqamətləndirir. Microsoft Research (Nagappan et al., 2008) tədqiqatına görə, TDD tətbiq edən komandalar ənənəvi yanaşma istifadə edən komandalarla müqayisədə qüsur sıxlığını 40–90% azaldır.

Red-Green-Refactor dövrü

Red-Green-Refactor dövrü — hər yeni test üçün təkrarlanan üç addımlı ardıcıllıqdır. Red: keçməyən test yaz. Green: testi keçmək üçün minimal kod yaz. Refactor: davranışını dəyişmədən kodu təkmilləşdir.

Red mərhələsi: uğursuz testin yazılması

Proqramçı hələ icra edilməmiş funksionallığı yoxlayan test yazır. Bu mərhələdə test uğursuz olmalıdır — bu, testin həqiqətən nəyisə yoxladığını təsdiqləyir. Android inkişaf mühitində JUnit 5 freymvorku uğursuz testlər üçün qırmızı göstərici göstərir, bu da mərhələyə adını vermişdir.

kotlin
class CalculatorTest {
    fun testAddition() {
        val result = Calculator().add(2, 3)
        Assertions.assertEquals(5, result)
    }
}

Green mərhələsi: minimal icra

Bu mərhələdə testi keçmək üçün kifayət edən minimal istehsal kodu yazılır. Heç bir artıqlıq — yalnız yaşıl göstərici üçün lazım olan. İcra sabit ola bilərsə — qoy sabit olsun. Refaktorinq yeni testlər görünəndə növbəti addımda baş verəcək.

kotlin
class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}

Refactor mərhələsi: risksiz təkmilləşdirmə

Yaşıl test refaktorinq üçün sığortadır. Proqramçı icranı yenidən yaza, performansı optimallaşdıra və ya oxunaqlılığı yaxşılaşdıra bilər, əmin olaraq ki, test gözlənilən davranışdan hər hansı bir kənarlaşmanı dərhal aşkarlayacaq. Android-də mobil inkişafda bu mərhələ ümumi interfeysləri ayırmaq və kod təkrarlanmasını azaltmaq üçün xüsusilə vacibdir.

TDD-nin mobil inkişafda üstünlükləri

TDD-nin mobil layihələrdə tətbiqi həm akademik tədqiqatlarla, həm də aparıcı inkişaf studiyalarının təcrübəsi ilə təsdiqlənmiş ölçülə bilən üstünlüklər verir.

Qüsur sıxlığının azaldılması

IBM (Bhat & Nagappan, 2006) tərəfindən dörd sənaye layihəsində aparılan tədqiqat göstərdi ki, TDD istifadə edən komandalar ənənəvi sxem üzrə işləyən oxşar komandalarla müqayisədə 40% az qüsur buraxır. Google Play-də buraxılışdan sonra səhvin düzəltmə dəyərinin kod yazma mərhələsindən əhəmiyyətli dərəcədə yüksək olduğu mobil inkişaf üçün bu metrik kritikdir.

Kodun testlər vasitəsilə sənədləşdirilməsi

TDD-ə uyğun yazılmış testlər API-nin canlı sənədləşməsi kimi xidmət edir. Layihəyə gələn proqramçı testləri oxuya və hər bir komponentin necə istifadə edilməli olduğunu başa düşə bilər. Bu, mobil studiyaların tipik problemi olan yüksək kadr dəyişkənliyi şəraitində xüsusilə dəyərlidir.

Etibarlı refaktorinq

90%-dən çox kod əhatəsi proqramçılara nəyisə pozmaq qorxusu olmadan refaktorinq aparmağa imkan verir. Google „Software Engineering at Google" (2020) kitabında test əhatəsini milyonlarla sətir kod olan layihələrdə kod bazasını təmiz saxlamağa imkan verən əsas amil adlandırır.

TDD üçün alətlər və freymvorklar

Mobil inkişafda TDD ekosisteminə vahid testlər, mocking və UI komponentlərinin yoxlanılması üçün alətlər daxildir — həm Android, həm də iOS üçün.

AlətPlatformaTəyinat
JUnit 5Android (Kotlin/Java)Vahid testlər üçün əsas freymvork
MockitoAndroidMock-obyektlərin yaradılması və çağırışların yoxlanılması
MockKAndroid (Kotlin)Kotlin-first sintaksisi və korutin dəstəyi ilə mocking
TurbineAndroidKotlin Flow və reaktiv axınların test edilməsi
XCTestiOS (Swift)Standart test freymvorku

Android üçün freymvork seçimi

Kotlin-də Android layihələri üçün standart yığma JUnit 5 + MockK daxildir. MockK Mockito-dan üstün tutulur, çünki əlavə konfiqurasiya olmadan Kotlin birinci dərəcəli funksiyalarını — sealed class, korutinlər və suspend-funksiyaları dəstəkləyir.

iOS üçün alətlər

iOS inkişafında TDD XCTest vasitəsilə icra olunur — Apple-ın daxili freymvorku, asertlər, test sinifləri və CI/CD ilə Xcode Server və ya GitHub Actions vasitəsilə inteqrasiya təmin edir. iOS-da mocking üçün Cuckoo və OHHTTPStubs kitabxanaları istifadə olunur.

Kotlin dilində TDD kod nümunələri

Android üçün Kotlin dilində real TDD ssenarisini nəzərdən keçirək — istifadəçi repozitoriyasının test edilməsi. Əvvəlcə test yazırıq, sonra — bu testi keçən icra.

Addım 1: UserRepository üçün test

kotlin
class UserRepositoryTest {
    private val api = mockk<UserApi>()
    private val dao = mockk<UserDao>()
    private val repo = UserRepository(api, dao)

    fun `when api returns user then cache and emit`() = runTest {
        val user = User(1, "Alice")
        coEvery { api.getUser(1) } returns user
        every { dao.insert(user) } returns Unit

        val result = repo.getUser(1)

        assertEquals(user, result)
        verify { dao.insert(user) }
    }
}

Addım 2: minimal icra

kotlin
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUser(id: Int): User {
        val user = api.getUser(id)
        dao.insert(user)
        return user
    }
}

Addım 3: oflayn rejimlə keşləmə testi

Birinci testi keçdikdən sonra ikincini əlavə edirik — şəbəkə xətası zamanı davranışı yoxlayırıq. İndi test müəyyən edir ki, API uğursuz olduqda repozitoriya keşdən məlumatları qaytarmalıdır.

kotlin
fun `when api fails then return cached user`() = runTest {
    val cached = User(1, "Cached Alice")
    coEvery { api.getUser(1) } throws IOException()
    every { dao.getById(1) } returns cached

    val result = repo.getUser(1)

    assertEquals(cached, result)
}

TDD tətbiqində tipik səhvlər

TDD-yə keçid metodologiyanın bütün üstünlüklərini heçə endirə bilən tipik səhvlərlə müşayiət olunur. Bu tələləri başa düşmək komandalara təcrübəni daha səmərəli tətbiq etməyə kömək edir.

Çox böyük testlər

Birinci və ən geniş yayılmış anti-nümunə — bir testdə çox böyük həcmdə funksionallığın test edilməsi. Test tam olaraq bir ifadəni (bir asert) yoxlamalıdır. Test uğursuz olarsa, proqramçı əlavə debug etmədən nəyin pozulduğunu bilməlidir.

Qırmızı mərhələnin göz ardı edilməsi

İkinci səhv — əvvəldən keçən testin yazılması. Test heç olmasa bir dəfə qırmızı olmayıbsa, onun ümumiyyətlə nəyisə yoxladığına əminlik yoxdur. Qayda: uğursuz olduğunu görmədiyin teste heç vaxt güvənmə.

Refaktorinqin buraxılması

Üçüncü tipik səhv — yaşıl mərhələdə dayanmaqdır. Refaktorinq dövrün isteğe bağlı deyil, məcburi mərhələsidir. Onsuz kod bazası deqradasiyaya uğrayır, testlər kövrək olur və TDD-nin üstünlükləri itir.

  • İcranın yoxlanılması, davranışın deyil — testlər detallara bağlanır və hər refaktorinqdə pozulur
  • Kənar hallar üçün testlərin olmaması — boş siyahılar, null dəyərlər, sərhəd şərtləri örtülməmiş qalır
  • Test sürətinin göz ardı edilməsi — yavaş testlər geribildirim dövrünü ləngidir və TDD intizamını öldürür

Tez-tez verilən suallar

TDD — test yoxsa dizayn texnikası?

TDD ilk növbədə dizayn texnikasıdır, test texnikası deyil. TDD-də testlər spesifikasiya rolunu oynayır: onlar komponentin API-ni onun icrasından əvvəl müəyyən edir. Kent Beck-in özü TDD-ni „dizayn intizamı, test intizamı deyil" adlandırır.

TDD-ni mənimsəmək nə qədər vaxt aparır?

Microsoft Research tədqiqatlarına görə, TDD-nin vərdiş halına gəlməsi üçün komandalara 3 aydan 6 aya qədər fasiləsiz təcrübə lazımdır. İlk 2–3 həftə məhsuldarlıq 15–30% düşür, lakin adaptasiyadan sonra debug vaxtının qısalması hesabına ilkin səviyyəyə qayıdır və ya onu üstələyir.

TDD UI komponentləri üçün uyğundurmu?

Bəli, lakin məhdudiyyətlərlə. UI məntiqi (ViewModel, State) üçün TDD birbaşa tətbiq olunur. Vizual komponentlər (Compose UI, SwiftUI Views) üçün ekran görüntüsü testi (snapshot testing) TDD-ni tamamlayır, lakin onu əvəz etmir. Biznes məntiqini və təqdimatı ayırmaq tövsiyə olunur.

TDD legacy layihələrdə tətbiq oluna bilərmi?

Legacy kod üçün „xarakterizasiya testləri" (characterization tests) strategiyası tövsiyə olunur — testlər mövcud davranışa yazılır, sonra kod refaktor edilir. Michael Feathers-in „Working Effectively with Legacy Code" (2004) kitabında təsvir edilən bu yanaşma TDD-ni mərhələli şəkildə tətbiq etməyə imkan verir.

TDD Clean Architecture ilə necə uyğunlaşır?

TDD və Clean Architecture bir-birini gücləndirir. Təmiz arxitektura təbəqələr arasında aydın sərhədlər tələb edir, TDD isə proqramçını bu sərhədləri testlər vasitəsilə dizayn etməyə məcbur edir. Domen təbəqəsi mock-asılılıqlarla izolyasiya olunmuş şəkildə test edilir, məlumat təbəqəsi — inteqrasiya testləri vasitəsilə.

Nəticə

  • TDD — testin icradan əvvəl yazıldığı, təmiz API formalaşdıran və arxitekturanı istiqamətləndirən metodologiyadır
  • Red-Green-Refactor dövrü — TDD-nin əsas vahidi: uğursuz test → minimal icra → refaktorinq
  • TDD tətbiqi IBM və Microsoft Research tədqiqatlarına görə qüsur sıxlığını 40–90% azaldır
  • Android inkişafı üçün əsas alətlər: JUnit 5, MockK, Flow üçün Turbine
  • MockK Kotlin layihələrində korutin və sealed class dəstəyi sayəsində Mockito-dan üstün tutulur
  • Tipik səhvlər: çox böyük testlər, qırmızı mərhələnin buraxılması, refaktorinqin göz ardı edilməsi
  • Tövsiyə olunan tətbiq strategiyası — mərhələli, domen təbəqəsindən və yeni xüsusiyyətlərdən başlayaraq, bütün legacy kodu bir anda əhatə etməyə çalışmadan

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun