Testlash (Jest)

Nega test yozamiz?

Kod yozish — ishning yarmi. Ikkinchi yarmi esa kod haqiqatan ishlayotganini va kelajakda ham ishlashda davom etishini ta'minlashdir. Aynan shu joyda testlash sahnaga chiqadi. Bu darsda testlashning nima ekanini, nega u zamonaviy dasturchi uchun majburiy ko'nikma bo'lganini va qanday test turlari mavjudligini chuqur ko'rib chiqamiz.

Qo'lda testlash muammosi

Ko'pchilik dasturchi ishni shunday boshlaydi: funksiya yozadi, so'ng console.log qo'yib, natijani ko'zi bilan tekshiradi. Yoki brauzerni ochib, tugmani bosib, hammasi joyida ekanini qo'lda ko'radi. Bu qo'lda testlash deyiladi.

function narxHisobla(soni, narx) {
  return soni * narx;
}

// Qo'lda tekshiruv:
console.log(narxHisobla(3, 100)); // 300 chiqishi kerak, ko'z bilan tekshiramiz
console.log(narxHisobla(0, 100)); // 0 chiqishi kerak

Kichik funksiya uchun bu yetarli ko'rinadi. Ammo dastur o'sib borgani sari qo'lda testlash tez orada jiddiy muammoga aylanadi:

Eng xavfli holat — regressiya: siz bitta joyni tuzatasiz, lekin bilmagan holda boshqa joyni buzasiz. Qo'lda testlashda buzilgan joy foydalanuvchiga yetib borgach ma'lum bo'ladi.

Avtomatik test nima beradi?

Avtomatik test — bu sizning kodingizni tekshiradigan yana bir kod. Ya'ni siz bir marta test yozasiz, so'ng uni cheksiz marta, bir soniyada, xatosiz ishga tushirasiz. Yuqoridagi funksiyani avtomatik test bilan quyidagicha tekshiramiz:

function narxHisobla(soni, narx) {
  return soni * narx;
}

test('3 ta mahsulot narxini hisoblaydi', () => {
  expect(narxHisobla(3, 100)).toBe(300);
});

test('0 ta mahsulot uchun 0 qaytaradi', () => {
  expect(narxHisobla(0, 100)).toBe(0);
});

Endi console.log natijasini ko'z bilan solishtirish shart emas — agar natija kutilganidan farq qilsa, test o'zi qizil rangda xatoni ko'rsatadi. Bu bizga aniq foydalar beradi:

Test yozishning maqsadi — testlar sonini ko'paytirish emas, balki kodga bo'lgan ishonchni oshirish. Har bir test biror haqiqatni himoya qilishi kerak.

Test turlari

Barcha testlar bir xil emas. Ular nimani va qanchalik keng tekshirishiga qarab uch asosiy turga bo'linadi.

Unit (birlik) testlar

Eng kichik va tez testlar. Bitta funksiya yoki bitta modulni yakka holda, boshqa qismlardan ajratib tekshiradi. Masalan, yuqoridagi narxHisobla uchun yozilgan testlar — bu unit testlar. Ular tez ishlaydi va xato qayerdaligini aniq ko'rsatadi.

Integration (integratsiya) testlar

Bir nechta qism birga qanday ishlashini tekshiradi. Masalan, ma'lumotlar bazasidan ma'lumot o'qib, uni qayta ishlab, javob qaytaradigan funksiyalar zanjiri. Ular unit testlardan sekinroq, ammo real hayotga yaqinroq.

End-to-end (E2E) testlar

Butun dasturni foydalanuvchi ko'zi bilan tekshiradi: brauzer ochiladi, tugmalar bosiladi, formalar to'ldiriladi va natija ko'riladi. Eng ishonchli, ammo eng sekin va eng mo'rt (tez sinuvchan) test turi. Bunga Cypress yoki Playwright kabi vositalar ishlatiladi.

Test piramidasi

Qaysi test turidan qanchasini yozish kerak? Bu savolga test piramidasi javob beradi. Bu Mike Cohn tomonidan mashhur qilingan tamoyil:

        /\
       /  \      E2E  — kam (sekin, qimmat, mo'rt)
      /----\
     /      \    Integration — o'rtacha
    /--------\
   /          \  Unit — ko'p (tez, arzon, barqaror)
  /____________\

Tamoyil oddiy: ko'p sonli tez unit testlar, o'rtacha integratsiya testlar va oz sonli E2E testlar yozing. Chunki unit testlar arzon va tez, E2E testlar esa qimmat va sekin. Piramida teskari bo'lib qolsa (ko'p E2E, kam unit), test to'plami sekin va ishonchsiz bo'ladi.

Amaliyotda odatda taxminan 70% unit, 20% integration va 10% E2E test nisbati sog'lom hisoblanadi. Bu qat'iy qoida emas, balki yo'nalish.

TDD tushunchasi

TDD (Test-Driven Development) — bu kod yozishdan oldin testni yozadigan yondashuv. U uch qadamdan iborat va "qizil–yashil–refaktoring" tsikli deb ataladi:

  1. Qizil (Red): hali mavjud bo'lmagan funksiya uchun test yozasiz — u albatta yiqiladi (qizil).
  2. Yashil (Green): testni o'tkazadigan eng oddiy kodni yozasiz — test yashil bo'ladi.
  3. Refaktoring (Refactor): testlar yashil turgan holda kodni tozalaysiz, yaxshilaysiz.
// 1-qadam (Qizil): funksiya hali yo'q, test yozamiz
test('juft sonni aniqlaydi', () => {
  expect(juftmi(4)).toBe(true);
  expect(juftmi(5)).toBe(false);
});

// 2-qadam (Yashil): eng oddiy ishlaydigan kod
function juftmi(son) {
  return son % 2 === 0;
}

// 3-qadam (Refaktoring): kerak bo'lsa tozalash, test hali ham yashil

TDD dizaynni yaxshilaydi (kodni ishlatib ko'rib yozganingiz uchun qulay interfeys chiqadi) va har bir kod satri test bilan qoplanishini ta'minlaydi. Ammo bu majburiy emas — testni kod bilan birga yoki keyin yozish ham to'liq maqbul.

Mashhur vositalar

JavaScript dunyosida bir nechta test freymvorki keng tarqalgan:

Yangi loyiha uchun Jest yoki Vitest — eng xavfsiz tanlov. Ikkalasi ham API va falsafada juda o'xshash, birini o'rgansangiz ikkinchisi bepul keladi.

Xulosa