O'zbek

JavaScript-da Test-Asosida Dasturlashni (TDD) o'zlashtiring. Ushbu qo'llanma Qizil-Yashil-Refaktor sikli, Jest bilan amaliy qo'llash va zamonaviy dasturlashning eng yaxshi amaliyotlarini o'z ichiga oladi.

JavaScript-da Test-Asosida Dasturlash (TDD): Global Dasturchilar uchun To'liq Qo'llanma

Ushbu stsenariyni tasavvur qiling: sizga katta, eski tizimdagi muhim kod qismini o'zgartirish vazifasi yuklangan. Siz dahshat hissini tuyasiz. Sizning o'zgarishingiz boshqa narsani buzib qo'yadimi? Tizim hali ham kutilganidek ishlashiga qanday amin bo'lishingiz mumkin? O'zgarishlardan qo'rqish dasturiy ta'minotni ishlab chiqishda keng tarqalgan holat bo'lib, ko'pincha sekin rivojlanishga va mo'rt ilovalarga olib keladi. Ammo dasturiy ta'minotni ishonch bilan yaratishning, xatolarni ishlab chiqarishga yetib bormasdanoq ushlaydigan xavfsizlik tarmog'ini yaratishning yo'li bo'lsa-chi? Bu Test-Asosida Dasturlashning (TDD) va'dasidir.

TDD shunchaki testlash usuli emas; bu dasturiy ta'minotni loyihalash va ishlab chiqishga intizomli yondashuvdir. U an'anaviy "kod yoz, keyin testla" modelini teskari o'giradi. TDD bilan siz uni o'tkazish uchun ishlab chiqarish kodini yozishdan oldin muvaffaqiyatsizlikka uchraydigan test yozasiz. Bu oddiy teskari o'zgarish kod sifati, dizayni va texnik xizmat ko'rsatish uchun chuqur oqibatlarga olib keladi. Ushbu qo'llanma professional dasturchilarning global auditoriyasi uchun mo'ljallangan JavaScript-da TDD ni amalga oshirish bo'yicha keng qamrovli, amaliy ko'rinishni taqdim etadi.

Test-Asosida Dasturlash (TDD) nima?

O'z mohiyatiga ko'ra, Test-Asosida Dasturlash juda qisqa ishlab chiqish siklining takrorlanishiga tayanadigan ishlab chiqish jarayonidir. Xususiyatlarni yozib, keyin ularni testlash o'rniga, TDD avval test yozilishini talab qiladi. Bu test muqarrar ravishda muvaffaqiyatsizlikka uchraydi, chunki xususiyat hali mavjud emas. Shundan so'ng, dasturchining vazifasi aynan shu testni o'tkazish uchun eng oddiy kodni yozishdir. U o'tgandan so'ng, kod tozalanadi va yaxshilanadi. Bu asosiy sikl "Qizil-Yashil-Refaktor" sikli sifatida tanilgan.

TDD ritmi: Qizil-Yashil-Refaktor

Bu uch bosqichli sikl TDD ning yuragi hisoblanadi. Bu ritmni tushunish va amalda qo'llash ushbu texnikani o'zlashtirish uchun asosiy hisoblanadi.

Bir kichik funksionallik uchun sikl tugagandan so'ng, siz keyingi qism uchun yangi muvaffaqiyatsiz test bilan qaytadan boshlaysiz.

TDD ning Uch Qonuni

Robert C. Martin (ko'pincha "Uncle Bob" nomi bilan tanilgan), Agile dasturiy ta'minot harakatining asosiy shaxslaridan biri, TDD intizomini kodlashtiradigan uchta oddiy qoidani belgilab bergan:

  1. Siz muvaffaqiyatsiz unit testni o'tkazish uchun bo'lmasa, hech qanday ishlab chiqarish kodi yozmasligingiz kerak.
  2. Siz unit testni muvaffaqiyatsizlikka uchratish uchun yetarli bo'lganidan ortiq yozmasligingiz kerak; va kompilyatsiya xatolari ham muvaffaqiyatsizlikdir.
  3. Siz bitta muvaffaqiyatsiz unit testni o'tkazish uchun yetarli bo'lganidan ortiq ishlab chiqarish kodi yozmasligingiz kerak.

Ushbu qonunlarga rioya qilish sizni Qizil-Yashil-Refaktor sikliga majburlaydi va ishlab chiqarish kodingizning 100% aniq, testlangan talabni qondirish uchun yozilishini ta'minlaydi.

Nima uchun TDD ni qabul qilishingiz kerak? Global biznes uchun asos

TDD individual dasturchilarga ulkan foyda keltirsa-da, uning haqiqiy kuchi jamoa va biznes darajasida, ayniqsa global miqyosda tarqalgan muhitlarda namoyon bo'ladi.

JavaScript TDD muhitingizni sozlash

JavaScript-da TDD bilan ishlashni boshlash uchun sizga bir nechta vositalar kerak. Zamonaviy JavaScript ekotizimi ajoyib tanlovlarni taklif etadi.

Testlash stekining asosiy komponentlari

Oddiyligi va "hammasi birda" tabiati uchun biz misollarimizda Jest dan foydalanamiz. Bu "nol-konfiguratsiya" tajribasini izlayotgan jamoalar uchun ajoyib tanlov.

Jest bilan qadamma-qadam sozlash

Keling, TDD uchun yangi loyiha sozlaymiz.

1. Loyihangizni ishga tushiring: Terminalingizni oching va yangi loyiha katalogini yarating.

mkdir js-tdd-project
cd js-tdd-project
npm init -y

2. Jest-ni o'rnating: Jest-ni loyihangizga ishlab chiqish bog'liqligi sifatida qo'shing.

npm install --save-dev jest

3. Test skriptini sozlang: `package.json` faylingizni oching. `"scripts"` bo'limini toping va `"test"` skriptini o'zgartiring. TDD ish jarayoni uchun bebaho bo'lgan `"test:watch"` skriptini qo'shish ham juda tavsiya etiladi.

"scripts": {
  "test": "jest",
  "test:watch": "jest --watchAll"
}

`--watchAll` bayrog'i Jest-ga fayl saqlangan har safar testlarni avtomatik ravishda qayta ishga tushirishni aytadi. Bu Qizil-Yashil-Refaktor sikli uchun mukammal bo'lgan bir zumda fikr-mulohaza beradi.

Bo'ldi! Sizning muhitingiz tayyor. Jest avtomatik ravishda `*.test.js`, `*.spec.js` deb nomlangan yoki `__tests__` katalogida joylashgan test fayllarini topadi.

TDD amaliyotda: `CurrencyConverter` modulini yaratish

Keling, TDD siklini amaliy, global miqyosda tushunarli bo'lgan muammoga qo'llaymiz: valyutalar o'rtasida pul konvertatsiyasi. Biz `CurrencyConverter` modulini qadamma-qadam yaratamiz.

1-iteratsiya: Oddiy, qat'iy kursli konvertatsiya

πŸ”΄ QIZIL: Birinchi muvaffaqiyatsiz testni yozing

Bizning birinchi talabimiz - ma'lum bir miqdorni bir valyutadan boshqasiga qat'iy kurs yordamida o'zgartirish. `CurrencyConverter.test.js` nomli yangi fayl yarating.

// CurrencyConverter.test.js
const CurrencyConverter = require('./CurrencyConverter');

describe('CurrencyConverter', () => {
  it('miqdorni USD dan EUR ga to\'g\'ri o\'zgartirishi kerak', () => {
    // Tayyorgarlik
    const amount = 10; // 10 AQSH dollari
    const expected = 9.2; // 1 USD = 0.92 EUR qat'iy kursi deb faraz qilib

    // Amal
    const result = CurrencyConverter.convert(amount, 'USD', 'EUR');

    // Tasdiqlash
    expect(result).toBe(expected);
  });
});

Endi, terminalingizdan test kuzatuvchisini ishga tushiring:

npm run test:watch

Test ajoyib tarzda muvaffaqiyatsizlikka uchraydi. Jest `TypeError: Cannot read properties of undefined (reading 'convert')` kabi xabar beradi. Bu bizning QIZIL holatimiz. Test muvaffaqiyatsiz bo'ldi, chunki `CurrencyConverter` mavjud emas.

🟒 YASHIL: O'tish uchun eng oddiy kodni yozing

Endi, keling, testni o'tkazaylik. `CurrencyConverter.js` faylini yarating.

// CurrencyConverter.js
const rates = {
  USD: {
    EUR: 0.92
  }
};

const CurrencyConverter = {
  convert(amount, from, to) {
    return amount * rates[from][to];
  }
};

module.exports = CurrencyConverter;

Ushbu faylni saqlashingiz bilanoq, Jest testni qayta ishga tushiradi va u YASHIL rangga aylanadi. Biz test talabini qondirish uchun eng minimal kodni yozdik.

πŸ”΅ REFAKTOR: Kodni yaxshilang

Kod oddiy, ammo biz allaqachon yaxshilanishlar haqida o'ylashimiz mumkin. Ichki `rates` obyekti biroz qotib qolgan. Hozircha u yetarlicha toza. Eng muhimi, bizda test bilan himoyalangan ishlaydigan xususiyat bor. Keling, keyingi talabga o'taylik.

2-iteratsiya: Noma'lum valyutalarni qayta ishlash

πŸ”΄ QIZIL: Yaroqsiz valyuta uchun test yozing

Agar biz bilmaydigan valyutaga konvertatsiya qilishga harakat qilsak nima bo'lishi kerak? Ehtimol, xatolik chiqarishi kerak. Keling, bu xatti-harakatni `CurrencyConverter.test.js` dagi yangi testda belgilaymiz.

// CurrencyConverter.test.js da, describe bloki ichida

it('noma\'lum valyutalar uchun xatolik chiqarishi kerak', () => {
  // Tayyorgarlik
  const amount = 10;

  // Amal va Tasdiqlash
  // Jestning toThrow funksiyasi ishlashi uchun funksiya chaqiruvini o'q funksiyasiga o'raymiz.
  expect(() => {
    CurrencyConverter.convert(amount, 'USD', 'XYZ');
  }).toThrow('Noma\'lum valyuta: XYZ');
});

Faylni saqlang. Test yurituvchi darhol yangi nosozlikni ko'rsatadi. U QIZIL, chunki bizning kodimiz xatolik chiqarmaydi; u `rates['USD']['XYZ']` ga kirishga harakat qiladi, natijada `TypeError` kelib chiqadi. Bizning yangi testimiz bu kamchilikni to'g'ri aniqladi.

🟒 YASHIL: Yangi testni o'tkazing

Keling, tekshiruvni qo'shish uchun `CurrencyConverter.js` ni o'zgartiramiz.

// CurrencyConverter.js
const rates = {
  USD: {
    EUR: 0.92,
    GBP: 0.80
  },
  EUR: {
    USD: 1.08
  }
};

const CurrencyConverter = {
  convert(amount, from, to) {
    if (!rates[from] || !rates[from][to]) {
      // Yaxshiroq xato xabari uchun qaysi valyuta noma'lum ekanligini aniqlang
      const unknownCurrency = !rates[from] ? from : to;
      throw new Error(`Noma'lum valyuta: ${unknownCurrency}`);
    }
    return amount * rates[from][to];
  }
};

module.exports = CurrencyConverter;

Faylni saqlang. Endi ikkala test ham o'tadi. Biz YASHIL holatga qaytdik.

πŸ”΅ REFAKTOR: Uni tozalang

Bizning `convert` funksiyamiz o'sib bormoqda. Tekshirish mantig'i hisoblash bilan aralashib ketgan. O'qishni osonlashtirish uchun tekshirishni alohida xususiy funksiyaga chiqarishimiz mumkin, ammo hozircha u hali ham boshqariladigan darajada. Asosiysi shundaki, bizda bu o'zgarishlarni qilish erkinligi bor, chunki testlarimiz biror narsani buzganimizda bizga xabar beradi.

3-iteratsiya: Asinxron kurslarni olish

Kurslarni kodga qotirib qo'yish realistik emas. Keling, modulimizni (soxtalashtirilgan) tashqi API'dan kurslarni olish uchun refaktor qilamiz.

πŸ”΄ QIZIL: API chaqiruvini soxtalashtiradigan asinxron test yozing

Birinchidan, biz konverterimizni qayta tuzishimiz kerak. Endi u biz misol (instance) yaratishimiz mumkin bo'lgan klass bo'lishi kerak, ehtimol API mijozi bilan. Biz shuningdek `fetch` API'sini soxtalashtirishimiz kerak bo'ladi. Jest buni osonlashtiradi.

Keling, ushbu yangi, asinxron voqelikka moslashish uchun test faylimizni qayta yozamiz. Biz yana muvaffaqiyatli yo'lni testlashdan boshlaymiz.

// CurrencyConverter.test.js
const CurrencyConverter = require('./CurrencyConverter');

// Tashqi bog'liqlikni soxtalashtirish
global.fetch = jest.fn();

beforeEach(() => {
  // Har bir testdan oldin soxta tarixni tozalash
  fetch.mockClear();
});

describe('CurrencyConverter', () => {
  it('kurslarni olib kelishi va to\'g\'ri o\'zgartirishi kerak', async () => {
    // Tayyorgarlik
    // Muvaffaqiyatli API javobini soxtalashtirish
    fetch.mockResolvedValueOnce({
      json: () => Promise.resolve({ rates: { EUR: 0.92 } })
    });

    const converter = new CurrencyConverter('https://api.exchangerates.com');
    const amount = 10; // 10 AQSH dollari

    // Amal
    const result = await converter.convert(amount, 'USD', 'EUR');

    // Tasdiqlash
    expect(result).toBe(9.2);
    expect(fetch).toHaveBeenCalledTimes(1);
    expect(fetch).toHaveBeenCalledWith('https://api.exchangerates.com/latest?base=USD');
  });

  // Shuningdek, API nosozliklari uchun testlar qo'shamiz va hokazo.
});

Buni ishga tushirish QIZIL dengiziga olib keladi. Bizning eski `CurrencyConverter` klass emas, `async` metodga ega emas va `fetch` dan foydalanmaydi.

🟒 YASHIL: Asinxron mantiqni amalga oshiring

Endi, keling, test talablariga javob berish uchun `CurrencyConverter.js` ni qayta yozamiz.

// CurrencyConverter.js
class CurrencyConverter {
  constructor(apiUrl) {
    this.apiUrl = apiUrl;
  }

  async convert(amount, from, to) {
    const response = await fetch(`${this.apiUrl}/latest?base=${from}`);
    if (!response.ok) {
      throw new Error('Valyuta kurslarini olishda xatolik yuz berdi.');
    }

    const data = await response.json();
    const rate = data.rates[to];

    if (!rate) {
      throw new Error(`Noma'lum valyuta: ${to}`);
    }

    // Testlarda suzuvchi nuqta muammolarini oldini olish uchun oddiy yaxlitlash
    const convertedAmount = amount * rate;
    return parseFloat(convertedAmount.toFixed(2));
  }
}

module.exports = CurrencyConverter;

Saqlaganingizda, test YASHIL rangga o'tishi kerak. E'tibor bering, biz moliyaviy hisob-kitoblarda keng tarqalgan muammo bo'lgan suzuvchi nuqta noaniqliklarini bartaraf etish uchun yaxlitlash mantig'ini ham qo'shdik.

πŸ”΅ REFAKTOR: Asinxron kodni yaxshilang

`convert` metodi ko'p ish qilmoqda: ma'lumot olish, xatoliklarni qayta ishlash, tahlil qilish va hisoblash. Biz buni faqat API aloqasi uchun mas'ul bo'lgan alohida `RateFetcher` klassini yaratish orqali refaktor qilishimiz mumkin. Keyin bizning `CurrencyConverter` bu fetcher-dan foydalanadi. Bu Yagona Mas'uliyat Printsipiga amal qiladi va ikkala klassni ham testlash va saqlashni osonlashtiradi. TDD bizni ushbu toza dizaynga yo'naltiradi.

Umumiy TDD Namunalar va Anti-Namunalar

TDD bilan shug'ullanar ekansiz, yaxshi ishlaydigan namunalarni va ishqalanishga olib keladigan anti-namunalarni kashf etasiz.

Amal qilish kerak bo'lgan yaxshi namunalar

Qochish kerak bo'lgan anti-namunalar

Kengroq Rivojlanish Hayot Siklida TDD

TDD vakuumda mavjud emas. U zamonaviy Agile va DevOps amaliyotlari bilan, ayniqsa global jamoalar uchun go'zal tarzda birlashadi.

Xulosa: TDD bilan sayohatingiz

Test-Asosida Dasturlash testlash strategiyasidan ko'ra ko'proq narsaβ€”bu bizning dasturiy ta'minotni ishlab chiqishga bo'lgan yondashuvimizdagi paradigma o'zgarishidir. U sifat, ishonch va hamkorlik madaniyatini shakllantiradi. Qizil-Yashil-Refaktor sikli sizni toza, mustahkam va qo'llab-quvvatlanadigan kod sari yo'naltiradigan barqaror ritmni ta'minlaydi. Natijada paydo bo'lgan testlar to'plami jamoangizni regressiyalardan himoya qiladigan xavfsizlik tarmog'iga va yangi a'zolarni ishga tushiradigan jonli hujjatlarga aylanadi.

O'rganish egri chizig'i tik tuyulishi mumkin va dastlabki sur'at sekinroq ko'rinishi mumkin. Ammo nosozliklarni tuzatish vaqtini qisqartirish, dasturiy ta'minot dizaynini yaxshilash va dasturchi ishonchini oshirishdagi uzoq muddatli dividendlar beqiyosdir. TDD ni o'zlashtirish sayohati intizom va amaliyotdan iborat.

Bugundan boshlang. Keyingi loyihangizda bitta kichik, muhim bo'lmagan xususiyatni tanlang va jarayonga sodiq qoling. Avval test yozing. Uning muvaffaqiyatsiz bo'lishini kuzating. Uni o'tkazing. Va keyin, eng muhimi, refaktor qiling. Yashil testlar to'plamidan kelib chiqadigan ishonchni his eting va tez orada dasturiy ta'minotni boshqa yo'l bilan qanday yaratganingizga hayron bo'lasiz.

JavaScript-da Test-Asosida Dasturlash (TDD): Global Dasturchilar uchun To'liq Qo'llanma | MLOG