Testlash (Jest)

Jest asoslari

Jest โ€” bu JavaScript uchun eng ommabop test freymvorki. U o'rnatishi oson, konfiguratsiyasiz ishlaydi va test yozish uchun kerak bo'lgan hamma narsani o'z ichiga oladi. Bu darsda Jest'ni o'rnatib, birinchi testlarimizni yozamiz.

Jest'ni o'rnatish

Jest โ€” bu devDependenciesga (ishlab chiqish bog'liqliklariga) o'rnatiladigan paket, chunki u faqat dasturchiga kerak, produksiyada emas. Loyiha papkasida quyidagini bajaring:

# Yangi loyiha bo'lsa avval:
npm init -y

# Jest'ni ishlab chiqish bog'liqligi sifatida o'rnatamiz:
npm install --save-dev jest

# Qisqacha shakli ham bor:
npm i -D jest

So'ng package.json faylidagi scripts bo'limiga test buyrug'ini qo'shamiz, shunda testlarni npm test bilan ishga tushira olamiz:

{
  "name": "mening-loyiham",
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "jest": "^29.0.0"
  }
}
--save-dev (yoki -D) paketni devDependenciesga yozadi. Bu produksiya serverida keraksiz paketlar o'rnatilmasligini ta'minlaydi.

Test fayllar qayerda joylashadi?

Jest test fayllarni avtomatik topadi. U quyidagi qoidalarga mos fayllarni test deb hisoblaydi:

Odatda test fayl tekshirilayotgan fayl yonida turadi. Aytaylik, bizda narx.js bor:

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

module.exports = { narxHisobla };

Uning yonida narx.test.js yaratamiz va tekshirmoqchi bo'lgan funksiyani import qilamiz:

// narx.test.js
const { narxHisobla } = require('./narx');

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

test() va it()

Har bir test test() funksiyasi bilan e'lon qilinadi. U ikki argument oladi: testning nomi (matn) va sinovni bajaradigan funksiya.

test('nom: nima tekshirilayotgani', () => {
  // shu yerda tekshiruvlar bo'ladi
});

it() โ€” bu test()ning aynan bir xil sinonimi (taxallusi). U jumla ravon o'qilishi uchun ishlatiladi: "it should ..." ("u ... qilishi kerak"). Ikkalasi ham bir xil ishlaydi, tanlov did masalasi:

// Bu ikkisi mutlaqo bir xil:
test('300 qaytaradi', () => { /* ... */ });
it('300 qaytaradi',   () => { /* ... */ });
Test nomini aniq va tushunarli yozing. Yaxshi nom xatolik chiqqanda darhol nima buzilganini aytib beradi: 'bo'sh savatcha uchun 0 qaytaradi' โ€” 'test1' dan minglab marta foydaliroq.

expect va matcherlar

Testning yuragi โ€” expect. U tekshirmoqchi bo'lgan qiymatni oladi, so'ng unga matcher (moslashtiruvchi) zanjirlanadi. Matcher qiymat qanday bo'lishi kerakligini aytadi. Umumiy shakl:

expect(haqiqiyQiymat).matcher(kutilganQiymat);

toBe โ€” aniq tenglik

toBe qiymatlarni === orqali solishtiradi. Sonlar, satrlar, boolean kabi oddiy (primitiv) qiymatlar uchun ishlatiladi.

expect(2 + 2).toBe(4);
expect('salom').toBe('salom');
expect(narxHisobla(0, 100)).toBe(0);

toEqual โ€” chuqur tenglik

Obyekt va massivlar uchun toBe ishlamaydi, chunki ikki alohida obyekt hech qachon === bo'yicha teng emas. Ular ichidagi qiymatlarni solishtirish uchun toEqual ishlatiladi:

expect({ ism: 'Ali', yosh: 20 }).toEqual({ ism: 'Ali', yosh: 20 });
expect([1, 2, 3]).toEqual([1, 2, 3]);

// Diqqat: bu YIQILADI, chunki ikki obyekt turli xotira manzillari:
// expect({ ism: 'Ali' }).toBe({ ism: 'Ali' });
Obyekt yoki massivni toBe bilan solishtirmang โ€” u har doim yiqiladi. Ichki qiymatlarni tekshirish uchun har doim toEqual ishlating.

toContain โ€” tarkibida bormi

Massivda element yoki satrda kichik satr borligini tekshiradi:

expect([1, 2, 3]).toContain(2);
expect(['olma', 'nok', 'uzum']).toContain('nok');
expect('salom dunyo').toContain('dunyo');

toThrow โ€” xato tashlaydimi

Funksiya xato (exception) tashlashini tekshiradi. Muhim nuqta: funksiyani chaqirib emas, balki funksiyani strelka ichiga o'rab berish kerak, aks holda xato testdan oldin otiladi:

function bo'l(a, b) {
  if (b === 0) throw new Error('Nolga bo'lish mumkin emas');
  return a / b;
}

// To'g'ri: funksiyani strelka ichida uzatamiz
expect(() => bo'l(10, 0)).toThrow();

// Xato matnini ham tekshirish mumkin:
expect(() => bo'l(10, 0)).toThrow('Nolga bo'lish mumkin emas');

Boshqa foydali matcherlar

expect(10).toBeGreaterThan(5);
expect([1, 2, 3]).toHaveLength(3);
expect('ali').not.toBe('vali');
expect(undefined).toBeUndefined();

describe bloki

Bog'liq testlarni guruhlash uchun describe bloki ishlatiladi. U testlarni tartibga soladi va natijalar chiqishini o'qilishi qulay qiladi:

const { narxHisobla } = require('./narx');

describe('narxHisobla funksiyasi', () => {
  test('oddiy hisob-kitobni bajaradi', () => {
    expect(narxHisobla(3, 100)).toBe(300);
  });

  test('soni 0 bo'lsa 0 qaytaradi', () => {
    expect(narxHisobla(0, 100)).toBe(0);
  });

  test('katta sonlar bilan ishlaydi', () => {
    expect(narxHisobla(1000, 1000)).toBe(1000000);
  });
});
describe bloklarini bir-birining ichiga joylashtirish (nested) ham mumkin. Bu murakkab funksiyalarni holatlarga bo'lib tekshirishda foydali.

Testlarni ishga tushirish

Testlarni npm test yoki to'g'ridan-to'g'ri npx jest bilan ishga tushiramiz:

npm test

# Natija shunday ko'rinadi:
# PASS  ./narx.test.js
#   narxHisobla funksiyasi
#     v oddiy hisob-kitobni bajaradi (2 ms)
#     v soni 0 bo'lsa 0 qaytaradi
#     v katta sonlar bilan ishlaydi
#
# Test Suites: 1 passed, 1 total
# Tests:       3 passed, 3 total

Kod ustida ishlayotganda eng qulay rejim โ€” watch (kuzatuv) rejimi. U fayllar o'zgarishini kuzatadi va faqat tegishli testlarni avtomatik qayta ishga tushiradi:

npx jest --watch

# Faqat bitta faylni ishga tushirish:
npx jest narx.test.js

# Nomi 'narx' so'zini o'z ichiga olgan testlarni ishga tushirish:
npx jest -t narx
Kod yozayotganda --watch rejimini yoqib qo'ying. Har bir saqlashda testlar avtomatik ishlaydi va siz xatoni darhol ko'rasiz โ€” bu o'ta samarali ish sikli.

Xulosa