Node.js'da testlash: node:test
Kod yozgandan keyin uni tekshirasiz: dasturni ishga tushirib, natijani ko’zdan kechirasiz. Funksiya o’nta bo’lsa, har o’zgarishdan keyin o’ntasini qayta tekshirish kerak. Amalda buni hech kim qilmaydi — shuning uchun eski kod buzilgani sezilmay qoladi.
Test aynan shu ishni bajaradi: bitta buyruq bilan hamma tekshiruv avtomatik yuriydi.
Hech narsa o’rnatilmaydi
JavaScript testlash darsida test tushunchasi bilan tanishgansiz. Node.js’da test yurituvchi ichiga qurilgan:
Sinaladigan funksiya
Avval tekshiriladigan kod kerak. slug.js:
function createSlug(title) {
if (typeof title !== "string") {
throw new TypeError("title satr bo'lishi kerak");
}
return title
.trim()
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-|-$/g, "");
}
module.exports = { createSlug };
Funksiya sarlavhadan URL uchun qismni yasaydi.
Birinchi test
Test fayli nomi .test.js bilan tugaydi. slug.test.js:
const test = require("node:test");
const assert = require("node:assert");
const { createSlug } = require("./slug");
test("bo'shliqni chiziqchaga almashtiradi", () => {
assert.strictEqual(createSlug("Node js darsi"), "node-js-darsi");
});
test("bosh va oxirgi chiziqchani olib tashlaydi", () => {
assert.strictEqual(createSlug(" Salom! "), "salom");
});
test("satr bo'lmasa xato beradi", () => {
assert.throws(() => createSlug(42), TypeError);
});
Yuritish:
node --test
✔ bo'shliqni chiziqchaga almashtiradi (1.1955ms)
✔ bosh va oxirgi chiziqchani olib tashlaydi (0.1961ms)
✔ satr bo'lmasa xato beradi (0.6304ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 128.6357
Uchta belgisi — uchta test o’tdi. --test bayrog’i papkadagi test
fayllarini o’zi topadi.
Test yiqilganda nima ko’rinadi
Bu muhim: xato xabarini o’qiy bilish kerak. Ataylab noto’g’ri kutilgan qiymat yozamiz:
const test = require("node:test");
const assert = require("node:assert");
function add(a, b) {
return a + b;
}
test("ikki sonni qo'shadi", () => {
assert.strictEqual(add(2, 2), 5);
});
node --test
✖ ikki sonni qo'shadi (1.9518ms)
ℹ tests 1
ℹ pass 0
ℹ fail 1
✖ failing tests:
test at fail.test.js:5:1
✖ ikki sonni qo'shadi (1.9518ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
4 !== 5
actual: 4,
expected: 5,
operator: 'strictEqual'
Uch narsa aytilgan: qaysi test, qaysi qator va 4 !== 5. actual
haqiqiy natija, expected kutilgani.
Asosiy assert metodlari
| Metod | Nimani tekshiradi |
|---|---|
assert.strictEqual(a, b) |
a === b — son, satr, mantiqiy qiymat |
assert.deepStrictEqual(a, b) |
Massiv va obyekt ichini solishtiradi |
assert.ok(value) |
Qiymat rostmi |
assert.throws(fn, Type) |
Funksiya xato chiqaradimi |
assert.rejects(promise) |
Asinxron amal rad etiladimi |
describe va it bilan guruhlash
Testlar ko’payganda ularni mavzu bo’yicha guruhlash qulay.
storage.js — fayl bilan ishlaydigan modul:
const fs = require("node:fs/promises");
async function saveNotes(filePath, notes) {
await fs.writeFile(filePath, JSON.stringify(notes, null, 2), "utf8");
}
async function loadNotes(filePath) {
try {
const content = await fs.readFile(filePath, "utf8");
return JSON.parse(content);
} catch (error) {
if (error.code === "ENOENT") {
return [];
}
throw error;
}
}
module.exports = { saveNotes, loadNotes };
storage.test.js:
const { describe, it, after } = require("node:test");
const assert = require("node:assert");
const fs = require("node:fs/promises");
const path = require("node:path");
const { saveNotes, loadNotes } = require("./storage");
const testFile = path.join(__dirname, "test-notes.json");
describe("storage moduli", () => {
// Test tugagach yaratilgan faylni tozalaymiz
after(async () => {
await fs.rm(testFile, { force: true });
});
it("fayl yo'q bo'lsa bo'sh ro'yxat qaytaradi", async () => {
const notes = await loadNotes(path.join(__dirname, "yoq.json"));
assert.deepStrictEqual(notes, []);
});
it("yozgan ma'lumotini qayta o'qiydi", async () => {
await saveNotes(testFile, [{ id: 1, text: "Salom" }]);
const notes = await loadNotes(testFile);
assert.strictEqual(notes.length, 1);
assert.strictEqual(notes[0].text, "Salom");
});
});
node --test
▶ storage moduli
✔ fayl yo'q bo'lsa bo'sh ro'yxat qaytaradi (6.8637ms)
✔ yozgan ma'lumotini qayta o'qiydi (4.7573ms)
✔ storage moduli (14.7798ms)
ℹ tests 2
ℹ suites 1
ℹ pass 2
ℹ fail 0
Uch narsaga e’tibor bering. Birinchidan, testlar guruh ichida
chekindi. Ikkinchidan, async funksiya test sifatida ishlaydi —
qo’shimcha sozlash kerak emas. Uchinchidan, after testdan keyin
tozalash ishini bajardi.
| Yordamchi | Qachon ishlaydi |
|---|---|
before |
Guruhdagi barcha testlardan oldin bir marta |
after |
Guruhdagi barcha testlardan keyin bir marta |
beforeEach |
Har test oldidan |
afterEach |
Har testdan keyin |
Asinxron xatoni tekshirish
Rad etilgan Promise uchun alohida metod bor:
const test = require("node:test");
const assert = require("node:assert");
async function findUser(id) {
if (typeof id !== "number") {
throw new TypeError("id son bo'lishi kerak");
}
return { id, name: "Aziz" };
}
test("noto'g'ri id da rad etadi", async () => {
await assert.rejects(() => findUser("salom"), TypeError);
});
test("to'g'ri id da foydalanuvchi qaytaradi", async () => {
const user = await findUser(7);
assert.strictEqual(user.id, 7);
});
node --test
✔ noto'g'ri id da rad etadi (1.8021ms)
✔ to'g'ri id da foydalanuvchi qaytaradi (0.3104ms)
ℹ pass 2
ℹ fail 0
assert.rejects oldida await turishi shart —
xatolar darsida aytilgan qoida bu yerda ham
ishlaydi.
mock — soxta funksiya
Ba’zan funksiya chaqirilganini tekshirish kerak, natijani emas. Masalan, xabar yuborish funksiyasi har element uchun ishladimi?
const { test, mock } = require("node:test");
const assert = require("node:assert");
function sendReport(items, notify) {
for (const item of items) {
notify(item);
}
return items.length;
}
test("notify har element uchun chaqiriladi", () => {
const notify = mock.fn();
const total = sendReport(["a", "b", "c"], notify);
assert.strictEqual(total, 3);
assert.strictEqual(notify.mock.callCount(), 3);
assert.strictEqual(notify.mock.calls[0].arguments[0], "a");
});
node --test
✔ notify har element uchun chaqiriladi (1.3508ms)
ℹ pass 1
ℹ fail 0
Haqiqiy loyihada notify o’rnida xat yuborish turishi mumkin. Mock
tufayli test paytida hech kimga xat ketmaydi.
Qamrovni o’lchash
node --test --experimental-test-coverage
ℹ start of coverage report
ℹ ------------------------------------------------------------
ℹ file | line % | branch % | funcs % | uncovered lines
ℹ ------------------------------------------------------------
ℹ storage.js | 89.47 | 80.00 | 100.00 | 15-16
ℹ slug.js | 100.00 | 100.00 | 100.00 |
ℹ ------------------------------------------------------------
ℹ all files | 93.55 | 88.89 | 100.00 |
ℹ ------------------------------------------------------------
ℹ end of coverage report
Oxirgi ustun eng foydalisi. storage.js da 15-16-qatorlar
tekshirilmagan — bu ENOENT dan boshqa xato uchun yozilgan throw
tarmog’i.
package.json ga qo’shish
Har safar bayroq yozmaslik uchun buyruqni skriptga yozing:
{
"name": "node-start",
"version": "1.0.0",
"scripts": {
"test": "node --test",
"test:coverage": "node --test --experimental-test-coverage"
}
}
npm test
ℹ tests 3
ℹ pass 3
ℹ fail 0
Skriptlar npm darsida ko’rilgan.
Amaliy mashq
node-start papkasida bajaring:
slug.jsni yozib, unga uchta test qo’shing vanode --testbilan yuriting;- Bitta testdagi kutilgan qiymatni ataylab buzib, xato xabaridagi
actualvaexpectedqatorlarini o’qing; - Ikki obyektni
strictEqualbilan solishtirib ko’ring, so’ngdeepStrictEqualga almashtiring; storage.jsuchundescribevaitbilan guruh yozib,afterichida test faylini tozalang;mock.fn()bilan soxta funksiya yaratib,callCount()ni tekshiring;--experimental-test-coveragebilan qamrovni o’lchang va tekshirilmagan qatorlarni toping.
2-qadam eng muhimi: test yiqilganda chiqadigan xabarni o’qiy bilish testlar yozishdan kam ahamiyatli emas.
Qisqacha xulosa
node:testvanode:assertNode.js ichida keladi — paket o’rnatilmaydi.- Test fayli
.test.jsbilan tugaydi,node --testularni o’zi topadi. strictEqualoddiy qiymatlar uchun, obyekt va massiv uchundeepStrictEqual.describevaittestlarni guruhlaydi,before/aftertayyorlash va tozalash ishini bajaradi.asyncfunksiya test sifatida ishlaydi, rad etishniassert.rejectstekshiradi.mock.fn()funksiya necha marta va qanday argument bilan chaqirilganini eslab qoladi.- Qamrov hisoboti sinalmagan qatorlarni ko’rsatadi — raqamning o’zi maqsad emas.
Keyingi darsda debug qilish — xatoni
console.log siz topish.