Jest — o'rnatish, birinchi test, describe, it, expect
Muammodan boshlaylik
Loyiha o'saydi. Yangi funksiya qo'shdingiz — eski narsa buzildi. Siz bilmaysiz. Foydalanuvchi topadi.
Yoki: tugmani bosib har safar qo'lda tekshirasiz — "ishladimi?". Bu samarasiz. Loyiha kattalashgani sari qo'lda tekshirish imkonsiz bo'ladi.
Test — bu: "men yozgan kod ishlaydi" ni tasdiqlash. Bir marta yoziladi, keyin har safar avtomatik ishlatiladi.
Test nima?
Test — funksiyangizga ma'lum kirish berilib, kutilgan chiqish tekshiriladigan kod.
sen yozgan funksiya: test:
───────────────────── ─────────────────────
qo'sh(2, 3) → natija 5 bo'lishi kerak
qo'sh(0, 0) → natija 0 bo'lishi kerak
qo'sh(-1, 1) → natija 0 bo'lishi kerak
Test o'tdi — funksiya to'g'ri ishlaydi. Test o'tmadi — qayerda buzilganini darhol bilasiz.
Hayotiy o'xshatma
Zavod konveyer. Har bir mahsulot chiqqanda — tekshiruv punkti. Nuqsonli bo'lsa — darhol to'xtatiladi, omborga bormaydi.
Testsiz dasturlash — tekshiruvsiz konveyer. Nuqsonli mahsulot foydalanuvchiga yetib boradi.
O'rnatish
npm install --save-dev jest
package.json:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
}
ES module ishlatayotgan bo'lsangiz:
npm install --save-dev jest @babel/preset-env babel-jest
babel.config.json:
{
"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
}
Birinchi test
// utils/math.js
export const qo'sh = (a, b) => a + b;
export const ayir = (a, b) => a - b;
// utils/math.test.js
import { qo'sh, ayir } from './math.js';
test('2 + 3 = 5', () => {
expect(qo'sh(2, 3)).toBe(5);
});
test('5 - 3 = 2', () => {
expect(ayir(5, 3)).toBe(2);
});
npm test
✓ 2 + 3 = 5 (2ms)
✓ 5 - 3 = 2 (1ms)
Tests: 2 passed
describe — testlarni guruhlash
Bir funksiya uchun ko'p test bo'lsa — describe bilan guruhlang:
import { qo'sh } from './math.js';
describe('qo\'sh funksiyasi', () => {
test('musbat sonlar', () => {
expect(qo'sh(2, 3)).toBe(5);
});
test('manfiy sonlar', () => {
expect(qo'sh(-2, -3)).toBe(-5);
});
test('nol bilan', () => {
expect(qo'sh(5, 0)).toBe(5);
});
});
qo'sh funksiyasi
✓ musbat sonlar
✓ manfiy sonlar
✓ nol bilan
💡
testo'rnigaitham ishlatiladi — ikkalasi bir xil.it('musbat sonlarni qo\'shadi', ...)— inglizcha o'qishda tabiiyroq.
expect — nimani tekshirish
// Teng
expect(natija).toBe(5); // qat'iy tenglik (===)
expect(natija).toEqual({ a: 1 }); // obyekt/massiv tenglik
// To'g'ri/noto'g'ri
expect(natija).toBeTruthy(); // true bo'lsa
expect(natija).toBeFalsy(); // false bo'lsa
expect(natija).toBeNull(); // null bo'lsa
// Mavjudlik
expect(massiv).toContain(5); // massivda bor
expect(matn).toMatch('salom'); // satrda bor
expect(funksiya).toThrow('xato xabari'); // xato tashlaydi
// Soni
expect(natija).toBeGreaterThan(3); // > 3
expect(natija).toBeLessThanOrEqual(10); // <= 10
Async test
// utils/user.js
export const ismniOl = async (id) => {
const user = await db.findById(id);
return user.name;
};
// utils/user.test.js
// async/await bilan
test('foydalanuvchi ismini qaytaradi', async () => {
const ism = await ismniOl(1);
expect(ism).toBe('Ali');
});
Amaliy misol — parol tekshirish funksiyasi
// utils/validation.js
export const parolTekshir = (parol) => {
if (parol.length < 8) return { togri: false, xabar: 'Kamida 8 belgi' };
if (!/[A-Z]/.test(parol)) return { togri: false, xabar: 'Katta harf kerak' };
if (!/[0-9]/.test(parol)) return { togri: false, xabar: 'Raqam kerak' };
return { togri: true };
};
// utils/validation.test.js
import { parolTekshir } from './validation.js';
describe('parolTekshir', () => {
test('qisqa parol', () => {
const natija = parolTekshir('abc');
expect(natija.togri).toBe(false);
expect(natija.xabar).toBe('Kamida 8 belgi');
});
test('katta harf yo\'q', () => {
const natija = parolTekshir('password1');
expect(natija.togri).toBe(false);
expect(natija.xabar).toBe('Katta harf kerak');
});
test('to\'g\'ri parol', () => {
const natija = parolTekshir('Password1');
expect(natija.togri).toBe(true);
});
});
Test fayllarni qayerga qo'yish
Ikkita keng tarqalgan yondashuv:
// 1 — manba yonida
src/
├── utils/
│ ├── math.js
│ └── math.test.js ← bir joyda
// 2 — alohida papka
src/
├── utils/
│ └── math.js
tests/
└── math.test.js
Ko'pchilik manba yonida usulni afzal ko'radi — faylni ko'rganingizda test ham ko'rinadi.
Tez-tez uchraydigan xatolar
1. toBe va toEqual aralashtirib yuborish
// ❌ — obyektda toBe ishlamaydi
expect({ a: 1 }).toBe({ a: 1 }); // false! Turli xotira manzili
// ✅
expect({ a: 1 }).toEqual({ a: 1 }); // ichini solishtiradi
2. Async testda await unutish
// ❌ — test har doim o'tadi (natijani kutmaydi)
test('test', () => {
expect(asyncFn()).resolves.toBe('ok'); // await yo'q!
});
// ✅
test('test', async () => {
await expect(asyncFn()).resolves.toBe('ok');
});
3. Test izolyatsiyasi
// ❌ — testlar bir-biriga bog'liq
let hisoblagich = 0;
test('birinchi', () => { hisoblagich++; });
test('ikkinchi', () => {
expect(hisoblagich).toBe(1); // ← tartib o'zgansa — sinadi
});
// ✅ — har test o'z holatida
test('birinchi', () => {
let h = 0; h++;
expect(h).toBe(1);
});
Xulosa
- Test — funksiyaga kirish berib, kutilgan chiqishni tekshirish
describe— guruh;test/it— bitta test;expect— tekshirishtoBe— qat'iy tenglik;toEqual— obyekt/massiv ichini solishtiradi- Async test —
async/awaitbilan - Har test mustaqil bo'lsin — boshqa testga tayanmasin
Keyingi dars: 51-dars: Supertest — HTTP endpointlarni testlash