Asosiy kontentga o‘tish
Innovialabs

Legacy kodni testlar bilan qoplash: xarakterlovchi testlar va choklar

Chuqur3 daq

Qisqacha

Avval joriy xatti-harakatni xarakterlovchi yoki snapshot testlar bilan qayd eting, so‘ng choklar orqali baza, tarmoq va vaqtni ajrating va shundan keyingina kodni kichik tekshirilgan qadamlarda o‘zgartiring.

Asosiy g‘oya

Legacy kodda darhol «qanday bo‘lishi kerak» degan testlarni yozib bo‘lmaydi: qanday bo‘lishi kerakligini hech kim aniq bilmaydi, kod esa allaqachon foydalanuvchilarda ishlayapti. Shuning uchun tartib boshqacha:

  1. Joriy xatti-harakatni qayd etish — hatto g‘alati bo‘lsa ham.
  2. Kodni baza, tarmoq, vaqt va fayllardan ajratish uchun choklarni topish.
  3. Kodni kichik qadamlarda o‘zgartirish, har biridan keyin testlarni ishga tushirish.

Birinchi testlarning maqsadi to‘g‘rilikni isbotlash emas, signalizatsiya o‘rnatish: xatti-harakat o‘zgarsa, buni darhol bilasiz.

Xarakterlovchi testlar

Xarakterlovchi test (characterization test) kod hozir nima qilayotganini tasvirlaydi. Usul oddiy:

  1. Funksiyani real kirish ma’lumotlari bilan chaqiring.
  2. Ataylab noto‘g‘ri kutilgan qiymat bilan tekshiruv yozing.
  3. Testni ishga tushiring, haqiqiy natijani ko‘ring va uni kutilgan qiymatga qo‘ying.

Agar natija xatoga o‘xshasa, uni darhol tuzatmang. Testni qoldiring, izoh qo‘shing va vazifa oching: xatoni tuzatish — alohida, ongli o‘zgarish.

Turli tarmoqlardan o‘tadigan kirishlarni tanlang. Qamrov hisoboti (coverage) qaysi tarmoqlar hali tegilmaganini ko‘rsatadi.

Snapshot va approval testing

Natija katta bo‘lsa — HTML, JSON, hisobot, matn ko‘rinishidagi PDF — kutilgan qiymatlarni qo‘lda yozish uzoq davom etadi. Bu yerda yordam beradi:

  • Snapshot testlar — Jest toMatchSnapshot, Python’da masalan syrupy. Birinchi ishga tushirish natijani saqlaydi, keyingilari u bilan solishtiradi.
  • Approval testing — ApprovalTests oilasidagi kutubxonalar. Natija received fayliga yoziladi, siz diff’ni ko‘rib chiqasiz va uni «tasdiqlab», approved ga aylantirasiz.
  • Golden master — ko‘plab kirishlarni (masalan, shaxsiy ma’lumotlardan tozalangan real ma’lumotlar eksportini) ishga tushirish va barcha chiqishlarni saqlash.

Snapshot’ga o‘zgaruvchan ma’lumotlar tushmasligini kuzating: joriy vaqt, tasodifiy ID’lar, kalitlar tartibi. Ularni almashtirish yoki normallashtirish kerak, aks holda testlar «miltillaydi».

Choklar va bog‘liqliklarni uzish

Chok (seam) — kodni aynan o‘sha joyda tahrirlamasdan uning xatti-harakatini o‘zgartirish mumkin bo‘lgan joy. Asosiy turlari:

ChokQanday ko‘rinadi
Obyektlikonstruktor yoki funksiyaga boshqa obyekt uzatish
Modulliimportni almashtirish: jest.mock, pytest’dagi monkeypatch
Konfiguratsiontestlar uchun boshqa baza URL’i yoki muhit bayrog‘i

Odatiy legacy kod bog‘liqliklarni o‘zi tortib oladi:

def send_reminders():
    for inv in db.query_unpaid():
        if inv.due_date < datetime.now() - timedelta(days=7):
            mailer.send(inv.email, render(inv))

Xavfsiz usul — parametrlarni ajratib olish va chaqiruvchi kodga tegmaslik uchun eski funksiyani o‘ram sifatida qoldirish:

def send_reminders_core(invoices, now, send):
    for inv in invoices:
        if inv.due_date < now - timedelta(days=7):
            send(inv.email, render(inv))

def send_reminders():
    send_reminders_core(db.query_unpaid(), datetime.now(), mailer.send)

Endi send_reminders_core ni xotiradagi ro‘yxat, qat’iy sana va soxta yuborish funksiyasi bilan testlash mumkin. Bunday mexanik qadamlarni IDE vositalari bilan bajaring — avtomatik refaktoringda xato ehtimoli kamroq.

Yana ikki foydali usul:

  • Sprout method — yangi mantiqni testlari bor alohida funksiyada yozing va uni eski koddan chaqiring.
  • Wrap method — eski funksiyani undan oldin yoki keyin xatti-harakat qo‘shadigan yangi funksiya bilan o‘rang.

Kichik qadamlarda refaktoring

  • Bitta o‘zgarish — bitta test ishga tushirish — bitta commit.
  • Refaktoring va xatti-harakat o‘zgarishini bitta commit’da aralashtirmang.
  • Test yiqilsa va sababi tushunarsiz bo‘lsa, oldinga tuzatmang, orqaga qayting.
  • Kod tushunarliroq bo‘lgani sari snapshot’larni mazmunli tekshiruvli aniq unit-testlar bilan almashtiring.
  • Butun loyihadan emas, eng ko‘p o‘zgaradigan yoki buziladigan qismlardan boshlang.

Keng tarqalgan xatolar

  • Testlar paydo bo‘lishidan oldin «yo‘l-yo‘lakay» katta refaktoring.
  • Ko‘rib chiqilmasdan yangilanadigan snapshot’lar — ular hech narsani himoya qilmaydi.
  • Har bir chaqiruv uchun mock’lar, natijada test implementatsiyani takrorlaydi va har qanday tahrirdan buziladi.

Ko‘p beriladigan savollar

Bir daraja yuqoridan boshlang: xatti-harakatni tashqaridan qayd etadigan end-to-end yoki API test. U sekinroq, lekin birinchi choklarni xavfsiz kiritish va keyin unit-testlarga tushish imkonini beradi.

Yana o‘qing

G‘oya yoki vazifangiz bormi? Bizga aytib bering

Ish kuni davomida javob beramiz va yechim taklif qilamiz. Konsultatsiya bepul.