मराठी

जावास्क्रिप्टमध्ये टेस्ट-ड्रिव्हन डेव्हलपमेंट (TDD) मध्ये प्रावीण्य मिळवा. हे सर्वसमावेशक मार्गदर्शक रेड-ग्रीन-रिफॅक्टर सायकल, Jest सोबत प्रात्यक्षिक अंमलबजावणी आणि आधुनिक विकासासाठी सर्वोत्तम पद्धती समाविष्ट करते.

जावास्क्रिप्टमध्ये टेस्ट-ड्रिव्हन डेव्हलपमेंट: जागतिक डेव्हलपर्ससाठी एक सर्वसमावेशक मार्गदर्शक

या परिस्थितीची कल्पना करा: तुम्हाला एका मोठ्या, लेगसी सिस्टीममधील कोडच्या एका महत्त्वपूर्ण भागामध्ये बदल करण्याचे काम दिले आहे. तुम्हाला एक प्रकारची भीती वाटते. तुमच्या बदलामुळे दुसरे काहीतरी बिघडेल का? सिस्टीम अजूनही हेतूनुसार काम करत आहे याची खात्री तुम्ही कशी करू शकता? बदलाची ही भीती सॉफ्टवेअर डेव्हलपमेंटमधील एक सामान्य आजार आहे, ज्यामुळे अनेकदा प्रगती मंदावते आणि ॲप्लिकेशन्स नाजूक बनतात. पण जर आत्मविश्वासाने सॉफ्टवेअर तयार करण्याचा एक मार्ग असेल, ज्यामुळे चुका प्रोडक्शनपर्यंत पोहोचण्यापूर्वीच पकडल्या जातील अशी सुरक्षा जाळी तयार होईल तर? हेच टेस्ट-ड्रिव्हन डेव्हलपमेंट (TDD) चे वचन आहे.

TDD हे केवळ एक टेस्टिंग तंत्र नाही; तर ते सॉफ्टवेअर डिझाइन आणि डेव्हलपमेंटसाठी एक शिस्तबद्ध दृष्टिकोन आहे. हे पारंपारिक "आधी कोड लिहा, मग टेस्ट करा" मॉडेलला उलट करते. TDD सह, तुम्ही प्रोडक्शन कोड लिहिण्यापूर्वीच एक अयशस्वी होणारी टेस्ट लिहिता. या साध्या उलट्या क्रियेचे कोड गुणवत्ता, डिझाइन आणि देखभालीवर खोल परिणाम होतात. हे मार्गदर्शक व्यावसायिक डेव्हलपर्सच्या जागतिक प्रेक्षकांसाठी डिझाइन केलेले, जावास्क्रिप्टमध्ये TDD लागू करण्यावर एक व्यापक, व्यावहारिक दृष्टिकोन प्रदान करेल.

टेस्ट-ड्रिव्हन डेव्हलपमेंट (TDD) म्हणजे काय?

त्याच्या मुळाशी, टेस्ट-ड्रिव्हन डेव्हलपमेंट ही एक विकास प्रक्रिया आहे जी अगदी लहान विकास चक्राच्या पुनरावृत्तीवर अवलंबून असते. वैशिष्ट्ये लिहून नंतर त्यांची चाचणी करण्याऐवजी, TDD आग्रह धरते की टेस्ट प्रथम लिहिली जावी. ही टेस्ट अपरिहार्यपणे अयशस्वी होईल कारण ते वैशिष्ट्य अद्याप अस्तित्वात नाही. डेव्हलपरचे काम नंतर त्या विशिष्ट टेस्टला पास करण्यासाठी सर्वात सोपा संभाव्य कोड लिहिणे हे असते. एकदा ती पास झाली की, कोड स्वच्छ आणि सुधारित केला जातो. या मूलभूत लूपला "रेड-ग्रीन-रिफॅक्टर" सायकल म्हणून ओळखले जाते.

TDD ची लय: रेड-ग्रीन-रिफॅक्टर

हे तीन- चरणांचे चक्र TDD चे हृदय आहे. या लयीला समजून घेणे आणि त्याचा सराव करणे हे तंत्रात प्रभुत्व मिळवण्यासाठी मूलभूत आहे.

एकदा कार्यक्षमतेच्या एका लहान भागासाठी चक्र पूर्ण झाल्यावर, तुम्ही पुढील भागासाठी नवीन अयशस्वी टेस्टसह पुन्हा सुरुवात करता.

TDD चे तीन नियम

रॉबर्ट सी. मार्टिन (ज्यांना "अंकल बॉब" म्हणून ओळखले जाते), ॲजाइल सॉफ्टवेअर चळवळीतील एक प्रमुख व्यक्ती, यांनी तीन सोपे नियम परिभाषित केले जे TDD शिस्तीला संहिताबद्ध करतात:

  1. तुम्ही कोणताही प्रोडक्शन कोड लिहू नये, जोपर्यंत तो अयशस्वी युनिट टेस्ट पास करण्यासाठी नसेल.
  2. तुम्ही अयशस्वी होण्यासाठी पुरेशी असलेल्या युनिट टेस्टपेक्षा जास्त लिहू नये; आणि कंपायलेशनमधील अपयश हे अपयशच आहे.
  3. तुम्ही एका अयशस्वी युनिट टेस्टला पास करण्यासाठी पुरेशा असलेल्या प्रोडक्शन कोडपेक्षा जास्त लिहू नये.

या नियमांचे पालन केल्याने तुम्हाला रेड-ग्रीन-रिफॅक्टर चक्रात भाग पाडले जाते आणि हे सुनिश्चित होते की तुमचा १००% प्रोडक्शन कोड एका विशिष्ट, चाचणी केलेल्या आवश्यकतेची पूर्तता करण्यासाठी लिहिलेला आहे.

तुम्ही TDD का स्वीकारावे? जागतिक व्यावसायिक दृष्टिकोन

TDD वैयक्तिक डेव्हलपर्सना प्रचंड फायदे देत असले तरी, त्याची खरी शक्ती टीम आणि व्यावसायिक स्तरावर, विशेषतः जागतिक स्तरावर वितरीत केलेल्या वातावरणात लक्षात येते.

तुमचे जावास्क्रिप्ट TDD पर्यावरण सेट करणे

जावास्क्रिप्टमध्ये TDD सह प्रारंभ करण्यासाठी, तुम्हाला काही साधनांची आवश्यकता आहे. आधुनिक जावास्क्रिप्ट इकोसिस्टम उत्कृष्ट पर्याय प्रदान करते.

टेस्टिंग स्टॅकचे मुख्य घटक

त्याच्या साधेपणामुळे आणि ऑल-इन-वन स्वरूपामुळे, आम्ही आमच्या उदाहरणांसाठी Jest वापरू. "शून्य-कॉन्फिगरेशन" अनुभव शोधणाऱ्या टीम्ससाठी हा एक उत्कृष्ट पर्याय आहे.

Jest सह स्टेप-बाय-स्टेप सेटअप

चला TDD साठी एक नवीन प्रोजेक्ट सेट करूया.

1. तुमचा प्रोजेक्ट सुरू करा: तुमचा टर्मिनल उघडा आणि एक नवीन प्रोजेक्ट डिरेक्टरी तयार करा.

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

2. Jest स्थापित करा: Jest ला तुमच्या प्रोजेक्टमध्ये डेव्हलपमेंट डिपेन्डन्सी म्हणून जोडा.

npm install --save-dev jest

3. टेस्ट स्क्रिप्ट कॉन्फिगर करा: तुमची `package.json` फाईल उघडा. `"scripts"` विभाग शोधा आणि `"test"` स्क्रिप्टमध्ये बदल करा. `"test:watch"` स्क्रिप्ट जोडण्याची देखील अत्यंत शिफारस केली जाते, जी TDD वर्कफ्लोसाठी अमूल्य आहे.

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

`--watchAll` फ्लॅग Jest ला सांगतो की जेव्हाही फाईल सेव्ह केली जाईल तेव्हा आपोआप टेस्ट्स पुन्हा चालवा. हे त्वरित अभिप्राय प्रदान करते, जे रेड-ग्रीन-रिफॅक्टर सायकलसाठी परिपूर्ण आहे.

बस! तुमचे पर्यावरण तयार आहे. Jest `*.test.js`, `*.spec.js` नावाची किंवा `__tests__` डिरेक्टरीमध्ये असलेली टेस्ट फाइल्स आपोआप शोधेल.

TDD व्यवहारात: `CurrencyConverter` मॉड्यूल तयार करणे

चला TDD सायकलला एका व्यावहारिक, जागतिक स्तरावर समजण्याजोग्या समस्येवर लागू करूया: चलनांमध्ये पैशांचे रूपांतर करणे. आपण टप्प्याटप्प्याने `CurrencyConverter` मॉड्यूल तयार करू.

पुनरावृत्ती १: साधे, निश्चित-दर रूपांतरण

🔴 रेड: पहिली अयशस्वी टेस्ट लिहा

आमची पहिली आवश्यकता एका निश्चित दराचा वापर करून एका चलनातील विशिष्ट रक्कम दुसऱ्या चलनामध्ये रूपांतरित करणे आहे. `CurrencyConverter.test.js` नावाची एक नवीन फाईल तयार करा.

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

describe('CurrencyConverter', () => {
  it('USD ते EUR मध्ये रकमेचे योग्यरित्या रूपांतरण करावे', () => {
    // व्यवस्था (Arrange)
    const amount = 10; // 10 USD
    const expected = 9.2; // 1 USD = 0.92 EUR चा निश्चित दर गृहीत धरून

    // कृती (Act)
    const result = CurrencyConverter.convert(amount, 'USD', 'EUR');

    // पडताळणी (Assert)
    expect(result).toBe(expected);
  });
});

आता, तुमच्या टर्मिनलवरून टेस्ट वॉचर चालवा:

npm run test:watch

टेस्ट मोठ्या प्रमाणात अयशस्वी होईल. Jest `TypeError: Cannot read properties of undefined (reading 'convert')` असे काहीतरी कळवेल. ही आपली रेड स्थिती आहे. `CurrencyConverter` अस्तित्वात नसल्यामुळे टेस्ट अयशस्वी होते.

🟢 ग्रीन: पास होण्यासाठी सर्वात सोपा कोड लिहा

आता, चला टेस्ट पास करूया. `CurrencyConverter.js` तयार करा.

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

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

module.exports = CurrencyConverter;

तुम्ही ही फाईल सेव्ह करताच, Jest टेस्ट पुन्हा चालवेल आणि ती ग्रीन होईल. आम्ही टेस्टची आवश्यकता पूर्ण करण्यासाठी सर्वात कमीत कमी कोड लिहिला आहे.

🔵 रिफॅक्टर: कोडमध्ये सुधारणा करा

कोड सोपा आहे, पण आपण आधीच सुधारणांबद्दल विचार करू शकतो. नेस्टेड `rates` ऑब्जेक्ट थोडे कडक आहे. सध्यासाठी, ते पुरेसे स्वच्छ आहे. सर्वात महत्वाची गोष्ट म्हणजे आमच्याकडे एक कार्यरत वैशिष्ट्य आहे जे टेस्टद्वारे संरक्षित आहे. चला पुढच्या आवश्यकतेकडे वळूया.

पुनरावृत्ती २: अज्ञात चलनांना हाताळणे

🔴 रेड: अवैध चलनासाठी एक टेस्ट लिहा

जर आपण अशा चलनात रूपांतरित करण्याचा प्रयत्न केला जे आपल्याला माहित नाही, तर काय व्हायला पाहिजे? कदाचित एक एरर (त्रुटी) यायला हवी. चला `CurrencyConverter.test.js` मध्ये एका नवीन टेस्टमध्ये हे वर्तन परिभाषित करूया.

// CurrencyConverter.test.js मध्ये, describe ब्लॉकच्या आत

it('अज्ञात चलनांसाठी एक एरर द्यावी', () => {
  // व्यवस्था (Arrange)
  const amount = 10;

  // कृती आणि पडताळणी (Act & Assert)
  // Jest च्या toThrow ला काम करण्यासाठी, आपण फंक्शन कॉलला एका ॲरो फंक्शनमध्ये गुंडाळतो.
  expect(() => {
    CurrencyConverter.convert(amount, 'USD', 'XYZ');
  }).toThrow('Unknown currency: XYZ');
});

फाईल सेव्ह करा. टेस्ट रनर त्वरित एक नवीन अपयश दर्शवेल. ते रेड आहे कारण आपला कोड एरर देत नाही; तो `rates['USD']['XYZ']` ऍक्सेस करण्याचा प्रयत्न करतो, ज्यामुळे `TypeError` येतो. आमच्या नवीन टेस्टने ही त्रुटी अचूकपणे ओळखली आहे.

🟢 ग्रीन: नवीन टेस्ट पास करा

चला `CurrencyConverter.js` मध्ये बदल करून व्हॅलिडेशन जोडूया.

// 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]) {
      // चांगल्या एरर मेसेजसाठी कोणते चलन अज्ञात आहे ते निश्चित करा
      const unknownCurrency = !rates[from] ? from : to;
      throw new Error(`Unknown currency: ${unknownCurrency}`);
    }
    return amount * rates[from][to];
  }
};

module.exports = CurrencyConverter;

फाईल सेव्ह करा. दोन्ही टेस्ट्स आता पास होतील. आपण परत ग्रीन वर आलो आहोत.

🔵 रिफॅक्टर: ते स्वच्छ करा

आमचे `convert` फंक्शन वाढत आहे. व्हॅलिडेशन लॉजिक गणनेसह मिसळलेले आहे. वाचनीयता सुधारण्यासाठी आपण व्हॅलिडेशन एका वेगळ्या खाजगी फंक्शनमध्ये काढू शकतो, परंतु सध्यासाठी, ते अजूनही व्यवस्थापनीय आहे. मुख्य गोष्ट अशी आहे की आम्हाला हे बदल करण्याचे स्वातंत्र्य आहे कारण आमच्या टेस्ट्स आम्हाला सांगतील की आम्ही काही बिघडवले आहे का.

पुनरावृत्ती ३: असिंक्रोनस रेट फेचिंग

दर हार्डकोड करणे वास्तववादी नाही. चला आपले मॉड्यूल (मॉक केलेल्या) बाह्य API मधून दर आणण्यासाठी रिफॅक्टर करूया.

🔴 रेड: एक असिंक टेस्ट लिहा जी API कॉलला मॉक करते

प्रथम, आपल्याला आमचे कन्व्हर्टर पुन्हा संरचित करण्याची आवश्यकता आहे. ते आता एक क्लास असेल ज्याला आपण इन्स्टँशिएट करू शकतो, कदाचित एका API क्लायंटसह. आपल्याला `fetch` API ला मॉक करण्याची देखील आवश्यकता असेल. Jest हे सोपे करते.

चला या नवीन, असिंक्रोनस वास्तवाला सामावून घेण्यासाठी आपली टेस्ट फाईल पुन्हा लिहूया. आपण पुन्हा एकदा हॅपी पाथची चाचणी करून सुरुवात करू.

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

// बाह्य अवलंबित्व मॉक करा
global.fetch = jest.fn();

beforeEach(() => {
  // प्रत्येक टेस्टपूर्वी मॉक हिस्ट्री साफ करा
  fetch.mockClear();
});

describe('CurrencyConverter', () => {
  it('दर आणून योग्यरित्या रूपांतरित करावे', async () => {
    // व्यवस्था (Arrange)
    // यशस्वी API प्रतिसादाला मॉक करा
    fetch.mockResolvedValueOnce({
      json: () => Promise.resolve({ rates: { EUR: 0.92 } })
    });

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

    // कृती (Act)
    const result = await converter.convert(amount, 'USD', 'EUR');

    // पडताळणी (Assert)
    expect(result).toBe(9.2);
    expect(fetch).toHaveBeenCalledTimes(1);
    expect(fetch).toHaveBeenCalledWith('https://api.exchangerates.com/latest?base=USD');
  });

  // आम्ही API अयशस्वीतेसाठी इत्यादी चाचण्या देखील जोडू.
});

हे चालवल्याने रेडचा समुद्र दिसेल. आमचा जुना `CurrencyConverter` एक क्लास नाही, त्यात `async` मेथड नाही, आणि तो `fetch` वापरत नाही.

🟢 ग्रीन: असिंक लॉजिक लागू करा

आता, चला `CurrencyConverter.js` ला टेस्टच्या आवश्यकता पूर्ण करण्यासाठी पुन्हा लिहूया.

// 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('Failed to fetch exchange rates.');
    }

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

    if (!rate) {
      throw new Error(`Unknown currency: ${to}`);
    }

    // टेस्ट्समधील फ्लोटिंग पॉइंट समस्या टाळण्यासाठी साधे राउंडिंग
    const convertedAmount = amount * rate;
    return parseFloat(convertedAmount.toFixed(2));
  }
}

module.exports = CurrencyConverter;

जेव्हा तुम्ही सेव्ह कराल, तेव्हा टेस्ट ग्रीन व्हायला हवी. लक्षात घ्या की आम्ही फ्लोटिंग-पॉइंटच्या चुकीच्या गणनेला हाताळण्यासाठी राउंडिंग लॉजिक देखील जोडले आहे, जी आर्थिक गणनेमधील एक सामान्य समस्या आहे.

🔵 रिफॅक्टर: असिंक कोडमध्ये सुधारणा करा

`convert` मेथड बरेच काही करत आहे: फेचिंग, एरर हँडलिंग, पार्सिंग आणि गणना. आम्ही हे एका वेगळ्या `RateFetcher` क्लास तयार करून रिफॅक्टर करू शकतो जो केवळ API संवादासाठी जबाबदार असेल. आमचा `CurrencyConverter` नंतर हा फेचर वापरेल. हे सिंगल रिस्पॉन्सिबिलिटी प्रिन्सिपलचे अनुसरण करते आणि दोन्ही क्लासेसची चाचणी आणि देखभाल करणे सोपे करते. TDD आम्हाला या स्वच्छ डिझाइनकडे मार्गदर्शन करते.

सामान्य TDD पॅटर्न्स आणि अँटी-पॅटर्न्स

तुम्ही TDD चा सराव करत असताना, तुम्हाला चांगले काम करणारे पॅटर्न्स आणि घर्षण निर्माण करणारे अँटी-पॅटर्न्स सापडतील.

अनुसरण करण्यासाठी चांगले पॅटर्न्स

टाळण्यासाठी अँटी-पॅटर्न्स

व्यापक विकास जीवनचक्रात TDD

TDD एकाकी अस्तित्वात नाही. ते आधुनिक ॲजाइल आणि DevOps पद्धतींसोबत, विशेषतः जागतिक टीम्ससाठी, सुंदरपणे समाकलित होते.

निष्कर्ष: TDD सोबत तुमचा प्रवास

टेस्ट-ड्रिव्हन डेव्हलपमेंट ही एक टेस्टिंग रणनीतीपेक्षा अधिक आहे—ती सॉफ्टवेअर डेव्हलपमेंटकडे पाहण्याच्या दृष्टिकोनात एक आदर्श बदल आहे. ते गुणवत्ता, आत्मविश्वास आणि सहकार्याच्या संस्कृतीला प्रोत्साहन देते. रेड-ग्रीन-रिफॅक्टर सायकल एक स्थिर लय प्रदान करते जी तुम्हाला स्वच्छ, मजबूत आणि देखभाल करण्यायोग्य कोडकडे मार्गदर्शन करते. परिणामी टेस्ट सूट एक सुरक्षा जाळी बनते जी तुमच्या टीमला रिग्रेशनपासून संरक्षण देते आणि नवीन सदस्यांना ऑनबोर्ड करणारे जिवंत दस्तऐवजीकरण बनते.

शिकण्याचा वक्र उंच वाटू शकतो, आणि सुरुवातीचा वेग मंद वाटू शकतो. परंतु डीबगिंग वेळेत घट, सुधारित सॉफ्टवेअर डिझाइन आणि वाढलेला डेव्हलपर आत्मविश्वास यातील दीर्घकालीन लाभांश अगणित आहेत. TDD मध्ये प्रभुत्व मिळवण्याचा प्रवास शिस्त आणि सरावाचा आहे.

आजच सुरुवात करा. तुमच्या पुढच्या प्रोजेक्टमधील एक लहान, बिनमहत्त्वाचे वैशिष्ट्य निवडा आणि प्रक्रियेसाठी वचनबद्ध व्हा. आधी टेस्ट लिहा. ती अयशस्वी होताना पहा. ती पास करा. आणि मग, सर्वात महत्त्वाचे म्हणजे, रिफॅक्टर करा. ग्रीन टेस्ट सूटमधून मिळणाऱ्या आत्मविश्वासाचा अनुभव घ्या, आणि तुम्हाला लवकरच आश्चर्य वाटेल की तुम्ही यापूर्वी कधी वेगळ्या पद्धतीने सॉफ्टवेअर कसे तयार केले.