Node.js Test Runner


ULASHISH

Node.js Test Runner dasturiga kirish

O‘rnatilgan node:test moduli to‘g‘ridan-to‘g‘ri Node.js da JavaScript testlarini yozish va ishga tushirish uchun yengil, bog‘liqliksiz tizimni ta’minlaydi.

Node.js 20 da barqaror API sifatida taqdim etilgan, u tashqi test tizimlariga tez va zamonaviy muqobil bo‘lishi uchun yaratilgan.

Eslatma: Node.js Test Runner Node.js v20 dan boshlab barqaror.

Ba’zi ilg‘or xususiyatlar oldingi versiyalarda eksperimental bo‘lishi mumkin.

Asosiy xususiyatlar

Asosiy qobiliyatlar

  • Nol konfiguratsiya: Hech qanday sozlashsiz qutidan tashqarida ishlaydi
  • Ikki modulni qo‘llab-quvvatlash: Mahalliy ESM va CommonJS muvofiqligi
  • Paralel bajarish: Sinovlar sukut bo‘yicha bir vaqtda ishlaydi
  • Test izolyatsiyasi: Har bir test o‘z kontekstida ishlaydi

Kengaytirilgan xususiyatlar

  • Asinxron qo‘llab-quvvatlash: Birinchi darajali async/await bilan ishlash
  • Test hook’lari: Set/buzib tashlash uchun hook’lardan oldin/keyin
  • Mocking (soxtalashtirish): O‘rnatilgan test doubles va spies (kuzatuvchilar)
  • Kod qamrovi: Node.js qamrov vositalari bilan integratsiya

Ishni boshlash

Birinchi testni yozish

Node.js Test Runner yordamida asosiy testni yaratamiz va ishga tushiramiz.

Sizga Node.js 16.17.0 yoki undan keyingi versiyasi o‘rnatilgan bo‘lishi kerak.

1. Test faylini yarating (test/example.test.js)

// Load the test module
const test = require('node:test');
// Use strict assertion mode for better error messages
const assert = require('node:assert/strict');

// Simple synchronous test
test('basic arithmetic', (t) => {
  // Assert that 1 + 1 equals 2
  assert.equal(1 + 1, 2, '1 + 1 should equal 2');

  // Deep equality check for objects/arrays
  assert.deepEqual(
    { a: 1, b: { c: 2 } },
    { a: 1, b: { c: 2 } }
  );
});
// Asynchronous test with async/await
test('async test', async (t) => {
  const result = await Promise.resolve('async result');
  assert.strictEqual(result, 'async result');
});

2. Sinovni bajaring

# Run all test files in the test directory
node --test

# Run a specific test file
node --test test/example.test.js

# Run with coverage reporting
NODE_V8_COVERAGE=coverage node --test
Misolni ishga tushirish »

Testning tuzilishi va tashkil etilishi

Kattaroq loyihalar uchun testlaringizni tuzilgan tarzda tashkil qiling:

project/
├── src/
│ ├── math.js
│ └── utils.js
└── test/
├── unit/
│ ├── math.test.js
│ └── utils.test.js
└── integration/
└── api.test.js

Test hooklari (Test hooks)

Sinov muhitini sozlash va tozalash uchun hook’lardan foydalaning:

const { test, describe, before, after, beforeEach, afterEach } = require('node:test');
const assert = require('node:assert/strict');

describe('Test Suite with Hooks', (t) => {
  let testData = [];

  // Runs once before all tests
  before(() => {
    console.log('Running before all tests');
    testData = [1, 2, 3];
  });

  // Runs before each test
  beforeEach((t) => {
    console.log('Running before each test');
  });

  test('array length', () => {
    assert.strictEqual(testData.length, 3);
  });

  // Runs after each test
  afterEach(() => {
    console.log('Running after each test');
  });

  // Runs once after all tests
  after(() => {
    console.log('Running after all tests');
    testData = [];
  });
});

CommonJS sintaksisi

// simple-test.js
const test = require('node:test');
const assert = require('node:assert/strict');

test('basic test', () => {
  assert.equal(1 + 1, 2);
});

Ishlayotgan testlar

--test bayrog‘i yordamida testlarni bajaring:

node --test simple-test.js

Shuningdek, barcha test fayllarini katalogdagi ishga tushirishingiz mumkin:

node --test

Bu quyidagi naqshlarga mos keladigan nomlar bilan barcha fayllarni ishga tushiradi:

  • **/*.test.js
  • **/*.spec.js
  • **/test-*.js
  • **/test/*.js


Yozish testlari

Asinxron testlar

Asinxron kod uchun asinxron test funksiyasidan foydalaning:

import test from 'node:test';
import assert from 'node:assert/strict';

// Using async/await
test('async test', async () => {
  // Simulate async operation
  const result = await Promise.resolve(42);
  assert.equal(result, 42);
});

// Using callbacks with done (older style)
test('callback test', (t, done) => {
  setTimeout(() => {
    assert.equal(1 + 1, 2);
    done();
  }, 100);
});

Subtestlar (ichma-ich testlar)

Subtestlar yordamida tegishli testlarni tashkil qilishingiz mumkin:

import test from 'node:test';
import assert from 'node:assert/strict';

test('math operations', async (t) => {
  await t.test('addition', () => {
    assert.equal(1 + 1, 2);
  });
  
  await t.test('multiplication', () => {
    assert.equal(2 * 3, 6);
  });
  
  await t.test('division', () => {
    assert.equal(10 / 2, 5);
  });
});

Setup va Teardown (test fixture’lari)

Sozlash (setup) va tozalash (teardown) talab qiladigan testlar uchun t.before() va t.after() hooklaridan foydalaning:

import test from 'node:test';
import assert from 'node:assert/strict';

test('using test fixtures', async (t) => {
  // Setup - runs before the test
  t.before(() => {
    console.log('Setting up test resources');
    // Example: Create test database, mock services, etc.
  });
  
  // Actual test
  await t.test('my test with fixtures', () => {
    assert.equal(1 + 1, 2);
  });
  
  // Teardown - runs after the test
  t.after(() => {
    console.log('Cleaning up test resources');
    // Example: Delete test database, restore mocks, etc.
  });
});

O‘tkazib yuborish va bajariladigan testlar

Siz o‘tkazib yuboriladigan testlarni yoki bajariladigan vazifalar sifatida belgilashingiz mumkin:

import test from 'node:test';

// Skip this test
test('skipped test', { skip: true }, () => {
  // This won't run
});

// Skip with a reason
test('skipped with reason', { skip: 'working on this later' }, () => {
  // This won't run
});

// Mark as TODO
test('todo test', { todo: true }, () => {
  // This won't run, but will be reported as TODO
});

// Conditional skip
test('conditional skip', { skip: process.platform === 'win32' }, () => {
  // This will be skipped on Windows
});

Tasdiqlar

Node.js Test Runner o‘rnatilgan assert moduli bilan ishlaydi. Qattiq tenglikni tekshirish uchun assert/strict dan foydalaning.

Umumiy da’volar

import assert from 'node:assert/strict';

// Equality checks
assert.equal(1, 1);                 // Loose equality (==)
assert.strictEqual(1, 1);           // Strict equality (===)
assert.deepEqual({a: 1}, {a: 1});   // Deep equality for objects
assert.deepStrictEqual({a: 1}, {a: 1}); // Strict deep equality

// Truthiness checks
assert.ok(true);                    // Checks if value is truthy
assert.ok(1);                       // Also truthy

// Comparing values
assert.notEqual(1, 2);              // Check inequality
assert.notStrictEqual(1, '1');      // Check strict inequality

// Throwing errors
assert.throws(() => { throw new Error('Boom!'); }); // Check if function throws
assert.doesNotThrow(() => { return 42; });         // Check if no error thrown

// Async assertions
await assert.rejects(               // Check if Promise rejects
  async () => { throw new Error('Async boom!'); }
);

Mocks bilan ishlash

Node.js Test Runner o‘rnatilgan mocking funksiyasini o‘z ichiga olmaydi, lekin siz:

  • Test juftligini ta’minlash uchun qaramlik in’ektsiyasidan foydalaning
  • Oddiy soxta funksiyalar va obyektlarni yarating
  • Agar kerak bo‘lsa, uchinchi tomon mocking kutubxonalari bilan integratsiya qiling

Oddiy soxta misol

import test from 'node:test';
import assert from 'node:assert/strict';

// Function we want to test
function processUser(user, logger) {
  if (!user.name) {
    logger.error('User has no name');
    return false;
  }
  logger.info(`Processing user: ${user.name}`);
  return true;
}

// Test with a mock logger
test('processUser logs correctly', () => {
  // Create a mock logger
  const mockCalls = [];
  const mockLogger = {
    error: (msg) => mockCalls.push(['error', msg]),
    info: (msg) => mockCalls.push(['info', msg])
  };
  
  // Test with valid user
  const validResult = processUser({name: 'Alice'}, mockLogger);
  assert.strictEqual(validResult, true);
  assert.deepStrictEqual(mockCalls[0], ['info', 'Processing user: Alice']);
  
  // Reset mock calls
  mockCalls.length = 0;
  
  // Test with invalid user
  const invalidResult = processUser({}, mockLogger);
  assert.strictEqual(invalidResult, false);
  assert.deepStrictEqual(mockCalls[0], ['error', 'User has no name']);
});

Haqiqiy misollarni sinab ko‘rish

Yordamchi dastur funksiyasini sinab ko‘rish

// utils.js
exports.formatPrice = function(price) {
  if (typeof price !== 'number' || isNaN(price)) {
    throw new Error('Price must be a valid number');
  }
  return `$${price.toFixed(2)}`;
};

// utils.test.js
const test = require('node:test');
const assert = require('node:assert/strict');
const { formatPrice } = require('./utils');

// Test cases
test('formatPrice formats numbers as currency strings', (t) => {
  assert.equal(formatPrice(10), '$10.00');
  assert.equal(formatPrice(10.5), '$10.50');
  assert.equal(formatPrice(0), '$0.00');
});

// Test for error
test('formatPrice throws error for invalid inputs', (t) => {
  assert.throws(() => formatPrice('not a number'), {
    message: 'Price must be a valid number'
  });
  assert.throws(() => formatPrice(NaN));
  assert.throws(() => formatPrice());
});

API so‘nggi nuqtasini sinovdan o‘tkazish

// userService.js
const express = require('express');
const app = express();
app.use(express.json());

app.get('/users/:id', (req, res) => {
  const userId = parseInt(req.params.id);
  // Simplified - in real app would fetch from database
  if (userId === 1) {
    res.json({ id: 1, name: 'John Doe', email: 'john@example.com' });
  } else {
    res.status(404).json({ error: 'User not found' });
  }
});

module.exports = app;

// userService.test.js
const test = require('node:test');
const assert = require('node:assert/strict');
const http = require('node:http');
const app = require('./userService');

test('GET /users/:id returns correct user', async (t) => {
  // Start the server
  const server = http.createServer(app);
  await new Promise(resolve => server.listen(0, resolve));
  const port = server.address().port;
  
  try {
    // Make request to our API
    const response = await fetch(`http://localhost:${port}/users/1`);
    assert.equal(response.status, 200, 'Status should be 200');
    
    const user = await response.json();
    assert.deepStrictEqual(user, {
      id: 1,
      name: 'John Doe',
      email: 'john@example.com'
    });
    
    // Test not found case
    const notFoundResponse = await fetch(`http://localhost:${port}/users/999`);
    assert.equal(notFoundResponse.status, 404, 'Status should be 404');
  } finally {
    // Clean up - close the server
    await new Promise(resolve => server.close(resolve));
  }
});

Kengaytirilgan konfiguratsiya

Maxsus reportyorlar

Sinov natijalari uchun turli chiqish formatlarini belgilashingiz mumkin:

node --test --test-reporter=spec

Mavjud muxbirlar qatoriga quyidagilar kiradi:

  • spec - Batafsil ierarxik ko‘rinish
  • dot - Minimal nuqta chiqishi
  • tap - Anything Protocol formatini sinab ko‘ring
  • junit - JUnit XML formati

Filtrlash testlari

Naqshlar yordamida qaysi testlarni bajarishni filtrlashingiz mumkin:

node --test --test-name-pattern="user"

Bu faqat o‘z nomidagi "foydalanuvchi" bilan testlarni amalga oshiradi.

Tomosha rejimi

Rivojlanish uchun siz fayllar o‘zgarganda avtomatik ravishda qayta ishga tushirish uchun tomosha rejimida testlarni o‘tkazishingiz mumkin:

node --test --watch

Boshqa test tizimlari bilan taqqoslash

Feature Node.js Test Runner Jest Mocha Vitest
Ichki o‘rnatilgan ✅ Yes (Node.js 16.17.0+) ❌ No ❌ No ❌ No
Zero Config ✅ Yes ✅ Yes ❌ Needs setup ✅ Yes
Test Runner Node.js’ga o‘rnatilgan Jest Mocha Vite
Assertion Library node:assert Jest Expect Chai/Sinon Jest-compatible
Parallel Tests ✅ Yes ✅ Yes ✅ --parallel bilan ✅ Yes
Code Coverage ✅ NODE_V8_COVERAGE bilan ✅ O‘rnatilgan ❌ Needs nyc/istanbul ✅ O‘rnatilgan
Mocking ✅ Basic ✅ Advanced ❌ Needs Sinon ✅ Advanced
Watch Mode ✅ Yes (--watch) ✅ Yes ✅ --watch bilan ✅ Fast HMR
Eng mos holatlar O‘rnatilgan yechim, oddiy loyihalar Full-featured testing Flexible testing Vite projects, ESM

Eslatma: Node.js Test Runner Node.js-ning o‘zida o‘rnatilgan yengil, nolga bog‘liqliksiz sinov yechimini talab qiladigan loyihalar uchun ideal.

Keyinchalik murakkab test ehtiyojlari uchun Jest yoki Mocha yaxshiroq tanlov bo‘lishi mumkin.




W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!