O'zbek

Yanada ishonchli va qo'llab-quvvatlanadigan dasturiy ta'minot yaratish uchun Jest'ning ilg'or testlash andozalarini o'zlashtiring. Xalqaro dasturchilar jamoalari uchun mocking, snapshot testlash, maxsus mosliklar va boshqa usullarni o'rganing.

Jest: Mustahkam Dasturiy Ta'minot uchun Ilg'or Testlash Andozalari

Bugungi tez sur'atlarda rivojlanayotgan dasturiy ta'minotni ishlab chiqish olamida kodingizning ishonchliligi va barqarorligini ta'minlash juda muhimdir. Jest JavaScript testlash uchun de-fakto standartga aylangan bo'lsa-da, oddiy unit testlardan tashqariga chiqish ilovalaringizga yangi darajadagi ishonchni ochib beradi. Ushbu maqola global dasturchilar auditoriyasiga mo'ljallangan mustahkam dasturiy ta'minot yaratish uchun zarur bo'lgan ilg'or Jest testlash andozalarini chuqur o'rganadi.

Nima uchun Oddiy Unit Testlar bilan Cheklanmaslik Kerak?

Oddiy unit testlar alohida komponentlarni izolyatsiyada tekshiradi. Biroq, real hayotdagi ilovalar komponentlar o'zaro ta'sir qiladigan murakkab tizimlardir. Ilg'or testlash andozalari ushbu murakkabliklarni hal qilishga yordam beradi, chunki ular bizga quyidagilarga imkon beradi:

Mocking va Spies'ni O'zlashtirish

Mocking (soxtalashtirish) test qilinayotgan birlikni uning bog'liqliklarini boshqariladigan o'rinbosarlar bilan almashtirish orqali izolyatsiya qilish uchun juda muhimdir. Jest buning uchun kuchli vositalarni taqdim etadi:

jest.fn(): Mock'lar va Spy'larning Asosi

jest.fn() mock (soxta) funksiya yaratadi. Siz uning chaqiruvlari, argumentlari va qaytarilgan qiymatlarini kuzatib borishingiz mumkin. Bu yanada murakkab mocking strategiyalari uchun asosiy qurilish blokidir.

Misol: Funksiya Chaqiruvlarini Kuzatish

// component.js
export const fetchData = () => {
  // API so'rovini simulyatsiya qiladi
  return Promise.resolve({ data: 'some data' });
};

export const processData = async (fetcher) => {
  const result = await fetcher();
  return `Qayta ishlandi: ${result.data}`;
};

// component.test.js
import { processData } from './component';

test('ma\'lumotlarni to\'g\'ri qayta ishlashi kerak', async () => {
  const mockFetcher = jest.fn().mockResolvedValue({ data: 'mocked data' });
  const result = await processData(mockFetcher);
  expect(result).toBe('Qayta ishlandi: mocked data');
  expect(mockFetcher).toHaveBeenCalledTimes(1);
  expect(mockFetcher).toHaveBeenCalledWith();
});

jest.spyOn(): Almashtirmasdan Kuzatish

jest.spyOn() mavjud ob'ektdagi metodga qilingan chaqiruvlarni uning implementatsiyasini almashtirmasdan kuzatish imkonini beradi. Agar kerak bo'lsa, implementatsiyani soxtalashtirishingiz ham mumkin.

Misol: Modul Metodini Kuzatish (Spying)

// logger.js
export const logInfo = (message) => {
  console.log(`INFO: ${message}`);
};

// service.js
import { logInfo } from './logger';

export const performTask = (taskName) => {
  logInfo(`Vazifa boshlanmoqda: ${taskName}`);
  // ... vazifa mantig'i ...
  logInfo(`Vazifa ${taskName} yakunlandi.`);
};

// service.test.js
import { performTask } from './service';
import * as logger from './logger';

test('vazifaning boshlanishi va yakunlanishini logga yozishi kerak', () => {
  const logSpy = jest.spyOn(logger, 'logInfo');

  performTask('backup');

  expect(logSpy).toHaveBeenCalledTimes(2);
  expect(logSpy).toHaveBeenCalledWith('Vazifa boshlanmoqda: backup');
  expect(logSpy).toHaveBeenCalledWith('Vazifa backup yakunlandi.');

  logSpy.mockRestore(); // Asl implementatsiyani tiklash muhim
});

Modul Importlarini Mocking Qilish

Jest'ning modulni mocking qilish imkoniyatlari keng. Siz butun modullarni yoki ma'lum eksportlarni soxtalashtirishingiz mumkin.

Misol: Tashqi API Klientini Mocking Qilish

// api.js
import axios from 'axios';

export const getUser = async (userId) => {
  const response = await axios.get(`/api/users/${userId}`);
  return response.data;
};

// user-service.js
import { getUser } from './api';

export const getUserFullName = async (userId) => {
  const user = await getUser(userId);
  return `${user.firstName} ${user.lastName}`;
};

// user-service.test.js
import { getUserFullName } from './user-service';
import * as api from './api';

// Butun api modulini soxtalashtirish
jest.mock('./api');

test('soxtalashtirilgan API yordamida to\'liq ismni olishi kerak', async () => {
  // Soxtalashtirilgan moduldan ma'lum bir funksiyani soxtalashtirish
  api.getUser.mockResolvedValue({ id: 1, firstName: 'Ada', lastName: 'Lovelace' });

  const fullName = await getUserFullName(1);

  expect(fullName).toBe('Ada Lovelace');
  expect(api.getUser).toHaveBeenCalledTimes(1);
  expect(api.getUser).toHaveBeenCalledWith(1);
});

Avtomatik Mocking va Qo'lda Mocking

Jest avtomatik ravishda Node.js modullarini soxtalashtiradi. ES modullari yoki maxsus modullar uchun sizga jest.mock() kerak bo'lishi mumkin. Ko'proq nazorat uchun siz __mocks__ papkalarini yaratishingiz mumkin.

Mock Implementatsiyalari

Siz o'zingizning mock'laringiz uchun maxsus implementatsiyalarni taqdim etishingiz mumkin.

Misol: Maxsus Implementatsiya bilan Mocking

// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

// calculator.js
import { add, subtract } from './math';

export const calculate = (operation, a, b) => {
  if (operation === 'add') {
    return add(a, b);
  } else if (operation === 'subtract') {
    return subtract(a, b);
  }
  return null;
};

// calculator.test.js
import { calculate } from './calculator';
import * as math from './math';

// Butun math modulini soxtalashtirish
jest.mock('./math');

test('soxtalashtirilgan math add yordamida qo\'shishni bajarishi kerak', () => {
  // 'add' funksiyasi uchun mock implementatsiyasini taqdim etish
  math.add.mockImplementation((a, b) => a + b + 10); // Natijaga 10 qo'shish
  math.subtract.mockReturnValue(5); // subtract'ni ham soxtalashtirish

  const result = calculate('add', 5, 3);

  expect(math.add).toHaveBeenCalledWith(5, 3);
  expect(result).toBe(18); // 5 + 3 + 10

  const subResult = calculate('subtract', 10, 2);
  expect(math.subtract).toHaveBeenCalledWith(10, 2);
  expect(subResult).toBe(5);
});

Snapshot Testlash: UI va Konfiguratsiyani Saqlash

Snapshot testlar bu sizning komponentlaringiz yoki konfiguratsiyalaringizning chiqish natijasini qayd etish uchun kuchli xususiyatdir. Ular ayniqsa UI testlash yoki murakkab ma'lumotlar tuzilmalarini tekshirish uchun foydalidir.

Snapshot Testlash Qanday Ishlaydi

Snapshot testi birinchi marta ishga tushirilganda, Jest test qilinayotgan qiymatning seriyalashtirilgan ko'rinishini o'z ichiga olgan .snap faylini yaratadi. Keyingi ishga tushirishlarda Jest joriy natijani saqlangan snapshot bilan solishtiradi. Agar ular farq qilsa, test muvaffaqiyatsiz tugaydi va sizni kutilmagan o'zgarishlar haqida ogohlantiradi. Bu turli mintaqalar yoki tillar uchun UI komponentlaridagi regressiyalarni aniqlashda bebaho vositadir.

Misol: React Komponentini Snapshot Qilish

Sizda React komponenti bor deb faraz qilaylik:

// UserProfile.js
import React from 'react';

const UserProfile = ({ name, email, isActive }) => (
  <div>
    <h2>{name}</h2>
    <p><strong>Email:</strong> {email}</p>
    <p><strong>Status:</strong> {isActive ? 'Faol' : 'Nofaol'}</p>
  </div>
);

export default UserProfile;

// UserProfile.test.js
import React from 'react';
import renderer from 'react-test-renderer'; // React komponent snapshotlari uchun
import UserProfile from './UserProfile';

test('UserProfile to\'g\'ri render qilinadi', () => {
  const user = {
    name: 'Jane Doe',
    email: 'jane.doe@example.com',
    isActive: true,
  };
  const component = renderer.create(
    <UserProfile {...user} />
  );
  const tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});

test('nofaol UserProfile to\'g\'ri render qilinadi', () => {
  const user = {
    name: 'John Smith',
    email: 'john.smith@example.com',
    isActive: false,
  };
  const component = renderer.create(
    <UserProfile {...user} />
  );
  const tree = component.toJSON();
  expect(tree).toMatchSnapshot('nofaol foydalanuvchi profili'); // Nomlangan snapshot
});

Testlarni ishga tushirgandan so'ng, Jest UserProfile.test.js.snap faylini yaratadi. Komponentni yangilaganingizda, o'zgarishlarni ko'rib chiqishingiz va Jest'ni --updateSnapshot yoki -u flugi bilan ishga tushirib, snapshotni yangilashingiz kerak bo'ladi.

Snapshot Testlash uchun Eng Yaxshi Amaliyotlar

Maxsus Mosliklar: Test O'qilishini Yaxshilash

Jest'ning o'rnatilgan mosliklari (matchers) keng qamrovli, ammo ba'zida siz qamrab olinmagan maxsus shartlarni tasdiqlashingiz kerak bo'ladi. Maxsus mosliklar sizga o'zingizning tasdiqlash mantig'ingizni yaratishga imkon beradi, bu esa testlaringizni yanada ifodali va o'qilishi oson qiladi.

Maxsus Mosliklarni Yaratish

Siz Jest'ning expect ob'ektini o'zingizning mosliklaringiz bilan kengaytirishingiz mumkin.

Misol: To'g'ri Email Formatini Tekshirish

Jest sozlash faylingizda (masalan, jest.config.js da sozlanadigan jest.setup.js):

// jest.setup.js

expect.extend({
  toBeValidEmail(received) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    const pass = emailRegex.test(received);

    if (pass) {
      return {
        message: () => `kutilgan ${received} to\'g\'ri email bo\'lmasligi kerak edi`,
        pass: true,
      };
    } else {
      return {
        message: () => `kutilgan ${received} to\'g\'ri email bo\'lishi kerak edi`,
        pass: false,
      };
    }
  },
});

// jest.config.js faylingizda
// module.exports = { setupFilesAfterEnv: ['/jest.setup.js'] };

Test faylingizda:

// validation.test.js

test('email formatlarini tasdiqlashi kerak', () => {
  expect('test@example.com').toBeValidEmail();
  expect('invalid-email').not.toBeValidEmail();
  expect('another.test@sub.domain.co.uk').toBeValidEmail();
});

Maxsus Mosliklarning Afzalliklari

Asinxron Operatsiyalarni Testlash

JavaScript asosan asinxrondir. Jest promiselar (promises) va async/await'ni testlash uchun ajoyib yordam beradi.

async/await dan Foydalanish

Bu asinxron kodni testlashning zamonaviy va eng o'qilishi oson usuli.

Misol: Asinxron Funksiyani Testlash

// dataService.js
export const fetchUserData = async (userId) => {
  // Ma'lumotlarni kechikish bilan olishni simulyatsiya qilish
  await new Promise(resolve => setTimeout(resolve, 50));
  if (userId === 1) {
    return { id: 1, name: 'Alice' };
  } else {
    throw new Error('Foydalanuvchi topilmadi');
  }
};

// dataService.test.js
import { fetchUserData } from './dataService';

test('foydalanuvchi ma\'lumotlarini to\'g\'ri oladi', async () => {
  const user = await fetchUserData(1);
  expect(user).toEqual({ id: 1, name: 'Alice' });
});

test('mavjud bo\'lmagan foydalanuvchi uchun xatolik chiqaradi', async () => {
  await expect(fetchUserData(2)).rejects.toThrow('Foydalanuvchi topilmadi');
});

.resolves va .rejects dan Foydalanish

Ushbu mosliklar promiselarning muvaffaqiyatli bajarilishi (resolutions) va rad etilishini (rejections) testlashni osonlashtiradi.

Misol: .resolves/.rejects dan Foydalanish

// dataService.test.js (davomi)

test('foydalanuvchi ma\'lumotlarini .resolves bilan oladi', () => {
  return expect(fetchUserData(1)).resolves.toEqual({ id: 1, name: 'Alice' });
});

test('mavjud bo\'lmagan foydalanuvchi uchun .rejects bilan xatolik chiqaradi', () => {
  return expect(fetchUserData(2)).rejects.toThrow('Foydalanuvchi topilmadi');
});

Taymerlarni Boshqarish

setTimeout yoki setInterval dan foydalanadigan funksiyalar uchun Jest taymerni boshqarishni ta'minlaydi.

Misol: Taymerlarni Boshqarish

// delayedGreeter.js
export const greetAfterDelay = (name, callback) => {
  setTimeout(() => {
    callback(`Salom, ${name}!`);
  }, 1000);
};

// delayedGreeter.test.js
import { greetAfterDelay } from './delayedGreeter';

jest.useFakeTimers(); // Soxta taymerlarni yoqish

test('kechikishdan keyin salom beradi', () => {
  const mockCallback = jest.fn();
  greetAfterDelay('Dunyo', mockCallback);

  // Taymerlarni 1000ms oldinga surish
  jest.advanceTimersByTime(1000);

  expect(mockCallback).toHaveBeenCalledTimes(1);
  expect(mockCallback).toHaveBeenCalledWith('Salom, Dunyo!');
});

// Agar boshqa joyda kerak bo'lsa, haqiqiy taymerlarni tiklash
jest.useRealTimers();

Testlarni Tashkil Qilish va Tuzilmasi

Testlar to'plami o'sib borishi bilan, qo'llab-quvvatlash uchun tashkillashtirish muhim ahamiyatga ega bo'ladi.

Describe Bloklari va It Bloklari

Bog'liq testlarni guruhlash uchun describe dan va alohida test holatlari uchun it (yoki test) dan foydalaning. Bu tuzilma ilovaning modulliligini aks ettiradi.

Misol: Tuzilgan Testlar

describe('Foydalanuvchi Autentifikatsiya Servisi', () => {
  let authService;

  beforeEach(() => {
    // Har bir testdan oldin mock'larni yoki servis nusxalarini sozlash
    authService = require('./authService');
    jest.spyOn(authService, 'login').mockImplementation(() => Promise.resolve({ token: 'fake_token' }));
  });

  afterEach(() => {
    // Mock'larni tozalash
    jest.restoreAllMocks();
  });

  describe('login funksionalligi', () => {
    it('to\'g\'ri ma\'lumotlar bilan foydalanuvchini muvaffaqiyatli tizimga kiritishi kerak', async () => {
      const result = await authService.login('user@example.com', 'password123');
      expect(result.token).toBeDefined();
      // ... ko'proq tasdiqlar ...
    });

    it('noto\'g\'ri ma\'lumotlar bilan tizimga kirishda xatolikka uchrashi kerak', async () => {
      jest.spyOn(authService, 'login').mockRejectedValue(new Error('Noto\'g\'ri ma\'lumotlar'));
      await expect(authService.login('user@example.com', 'wrong_password')).rejects.toThrow('Noto\'g\'ri ma\'lumotlar');
    });
  });

  describe('logout funksionalligi', () => {
    it('foydalanuvchi sessiyasini tozalashi kerak', async () => {
      // Chiqish mantig'ini testlash...
    });
  });
});

O'rnatish va Tozalash Xuklari (Hooks)

Bu xuklar soxta ma'lumotlarni, ma'lumotlar bazasi ulanishlarini sozlash yoki testlar orasida resurslarni tozalash uchun zarurdir.

Global Auditoriya uchun Testlash

Global auditoriya uchun ilovalar ishlab chiqilayotganda, testlash masalalari kengayadi:

Internatsionalizatsiya (i18n) va Lokalizatsiya (l10n)

Sizning UI va xabarlaringiz turli tillar va mintaqaviy formatlarga to'g'ri moslashishini ta'minlang.

Misol: Lokalizatsiya qilingan sana formatlashni testlash

// dateUtils.js
export const formatLocalizedDate = (date, locale) => {
  return new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'numeric', day: 'numeric' }).format(date);
};

// dateUtils.test.js
import { formatLocalizedDate } from './dateUtils';

test('AQSh lokali uchun sanani to\'g\'ri formatlaydi', () => {
  const date = new Date(2023, 10, 15); // 2023-yil 15-noyabr
  expect(formatLocalizedDate(date, 'en-US')).toBe('11/15/2023');
});

test('Germaniya lokali uchun sanani to\'g\'ri formatlaydi', () => {
  const date = new Date(2023, 10, 15);
  expect(formatLocalizedDate(date, 'de-DE')).toBe('15.11.2023');
});

Vaqt Mintaqasidan Xabardorlik

Ilovangizning turli vaqt mintaqalarini qanday boshqarishini testlang, ayniqsa rejalashtirish yoki real vaqtdagi yangilanishlar kabi xususiyatlar uchun. Tizim soatini soxtalashtirish yoki vaqt mintaqalarini abstraksiya qiluvchi kutubxonalardan foydalanish foydali bo'lishi mumkin.

Ma'lumotlardagi Madaniy Nyanslar

Raqamlar, valyutalar va boshqa ma'lumotlar ko'rinishlari turli madaniyatlarda qanday qabul qilinishi yoki kutilishi mumkinligini hisobga oling. Maxsus mosliklar bu yerda ayniqsa foydali bo'lishi mumkin.

Ilg'or Texnikalar va Strategiyalar

Testga Asoslangan Dasturlash (TDD) va Xulq-atvorga Asoslangan Dasturlash (BDD)

Jest TDD (Qizil-Yashil-Refaktor) va BDD (Berilgan-Qachon-Keyin) metodologiyalari bilan yaxshi mos keladi. Implementatsiya kodini yozishdan oldin kerakli xulq-atvorni tavsiflovchi testlarni yozing. Bu kodning boshidanoq testlanuvchanlikni hisobga olgan holda yozilishini ta'minlaydi.

Jest bilan Integratsion Testlash

Jest unit testlarda ustun bo'lsa-da, u integratsion testlar uchun ham ishlatilishi mumkin. Kamroq bog'liqliklarni soxtalashtirish yoki Jest'ning runInBand opsiyasi kabi vositalardan foydalanish yordam berishi mumkin.

Misol: API O'zaro Ta'sirini Testlash (soddalashtirilgan)

// apiService.js
import axios from 'axios';

const API_BASE_URL = 'https://api.example.com';

export const createProduct = async (productData) => {
  const response = await axios.post(`${API_BASE_URL}/products`, productData);
  return response.data;
};

// apiService.test.js (Integratsion test)
import axios from 'axios';
import { createProduct } from './apiService';

// Tarmoq qatlamini nazorat qilish uchun integratsion testlarda axios'ni soxtalashtirish
jest.mock('axios');

test('API orqali mahsulot yaratadi', async () => {
  const mockProduct = { id: 1, name: 'Gadget' };
  const responseData = { success: true, product: mockProduct };

  axios.post.mockResolvedValue({
    data: responseData,
    status: 201,
    headers: { 'content-type': 'application/json' },
  });

  const newProductData = { name: 'Gadget', price: 99.99 };
  const result = await createProduct(newProductData);

  expect(axios.post).toHaveBeenCalledWith(`${process.env.API_BASE_URL || 'https://api.example.com'}/products`, newProductData);
  expect(result).toEqual(responseData);
});

Parallellik va Konfiguratsiya

Jest bajarilishni tezlashtirish uchun testlarni parallel ravishda ishga tushirishi mumkin. Buni jest.config.js faylingizda sozlang. Masalan, maxWorkers ni o'rnatish parallel jarayonlar sonini nazorat qiladi.

Qamrov Hisobotlari

Kodingizning testlanmayotgan qismlarini aniqlash uchun Jest'ning o'rnatilgan qamrov hisobotidan foydalaning. Batafsil hisobotlarni yaratish uchun testlarni --coverage bilan ishga tushiring.

jest --coverage

Qamrov hisobotlarini ko'rib chiqish sizning ilg'or testlash andozalaringiz muhim logikani, shu jumladan internatsionalizatsiya va lokalizatsiya kod yo'llarini samarali qamrab olayotganiga ishonch hosil qilishga yordam beradi.

Xulosa

Ilg'or Jest testlash andozalarini o'zlashtirish global auditoriya uchun ishonchli, qo'llab-quvvatlanadigan va yuqori sifatli dasturiy ta'minot yaratish yo'lidagi muhim qadamdir. Mocking, snapshot testlash, maxsus mosliklar va asinxron testlash usullaridan samarali foydalangan holda, siz test to'plamingizning mustahkamligini oshirishingiz va turli stsenariylar va mintaqalarda ilovangizning xulq-atvoriga bo'lgan ishonchni oshirishingiz mumkin. Ushbu andozalarni o'zlashtirish butun dunyo bo'ylab dasturchilar jamoalariga ajoyib foydalanuvchi tajribasini taqdim etish imkonini beradi.

JavaScript testlash amaliyotlaringizni yuksaltirish uchun bugunoq ushbu ilg'or usullarni ish jarayoningizga kiritishni boshlang.