Testing nima uchun kerak, qanday turlari bor

~10 daq · React · Testing

Muammodan boshlaylik

Juma kuni kechqurun. Siz savat sahifasida chegirma hisoblashni biroz o'zgartirdingiz. Brauzerda tekshirdingiz — chegirma to'g'ri. Deploy.

Dushanba kuni: "Buyurtma berish tugmasi ishlamayapti!" — bir kun davomida hech kim buyurtma bera olmagan. Sabab: siz o'zgartirgan funksiya boshqa joyda ham ishlatilardi, va u yerda yangi xatti-harakat formani buzgan edi. Siz uni tekshirmagan edingiz — chunki u yerda o'zgarish kutilmagan.

Qo'lda tekshirish ikki muammoga ega:

  • Sekin — har o'zgarishdan keyin 50 ta sahifani bosib chiqish mumkin emas
  • Ishonchsiz — biz faqat o'zgartirgan joyni tekshiramiz, "boshqa joyda buzilgan" narsani emas

Avtomatik testlar — kod qanday ishlashi kerakligini tekshiradigan kod. Ular bir necha soniyada yuzlab holatni tekshiradi, har safar, charchamasdan.


Test qanday ko'rinadi

import { describe, it, expect } from 'vitest';
import { chegirmaHisobla } from './narx';

describe('chegirmaHisobla', () => {
  it('10% chegirmani to\'g\'ri hisoblaydi', () => {
    expect(chegirmaHisobla(100_000, 10)).toBe(90_000);
  });

  it('chegirma 100% dan oshmaydi', () => {
    expect(chegirmaHisobla(100_000, 150)).toBe(0);
  });

  it('manfiy narxda xato beradi', () => {
    expect(() => chegirmaHisobla(-5, 10)).toThrow();
  });
});
✓ chegirmaHisobla > 10% chegirmani to'g'ri hisoblaydi
✓ chegirmaHisobla > chegirma 100% dan oshmaydi
✓ chegirmaHisobla > manfiy narxda xato beradi

Test Files  1 passed (1)
     Tests  3 passed (3)

Uch qism — AAA:

  1. Arrange (tayyorlash) — ma'lumotlar, komponentni render qilish
  2. Act (harakat) — funksiyani chaqirish, tugmani bosish
  3. Assert (tekshirish) — natija kutilganday mi

Test turlari

1. Unit test — bitta bo'lak

Bitta funksiya, hook yoki kichik komponentni alohida tekshiradi.

expect(formatNarx(1500000)).toBe("1 500 000 so'm");
  • ⚡ Juda tez — millisoniyalar
  • 🎯 Xato qayerda ekanini aniq ko'rsatadi
  • ⚠ Qismlar birga ishlashini tekshirmaydi

2. Integration test — bir nechta bo'lak birga

Bir nechta komponent, hook va (soxta) API ning birgalikda ishlashini tekshiradi:

"Foydalanuvchi mahsulotni savatga qo'shsa,
 header dagi savat belgisi 1 ga oshadi
 va savat sahifasida mahsulot ko'rinadi"
  • ⚡ Tez — soniyalar
  • 🎯 Foydalanuvchi ssenariylariga yaqin
  • React ilovalarida eng foydali test turi

3. End-to-End (E2E) test — butun tizim

Haqiqiy brauzerda, haqiqiy (yoki test) server bilan, foydalanuvchi kabi: sahifani ochadi, bosadi, yozadi.

// Playwright
test('mehmon buyurtma bera oladi', async ({ page }) => {
  await page.goto('/katalog');
  await page.getByRole('button', { name: 'Savatga' }).first().click();
  await page.getByRole('link', { name: /Savat/ }).click();
  await page.getByRole('button', { name: 'Buyurtma berish' }).click();
  await expect(page.getByText('Buyurtmangiz qabul qilindi')).toBeVisible();
});
  • 🐢 Sekin — har biri soniyalar yoki daqiqalar
  • 🎯 Eng ishonchli: "ilova haqiqatan ishlaydimi?"
  • ⚠ Mo'rt — tarmoq, vaqt, animatsiyalar tufayli tasodifan yiqilishi mumkin
  • Vositalar: Playwright, Cypress

4. Statik tekshiruv

Kod ishga tushmasdan oldin xatolarni topadi:

  • TypeScript — tur xatolari: undefined ning xususiyatini o'qish, noto'g'ri props
  • ESLint — shubhali kod: useEffect bog'liqliklari, ishlatilmagan o'zgaruvchilar

Eng arzon "test" — u allaqachon kod yozayotganda ishlaydi.


Test sinovlari "kubogi"

         ╱‾‾‾‾‾‾╲
        ╱  E2E   ╲         ← oz: eng muhim ssenariylar (login, to'lov)
       ├──────────┤
      ╱            ╲
     │ Integration │       ← ko'p: asosiy e'tibor shu yerda
      ╲            ╱
       ├──────────┤
       │   Unit   │        ← murakkab mantiq: hisob-kitob, formatlash
       ├──────────┤
       │  Statik  │        ← TypeScript + ESLint — hamma joyda
       ╰──────────╯

Bu "Testing Trophy" (Kent C. Dodds) deb ataladi. Asosiy g'oya: ishonchni eng arzon narxda olish. Integration testlar — foydalanuvchi ssenariylariga yaqin, lekin tez — eng yaxshi muvozanat.


Nimani tekshirish kerak

✅ Xatti-harakatni — foydalanuvchi ko'radigan natijani

// ✅ foydalanuvchi nima ko'radi
await user.click(screen.getByRole('button', { name: "Savatga" }));
expect(screen.getByText('Savatda: 1')).toBeInTheDocument();

❌ Ichki tafsilotlarni — implementatsiyani

// ❌ komponent ichida nima bo'layotgani
expect(component.state.savat.length).toBe(1);
expect(setSavat).toHaveBeenCalledWith([...]);

Nima uchun? Agar siz useState ni Zustand ga almashtirsangiz:

  • ❌ ichki tafsilotni tekshiradigan test yiqiladi — garchi ilova to'g'ri ishlasa ham
  • ✅ xatti-harakatni tekshiradigan test o'tadi — chunki foydalanuvchi uchun hech narsa o'zgarmadi

Yaxshi test — refactoring dan qo'rqmaslik imkonini beradi, unga to'sqinlik qilmaydi.

[!TIP] React Testing Library ning asosiy tamoyili: "Testlaringiz dasturingiz qanday ishlatilishiga qanchalik o'xshasa, ular sizga shunchalik ko'p ishonch beradi." Foydalanuvchi state ni ko'rmaydi — u tugmalarni, matnni, formalarni ko'radi. Testlar ham shularni ko'rsin.


Qancha test yozish kerak

100% coverage (har bir qatorni tekshirish) — maqsad emas. U ko'pincha ma'nosiz testlarga olib keladi: "getter qiymat qaytaradimi?".

Ustuvorlik:

  1. Pul va ma'lumot bilan bog'liq: to'lov, narx hisoblash, buyurtma, ro'yxatdan o'tish
  2. Murakkab mantiq: hisob-kitoblar, formatlash, validatsiya, holat mashinalari
  3. Tez-tez buziladigan joylar — har bir topilgan xato uchun test yozing, u qaytmasin
  4. Asosiy foydalanuvchi ssenariylari

Oddiy, mantiqsiz komponentlar (faqat props ni ko'rsatadi) — ko'pincha test shart emas.


Keyingi darslarda

Vosita Vazifasi Dars
Vitest Test ishga tushiruvchi: describe, it, expect, mock lar 74
React Testing Library Komponentlarni render qilish va foydalanuvchi kabi ishlatish 75–77
MSW API ni soxtalashtirish — haqiqiy server siz 78

Nima uchun shunday?

Nima uchun testlar yozish "qo'shimcha ish" emas, balki vaqtni tejaydi?

Chunki xatoni topish narxi u qachon topilganiga bog'liq. Kod yozayotganda topilgan xato — bir daqiqa. Code review da — bir soat (kontekstni eslash kerak). Production da — kunlar: foydalanuvchilar shikoyati, yo'qotilgan buyurtmalar, tunda shoshilinch tuzatish, va har bir qo'lda tekshirish. Testlar xatolarni eng arzon nuqtada ushlaydi. Ikkinchi, kamroq ko'rinadigan foyda — jasorat: testlar bilan himoyalangan kodni bemalol yaxshilash, qayta yozish, kutubxonalarni yangilash mumkin. Testsiz loyihada esa dasturchilar eski kodga tegishdan qo'rqadi — va kod yildan yilga yomonlashadi.


Xulosa

Eslab qoling:

  • Avtomatik testlar — tez, ishonchli, har safar; qo'lda tekshirish "boshqa joydagi" xatolarni o'tkazib yuboradi
  • AAA: Arrange → Act → Assert
  • Turlar: statik (TS, ESLint), unit, integration (eng foydali), E2E (eng muhim ssenariylar)
  • Xatti-harakatni tekshiring, ichki tafsilotlarni emas — refactoring testlarni buzmasin
  • Maqsad — ishonch, 100% coverage emas; pul, mantiq va topilgan xatolar — birinchi navbatda
  • Vositalar: Vitest, React Testing Library, MSW, Playwright

Keyingi dars

74-dars: Vitest — o'rnatish, birinchi test