Testing nima uchun kerak, qanday turlari bor
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:
- Arrange (tayyorlash) — ma'lumotlar, komponentni render qilish
- Act (harakat) — funksiyani chaqirish, tugmani bosish
- 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:
undefinedning xususiyatini o'qish, noto'g'ri props - ESLint — shubhali kod:
useEffectbog'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
stateni 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:
- Pul va ma'lumot bilan bog'liq: to'lov, narx hisoblash, buyurtma, ro'yxatdan o'tish
- Murakkab mantiq: hisob-kitoblar, formatlash, validatsiya, holat mashinalari
- Tez-tez buziladigan joylar — har bir topilgan xato uchun test yozing, u qaytmasin
- 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