Coverage va yaxshi amaliyot
Test yozishni bilish โ bir masala, yaxshi test yozish โ boshqa masala. Bu darsda kod qamrovini o'lchash, testlarni to'g'ri tuzilish namunasida yozish va qaysi holatlarni tekshirish kerakligini o'rganamiz.
Kod qamrovi (coverage)
Coverage (qamrov) โ bu testlaringiz kodning qancha qismini ishga tushirganini ko'rsatadigan o'lchov. Jest buni --coverage bayrog'i bilan hisoblab beradi:
npx jest --coverage
# package.json scripts'iga qo'shsa ham bo'ladi:
# "test:coverage": "jest --coverage"
Natijada jadval chiqadi. U to'rt ustunni ko'rsatadi:
-----------|---------|----------|---------|---------|
File | % Stmts | % Branch | % Funcs | % Lines |
-----------|---------|----------|---------|---------|
narx.js | 100 | 80 | 100 | 100 |
-----------|---------|----------|---------|---------|
- % Stmts โ bajarilgan operatorlar (statements) ulushi.
- % Branch โ tekshirilgan tarmoqlar (masalan
if/elseikkala yo'li). - % Funcs โ chaqirilgan funksiyalar ulushi.
- % Lines โ ishga tushgan satrlar ulushi.
ifning ham rost, ham yolg'on yo'llari tekshirilganini ko'rsatadi. Ko'p yashirin xatolar aynan tekshirilmagan tarmoqlarda yashiringan bo'ladi.AAA namunasi
Yaxshi test aniq tuzilishga ega bo'lishi kerak. Eng ommabop namuna โ AAA (Arrange-Act-Assert), ya'ni Tayyorla-Bajar-Tekshir. Har bir test uch qismga bo'linadi:
- Arrange (Tayyorla): kerakli ma'lumot va holatni tayyorlaysiz.
- Act (Bajar): tekshirilayotgan funksiyani bir marta chaqirasiz.
- Assert (Tekshir): natija kutilganidek ekanini tekshirasiz.
test('savatdagi mahsulotlar umumiy narxini hisoblaydi', () => {
// Arrange โ tayyorlash
const savat = [
{ nom: 'olma', narx: 100, soni: 2 },
{ nom: 'nok', narx: 200, soni: 1 }
];
// Act โ bajarish
const jami = umumiyNarx(savat);
// Assert โ tekshirish
expect(jami).toBe(400);
});
Nimani test qilish kerak?
Hamma narsani testlash kerak emas. Diqqatni eng ko'p xato yashiringan joylarga qarating:
- Oddiy holat (happy path): hamma narsa to'g'ri bo'lganda funksiya kutilgan natijani berishi.
- Chegaraviy holatlar (edge cases): bo'sh massiv, 0, manfiy son, juda katta qiymat, bitta element.
- Xato holatlar: noto'g'ri kirish,
null,undefined, xato tashlanishi kerak bo'lgan joylar. - Muhim biznes mantiq: narx hisoblash, chegirmalar, ruxsatlar kabi pul yoki xavfsizlikka aloqador qismlar.
Aksincha, bularni odatda alohida testlashning ma'nosi kam:
- Tashqi kutubxonalar (ular o'z testlariga ega).
- Oddiy getter/setter yoki hech qanday mantiqsiz o'ram funksiyalar.
- Til yoki freymvorkning o'zi (masalan
Array.mapishlashini tekshirish shart emas).
if uchun kamida ikkita test o'ylang: shart rost bo'lgan va yolg'on bo'lgan holatlar. Shunda tarmoqlar to'liq qoplanadi.Yaxshi test belgilari
Yaxshi testlar bir necha xususiyatga ega. Ularni FIRST tamoyillari deb ham atashadi:
- Fast (Tez): testlar tez ishlashi kerak, aks holda ularni ishga tushirmaysiz.
- Isolated (Mustaqil): har bir test boshqasidan mustaqil bo'lishi, tartibi muhim bo'lmasligi kerak.
- Repeatable (Takrorlanuvchi): test har safar bir xil natija berishi kerak โ vaqt, tasodif yoki tarmoqqa bog'liq bo'lmasligi lozim.
- Self-validating (O'z-o'zini tekshiruvchi): natija aniq yashil yoki qizil bo'lishi, qo'lda talqin talab qilmasligi kerak.
- Thorough (To'liq): muhim holatlarni โ oddiy, chegaraviy va xato holatlarni qamrab olishi kerak.
Bundan tashqari, quyidagi amaliy maslahatlarga rioya qiling:
- Bir testda bitta g'oyani tekshiring โ nomidan nima tekshirilayotgani aniq bo'lsin.
- Test nomi tushunarli jumla bo'lsin:
'bo'sh savat uchun 0 qaytaradi'. - Testda mantiq (if, sikl) yozmang โ test o'zi soddaligicha qolsin.
- Testlar tasodifiy qiymat yoki joriy vaqtga bog'liq bo'lmasin.
To'liq misol: valyuta konvertori
Endi barcha o'rganganlarimizni bitta funksiya uchun to'liq testda birlashtiramiz. Mana tekshiriladigan funksiya:
// konvertor.js
function konvertQil(summa, kurs) {
if (typeof summa !== 'number' || typeof kurs !== 'number') {
throw new Error('Summa va kurs son bo'lishi kerak');
}
if (summa < 0) {
throw new Error('Summa manfiy bo'lishi mumkin emas');
}
return Math.round(summa * kurs * 100) / 100;
}
module.exports = { konvertQil };
Uning uchun oddiy, chegaraviy va xato holatlarni qamrab oluvchi to'liq test to'plami:
// konvertor.test.js
const { konvertQil } = require('./konvertor');
describe('konvertQil', () => {
// Oddiy holat
test('summani kursga ko'paytiradi', () => {
// Arrange / Act
const natija = konvertQil(100, 12.5);
// Assert
expect(natija).toBe(1250);
});
test('natijani ikki xonagacha yaxlitlaydi', () => {
expect(konvertQil(10, 1.005)).toBe(10.05);
});
// Chegaraviy holatlar
test('0 summa uchun 0 qaytaradi', () => {
expect(konvertQil(0, 12.5)).toBe(0);
});
test('kurs 0 bo'lsa 0 qaytaradi', () => {
expect(konvertQil(100, 0)).toBe(0);
});
// Xato holatlar
test('manfiy summa uchun xato tashlaydi', () => {
expect(() => konvertQil(-5, 12)).toThrow('manfiy');
});
test('son bo'lmagan kirish uchun xato tashlaydi', () => {
expect(() => konvertQil('100', 12)).toThrow();
expect(() => konvertQil(100, null)).toThrow();
});
});
E'tibor bering: test to'plami funksiyaning har bir tarmog'ini โ oddiy ishlash, yaxlitlash, nol qiymatlar, manfiy va noto'g'ri turdagi kirishlarni โ qamrab oldi. Aynan shunday testlar kelajakda kod o'zgartirilganda sizni himoya qiladi.
Xulosa
jest --coveragekodning qancha qismi test bilan qoplanganini ko'rsatadi; % Branch โ eng foydali ustun.- Coverage 100% bo'lishi kod xatosiz degani emas โ uni yo'l-yo'riq sifatida ishlating.
- AAA namunasi: Arrange (tayyorla), Act (bajar), Assert (tekshir) โ testni o'qilishli qiladi.
- Oddiy, chegaraviy va xato holatlarni test qiling; tashqi kutubxona va tilning o'zini emas.
- Yaxshi test FIRST: tez, mustaqil, takrorlanuvchi, o'z-o'zini tekshiruvchi va to'liq.
- Har bir funksiya uchun oddiy + chegaraviy + xato holatlarni qamragan to'liq test to'plami eng ishonchli himoya beradi.