జావాస్క్రిప్ట్లో టెస్ట్-డ్రివెన్ డెవలప్మెంట్ (TDD)లో నైపుణ్యం సాధించండి. ఈ సమగ్ర మార్గదర్శి రెడ్-గ్రీన్-రీఫ్యాక్టర్ సైకిల్, జెస్ట్తో ఆచరణాత్మక అమలు మరియు ఆధునిక అభివృద్ధికి ఉత్తమ పద్ధతులను వివరిస్తుంది.
జావాస్క్రిప్ట్లో టెస్ట్-డ్రివెన్ డెవలప్మెంట్: గ్లోబల్ డెవలపర్ల కోసం ఒక సమగ్ర మార్గదర్శి
ఈ పరిస్థితిని ఊహించుకోండి: మీరు ఒక పెద్ద, లెగసీ సిస్టమ్లో ఒక కీలకమైన కోడ్ను మార్చే పనిలో ఉన్నారు. మీకు ఒక రకమైన భయం కలుగుతుంది. మీ మార్పు మరేదైనా విఫలం చేస్తుందా? సిస్టమ్ ఇప్పటికీ ఉద్దేశించిన విధంగా పనిచేస్తుందని మీరు ఎలా నిర్ధారించుకోగలరు? ఈ మార్పు భయం సాఫ్ట్వేర్ డెవలప్మెంట్లో ఒక సాధారణ రుగ్మత, ఇది తరచుగా నెమ్మది పురోగతికి మరియు పెళుసైన అప్లికేషన్లకు దారితీస్తుంది. కానీ లోపాలను ఉత్పత్తికి చేరకముందే పట్టుకునే ఒక భద్రతా వలయాన్ని సృష్టిస్తూ, విశ్వాసంతో సాఫ్ట్వేర్ను నిర్మించడానికి ఒక మార్గం ఉంటే? ఇదే టెస్ట్-డ్రివెన్ డెవలప్మెంట్ (TDD) యొక్క వాగ్దానం.
TDD కేవలం ఒక టెస్టింగ్ టెక్నిక్ కాదు; ఇది సాఫ్ట్వేర్ డిజైన్ మరియు డెవలప్మెంట్కు ఒక క్రమశిక్షణతో కూడిన విధానం. ఇది సాంప్రదాయ "కోడ్ రాయండి, తర్వాత టెస్ట్ చేయండి" మోడల్ను తారుమారు చేస్తుంది. TDDతో, మీరు ప్రొడక్షన్ కోడ్ పాస్ చేయడానికి ముందు విఫలమయ్యే టెస్ట్ ను రాస్తారు. ఈ సాధారణ తారుమారు కోడ్ నాణ్యత, డిజైన్ మరియు నిర్వహణ సామర్థ్యంపై లోతైన ప్రభావాలను చూపుతుంది. ఈ గైడ్ వృత్తిపరమైన డెవలపర్ల గ్లోబల్ ప్రేక్షకులకు రూపొందించబడిన, జావాస్క్రిప్ట్లో TDDను అమలు చేయడానికి ఒక సమగ్ర, ఆచరణాత్మక రూపాన్ని అందిస్తుంది.
టెస్ట్-డ్రివెన్ డెవలప్మెంట్ (TDD) అంటే ఏమిటి?
దాని మూలంలో, టెస్ట్-డ్రివెన్ డెవలప్మెంట్ అనేది చాలా చిన్న డెవలప్మెంట్ సైకిల్ను పునరావృతం చేయడంపై ఆధారపడిన ఒక డెవలప్మెంట్ ప్రక్రియ. ఫీచర్లను రాసి, ఆపై వాటిని టెస్ట్ చేయడానికి బదులుగా, TDD ముందుగా టెస్ట్ రాయాలని నొక్కి చెబుతుంది. ఈ టెస్ట్ తప్పనిసరిగా విఫలమవుతుంది ఎందుకంటే ఫీచర్ ఇంకా ఉనికిలో లేదు. డెవలపర్ పని ఆ నిర్దిష్ట టెస్ట్ పాస్ చేయడానికి సాధ్యమైనంత సులభమైన కోడ్ను రాయడం. అది పాస్ అయిన తర్వాత, కోడ్ శుభ్రపరచబడి మరియు మెరుగుపరచబడుతుంది. ఈ ప్రాథమిక లూప్ను "రెడ్-గ్రీన్-రీఫ్యాక్టర్" సైకిల్ అని పిలుస్తారు.
TDD యొక్క లయ: రెడ్-గ్రీన్-రీఫ్యాక్టర్
ఈ మూడు-దశల చక్రం TDD యొక్క హృదయ స్పందన. ఈ లయను అర్థం చేసుకోవడం మరియు సాధన చేయడం ఈ టెక్నిక్లో నైపుణ్యం సాధించడానికి ప్రాథమికం.
- 🔴 రెడ్ — ఒక విఫలమయ్యే టెస్ట్ రాయండి: మీరు ఒక కొత్త కార్యాచరణ కోసం ఆటోమేటెడ్ టెస్ట్ రాయడంతో ప్రారంభిస్తారు. ఈ టెస్ట్ మీరు కోడ్ ఏమి చేయాలనుకుంటున్నారో నిర్వచించాలి. మీరు ఇంకా ఎలాంటి ఇంప్లిమెంటేషన్ కోడ్ రాయలేదు కాబట్టి, ఈ టెస్ట్ విఫలమవడం ఖాయం. ఒక విఫలమయ్యే టెస్ట్ సమస్య కాదు; అది పురోగతి. ఇది టెస్ట్ సరిగ్గా పనిచేస్తోందని (అది విఫలం కాగలదు) రుజువు చేస్తుంది మరియు తదుపరి దశకు స్పష్టమైన, నిర్దిష్ట లక్ష్యాన్ని నిర్దేశిస్తుంది.
- 🟢 గ్రీన్ — పాస్ చేయడానికి సరళమైన కోడ్ రాయండి: మీ లక్ష్యం ఇప్పుడు ఏకవచనం: టెస్ట్ పాస్ చేయడం. టెస్ట్ను రెడ్ నుండి గ్రీన్కు మార్చడానికి అవసరమైన కనీస ప్రొడక్షన్ కోడ్ను మీరు రాయాలి. ఇది విరుద్ధంగా అనిపించవచ్చు; కోడ్ సొగసైనదిగా లేదా సమర్థవంతంగా ఉండకపోవచ్చు. అది ఫర్వాలేదు. ఇక్కడ దృష్టి కేవలం టెస్ట్ ద్వారా నిర్వచించబడిన అవసరాన్ని నెరవేర్చడంపై మాత్రమే ఉంటుంది.
- 🔵 రీఫ్యాక్టర్ — కోడ్ను మెరుగుపరచండి: ఇప్పుడు మీకు పాస్ అయిన టెస్ట్ ఉంది, మీకు ఒక భద్రతా వలయం ఉంది. కార్యాచరణను విఫలం చేస్తామనే భయం లేకుండా మీరు మీ కోడ్ను నమ్మకంగా శుభ్రపరచవచ్చు మరియు మెరుగుపరచవచ్చు. ఇక్కడే మీరు కోడ్ స్మెల్స్ ను పరిష్కరిస్తారు, నకిలీని తొలగిస్తారు, స్పష్టతను మెరుగుపరుస్తారు మరియు పనితీరును ఆప్టిమైజ్ చేస్తారు. మీరు ఏ రిగ్రెషన్లను ప్రవేశపెట్టలేదని నిర్ధారించుకోవడానికి రీఫ్యాక్టరింగ్ సమయంలో ఏ సమయంలోనైనా మీ టెస్ట్ సూట్ను అమలు చేయవచ్చు. రీఫ్యాక్టరింగ్ తర్వాత, అన్ని టెస్ట్లు ఇప్పటికీ గ్రీన్లో ఉండాలి.
ఒక చిన్న కార్యాచరణకు చక్రం పూర్తయిన తర్వాత, మీరు తదుపరి భాగం కోసం కొత్త విఫలమయ్యే టెస్ట్తో మళ్ళీ ప్రారంభిస్తారు.
TDD యొక్క మూడు సూత్రాలు
ఎజైల్ సాఫ్ట్వేర్ ఉద్యమంలో కీలక వ్యక్తి అయిన రాబర్ట్ సి. మార్టిన్ (తరచుగా "అంకుల్ బాబ్" అని పిలుస్తారు), TDD క్రమశిక్షణను క్రోడీకరించే మూడు సాధారణ నియమాలను నిర్వచించారు:
- విఫలమయ్యే యూనిట్ టెస్ట్ను పాస్ చేయడానికి తప్ప, మీరు ఏ ప్రొడక్షన్ కోడ్నూ రాయకూడదు.
- విఫలం కావడానికి సరిపోయే దానికంటే ఎక్కువ యూనిట్ టెస్ట్ను మీరు రాయకూడదు; మరియు కంపైలేషన్ వైఫల్యాలు కూడా వైఫల్యాలే.
- ఒక విఫలమయ్యే యూనిట్ టెస్ట్ను పాస్ చేయడానికి సరిపోయే దానికంటే ఎక్కువ ప్రొడక్షన్ కోడ్ను మీరు రాయకూడదు.
ఈ నియమాలను అనుసరించడం మిమ్మల్ని రెడ్-గ్రీన్-రీఫ్యాక్టర్ సైకిల్లోకి బలవంతం చేస్తుంది మరియు మీ ప్రొడక్షన్ కోడ్ 100% ఒక నిర్దిష్ట, పరీక్షించిన అవసరాన్ని సంతృప్తి పరచడానికి వ్రాయబడిందని నిర్ధారిస్తుంది.
మీరు TDDని ఎందుకు స్వీకరించాలి? గ్లోబల్ బిజినెస్ కేస్
TDD వ్యక్తిగత డెవలపర్లకు అపారమైన ప్రయోజనాలను అందించినప్పటికీ, దాని నిజమైన శక్తి బృందం మరియు వ్యాపార స్థాయిలో, ముఖ్యంగా ప్రపంచవ్యాప్తంగా పంపిణీ చేయబడిన వాతావరణాలలో గ్రహించబడుతుంది.
- పెరిగిన విశ్వాసం మరియు వేగం: ఒక సమగ్ర టెస్ట్ సూట్ ఒక భద్రతా వలయంగా పనిచేస్తుంది. ఇది జట్లకు కొత్త ఫీచర్లను జోడించడానికి లేదా ఉన్నవాటిని నమ్మకంగా రీఫ్యాక్టర్ చేయడానికి అనుమతిస్తుంది, ఇది అధిక స్థిరమైన అభివృద్ధి వేగానికి దారితీస్తుంది. మీరు మాన్యువల్ రిగ్రెషన్ టెస్టింగ్ మరియు డీబగ్గింగ్పై తక్కువ సమయం గడుపుతారు మరియు విలువను అందించడానికి ఎక్కువ సమయం గడుపుతారు.
- మెరుగైన కోడ్ డిజైన్: మొదట టెస్ట్లు రాయడం మీ కోడ్ ఎలా ఉపయోగించబడుతుందనే దాని గురించి ఆలోచించేలా చేస్తుంది. మీ స్వంత API యొక్క మొదటి వినియోగదారు మీరే. ఇది సహజంగా చిన్న, మరింత కేంద్రీకృత మాడ్యూల్స్ మరియు స్పష్టమైన బాధ్యతల విభజనతో మెరుగ్గా రూపొందించిన సాఫ్ట్వేర్కు దారితీస్తుంది.
- జీవించే డాక్యుమెంటేషన్: వేర్వేరు టైమ్ జోన్లు మరియు సంస్కృతులలో పనిచేస్తున్న గ్లోబల్ బృందం కోసం, స్పష్టమైన డాక్యుమెంటేషన్ కీలకం. బాగా వ్రాసిన టెస్ట్ సూట్ అనేది జీవించే, అమలు చేయగల డాక్యుమెంటేషన్ యొక్క ఒక రూపం. ఒక కొత్త డెవలపర్ ఒక కోడ్ ముక్క ఏమి చేయాలో మరియు వివిధ సందర్భాలలో అది ఎలా ప్రవర్తిస్తుందో ఖచ్చితంగా అర్థం చేసుకోవడానికి టెస్ట్లను చదవగలడు. సాంప్రదాయ డాక్యుమెంటేషన్ వలె కాకుండా, ఇది ఎప్పటికీ పాతదిగా మారదు.
- తగ్గిన మొత్తం యాజమాన్య ఖర్చు (TCO): డెవలప్మెంట్ సైకిల్లో ముందుగా పట్టుబడిన బగ్స్, ప్రొడక్షన్లో కనుగొనబడిన వాటి కంటే ఘాతాంకపరంగా చౌకగా సరిచేయబడతాయి. TDD ఒక పటిష్టమైన వ్యవస్థను సృష్టిస్తుంది, ఇది కాలక్రమేణా నిర్వహించడం మరియు విస్తరించడం సులభం, ఇది సాఫ్ట్వేర్ యొక్క దీర్ఘకాలిక TCOని తగ్గిస్తుంది.
మీ జావాస్క్రిప్ట్ TDD పర్యావరణాన్ని ఏర్పాటు చేయడం
జావాస్క్రిప్ట్లో TDDతో ప్రారంభించడానికి, మీకు కొన్ని సాధనాలు అవసరం. ఆధునిక జావాస్క్రిప్ట్ పర్యావరణ వ్యవస్థ అద్భుతమైన ఎంపికలను అందిస్తుంది.
టెస్టింగ్ స్టాక్ యొక్క ముఖ్య భాగాలు
- టెస్ట్ రన్నర్: మీ టెస్ట్లను కనుగొని అమలు చేసే ప్రోగ్రామ్. ఇది నిర్మాణం (`describe` మరియు `it` బ్లాక్ల వంటివి) అందిస్తుంది మరియు ఫలితాలను నివేదిస్తుంది. జెస్ట్ మరియు మోకా రెండు అత్యంత ప్రజాదరణ పొందిన ఎంపికలు.
- అసెర్షన్ లైబ్రరీ: మీ కోడ్ ఆశించిన విధంగా ప్రవర్తిస్తుందని ధృవీకరించడానికి ఫంక్షన్లను అందించే ఒక సాధనం. ఇది `expect(result).toBe(true)` వంటి స్టేట్మెంట్లను రాయడానికి మిమ్మల్ని అనుమతిస్తుంది. చాయ్ ఒక ప్రసిద్ధ స్టాండలోన్ లైబ్రరీ, అయితే జెస్ట్ దాని స్వంత శక్తివంతమైన అసెర్షన్ లైబ్రరీని కలిగి ఉంటుంది.
- మాకింగ్ లైబ్రరీ: API కాల్స్ లేదా డేటాబేస్ కనెక్షన్ల వంటి డిపెండెన్సీల "నకిలీలను" సృష్టించే సాధనం. ఇది మీ కోడ్ను ఒంటరిగా పరీక్షించడానికి మిమ్మల్ని అనుమతిస్తుంది. జెస్ట్ లో అద్భుతమైన అంతర్నిర్మిత మాకింగ్ సామర్థ్యాలు ఉన్నాయి.
దాని సరళత మరియు ఆల్-ఇన్-వన్ స్వభావం కోసం, మేము మా ఉదాహరణల కోసం జెస్ట్ ఉపయోగిస్తాము. ఇది "జీరో-కాన్ఫిగరేషన్" అనుభవాన్ని కోరుకునే బృందాలకు అద్భుతమైన ఎంపిక.
జెస్ట్తో దశలవారీగా సెటప్
TDD కోసం కొత్త ప్రాజెక్ట్ను ఏర్పాటు చేద్దాం.
1. మీ ప్రాజెక్ట్ను ప్రారంభించండి: మీ టెర్మినల్ తెరిచి కొత్త ప్రాజెక్ట్ డైరెక్టరీని సృష్టించండి.
mkdir js-tdd-project
cd js-tdd-project
npm init -y
2. జెస్ట్ను ఇన్స్టాల్ చేయండి: మీ ప్రాజెక్ట్కు జెస్ట్ను డెవలప్మెంట్ డిపెండెన్సీగా జోడించండి.
npm install --save-dev jest
3. టెస్ట్ స్క్రిప్ట్ను కాన్ఫిగర్ చేయండి: మీ `package.json` ఫైల్ను తెరవండి. `"scripts"` విభాగాన్ని కనుగొని, `"test"` స్క్రిప్ట్ను సవరించండి. TDD వర్క్ఫ్లో కోసం అమూల్యమైన `"test:watch"` స్క్రిప్ట్ను జోడించడం కూడా బాగా సిఫార్సు చేయబడింది.
"scripts": {
"test": "jest",
"test:watch": "jest --watchAll"
}
`--watchAll` ఫ్లాగ్ జెస్ట్కు ఫైల్ సేవ్ చేయబడినప్పుడల్లా టెస్ట్లను ఆటోమేటిక్గా తిరిగి అమలు చేయమని చెబుతుంది. ఇది తక్షణ ఫీడ్బ్యాక్ను అందిస్తుంది, ఇది రెడ్-గ్రీన్-రీఫ్యాక్టర్ సైకిల్ కోసం ఖచ్చితంగా సరిపోతుంది.
అంతే! మీ పర్యావరణం సిద్ధంగా ఉంది. జెస్ట్ `*.test.js`, `*.spec.js` అని పేరు పెట్టబడిన లేదా `__tests__` డైరెక్టరీలో ఉన్న టెస్ట్ ఫైల్లను ఆటోమేటిక్గా కనుగొంటుంది.
TDD ఆచరణలో: `CurrencyConverter` మాడ్యూల్ను నిర్మించడం
TDD చక్రాన్ని ఒక ఆచరణాత్మక, ప్రపంచవ్యాప్తంగా అర్థమయ్యే సమస్యకు వర్తింపజేద్దాం: కరెన్సీల మధ్య డబ్బును మార్చడం. మేము దశలవారీగా ఒక `CurrencyConverter` మాడ్యూల్ను నిర్మిస్తాము.
మొదటి పునరావృతం: సాధారణ, స్థిర-రేటు మార్పిడి
🔴 రెడ్: మొదటి విఫలమయ్యే టెస్ట్ రాయండి
మా మొదటి అవసరం ఒక నిర్దిష్ట మొత్తాన్ని ఒక కరెన్సీ నుండి మరొక దానికి స్థిర రేటు ఉపయోగించి మార్చడం. `CurrencyConverter.test.js` అనే కొత్త ఫైల్ను సృష్టించండి.
// CurrencyConverter.test.js
const CurrencyConverter = require('./CurrencyConverter');
describe('CurrencyConverter', () => {
it('should convert an amount from USD to EUR correctly', () => {
// Arrange
const amount = 10; // 10 USD
const expected = 9.2; // Assuming a fixed rate of 1 USD = 0.92 EUR
// Act
const result = CurrencyConverter.convert(amount, 'USD', 'EUR');
// Assert
expect(result).toBe(expected);
});
});
ఇప్పుడు, మీ టెర్మినల్ నుండి టెస్ట్ వాచర్ను అమలు చేయండి:
npm run test:watch
టెస్ట్ ఘోరంగా విఫలమవుతుంది. జెస్ట్ `TypeError: Cannot read properties of undefined (reading 'convert')` వంటిది నివేదిస్తుంది. ఇది మా RED స్థితి. `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;
మీరు ఈ ఫైల్ను సేవ్ చేసిన వెంటనే, జెస్ట్ టెస్ట్ను తిరిగి అమలు చేస్తుంది మరియు అది GREEN గా మారుతుంది. మేము టెస్ట్ యొక్క అవసరాన్ని సంతృప్తి పరచడానికి కనీస కోడ్ను రాశాము.
🔵 రీఫ్యాక్టర్: కోడ్ను మెరుగుపరచండి
కోడ్ సరళమైనది, కానీ మనం ఇప్పటికే మెరుగుదలల గురించి ఆలోచించవచ్చు. నెస్టెడ్ `rates` ఆబ్జెక్ట్ కొద్దిగా కఠినంగా ఉంది. ప్రస్తుతానికి, ఇది తగినంత శుభ్రంగా ఉంది. ముఖ్యమైన విషయం ఏమిటంటే, మనకు ఒక టెస్ట్ ద్వారా రక్షించబడిన వర్కింగ్ ఫీచర్ ఉంది. తదుపరి అవసరానికి వెళ్దాం.
రెండవ పునరావృతం: తెలియని కరెన్సీలను నిర్వహించడం
🔴 రెడ్: చెల్లని కరెన్సీ కోసం టెస్ట్ రాయండి
మనకు తెలియని కరెన్సీకి మార్చడానికి ప్రయత్నిస్తే ఏమి జరగాలి? ఇది బహుశా ఒక ఎర్రర్ను త్రో చేయాలి. ఈ ప్రవర్తనను `CurrencyConverter.test.js`లో కొత్త టెస్ట్లో నిర్వచిద్దాం.
// In CurrencyConverter.test.js, inside the describe block
it('should throw an error for unknown currencies', () => {
// Arrange
const amount = 10;
// Act & Assert
// We wrap the function call in an arrow function for Jest's toThrow to work.
expect(() => {
CurrencyConverter.convert(amount, 'USD', 'XYZ');
}).toThrow('Unknown currency: XYZ');
});
ఫైల్ను సేవ్ చేయండి. టెస్ట్ రన్నర్ వెంటనే కొత్త వైఫల్యాన్ని చూపుతుంది. ఇది RED ఎందుకంటే మా కోడ్ ఎర్రర్ను త్రో చేయదు; అది `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]) {
// Determine which currency is unknown for a better error message
const unknownCurrency = !rates[from] ? from : to;
throw new Error(`Unknown currency: ${unknownCurrency}`);
}
return amount * rates[from][to];
}
};
module.exports = CurrencyConverter;
ఫైల్ను సేవ్ చేయండి. ఇప్పుడు రెండు టెస్ట్లు పాస్ అవుతాయి. మేము తిరిగి GREEN కి వచ్చాము.
🔵 రీఫ్యాక్టర్: దాన్ని శుభ్రపరచండి
మా `convert` ఫంక్షన్ పెరుగుతోంది. ధ్రువీకరణ తర్కం గణనతో మిళితమై ఉంది. చదవడానికి వీలుగా ధ్రువీకరణను ఒక ప్రత్యేక ప్రైవేట్ ఫంక్షన్లోకి సంగ్రహించవచ్చు, కానీ ప్రస్తుతానికి, ఇది ఇంకా నిర్వహించదగినది. ముఖ్యమైన విషయం ఏమిటంటే, మాకు ఈ మార్పులు చేసే స్వేచ్ఛ ఉంది ఎందుకంటే మేము ఏదైనా విఫలం చేస్తే మా టెస్ట్లు మాకు చెబుతాయి.
మూడవ పునరావృతం: అసమకాలిక రేటు ఫెచింగ్
రేట్లను హార్డ్కోడ్ చేయడం వాస్తవికం కాదు. మా మాడ్యూల్ను (మాక్ చేసిన) బాహ్య API నుండి రేట్లను పొందేందుకు రీఫ్యాక్టర్ చేద్దాం.
🔴 రెడ్: API కాల్ను మాక్ చేసే అసింక్ టెస్ట్ రాయండి
మొదట, మన కన్వర్టర్ను పునర్నిర్మించాలి. ఇది ఇప్పుడు మనం ఇన్స్టాన్షియేట్ చేయగల ఒక క్లాస్ కావాలి, బహుశా ఒక API క్లయింట్తో. మనకు `fetch` APIని మాక్ చేయాల్సి ఉంటుంది. జెస్ట్ దీన్ని సులభం చేస్తుంది.
ఈ కొత్త, అసమకాలిక వాస్తవికతకు అనుగుణంగా మన టెస్ట్ ఫైల్ను తిరిగి వ్రాద్దాం. మేము మళ్లీ హ్యాపీ పాత్ను పరీక్షించడం ద్వారా ప్రారంభిస్తాము.
// CurrencyConverter.test.js
const CurrencyConverter = require('./CurrencyConverter');
// Mock the external dependency
global.fetch = jest.fn();
beforeEach(() => {
// Clear mock history before each test
fetch.mockClear();
});
describe('CurrencyConverter', () => {
it('should fetch rates and convert correctly', async () => {
// Arrange
// Mock the successful API response
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');
});
// We'd also add tests for API failures, etc.
});
దీన్ని అమలు చేయడం వలన RED సముద్రం వస్తుంది. మా పాత `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}`);
}
// Simple rounding to avoid floating point issues in tests
const convertedAmount = amount * rate;
return parseFloat(convertedAmount.toFixed(2));
}
}
module.exports = CurrencyConverter;
మీరు సేవ్ చేసినప్పుడు, టెస్ట్ GREEN గా మారాలి. ఫైనాన్షియల్ గణనలలో ఒక సాధారణ సమస్య అయిన ఫ్లోటింగ్-పాయింట్ అవాస్తవాలను నిర్వహించడానికి మేము రౌండింగ్ లాజిక్ను కూడా జోడించామని గమనించండి.
🔵 రీఫ్యాక్టర్: అసింక్ కోడ్ను మెరుగుపరచండి
`convert` మెథడ్ చాలా పనులు చేస్తోంది: ఫెచింగ్, ఎర్రర్ హ్యాండ్లింగ్, పార్సింగ్ మరియు గణన. కేవలం API కమ్యూనికేషన్కు బాధ్యత వహించే ప్రత్యేక `RateFetcher` క్లాస్ను సృష్టించడం ద్వారా దీనిని మనం రీఫ్యాక్టర్ చేయవచ్చు. మా `CurrencyConverter` అప్పుడు ఈ ఫెచర్ను ఉపయోగిస్తుంది. ఇది సింగిల్ రెస్పాన్సిబిలిటీ ప్రిన్సిపల్ను అనుసరిస్తుంది మరియు రెండు క్లాస్లను పరీక్షించడం మరియు నిర్వహించడం సులభం చేస్తుంది. TDD మనల్ని ఈ శుభ్రమైన డిజైన్ వైపు నడిపిస్తుంది.
సాధారణ TDD పద్ధతులు మరియు వ్యతిరేక-పద్ధతులు
మీరు TDD సాధన చేస్తున్నప్పుడు, బాగా పనిచేసే పద్ధతులు మరియు ఘర్షణకు కారణమయ్యే వ్యతిరేక-పద్ధతులను మీరు కనుగొంటారు.
అనుసరించాల్సిన మంచి పద్ధతులు
- అరేంజ్, యాక్ట్, అసర్ట్ (AAA): మీ టెస్ట్లను మూడు స్పష్టమైన భాగాలుగా cấu trúc చేయండి. మీ సెటప్ను అరేంజ్ చేయండి, టెస్ట్ కింద ఉన్న కోడ్ను అమలు చేయడం ద్వారా యాక్ట్ చేయండి, మరియు ఫలితం సరిగ్గా ఉందని అసర్ట్ చేయండి. ఇది టెస్ట్లను చదవడం మరియు అర్థం చేసుకోవడం సులభం చేస్తుంది.
- ఒక సమయంలో ఒక ప్రవర్తనను పరీక్షించండి: ప్రతి టెస్ట్ కేస్ ఒకే, నిర్దిష్ట ప్రవర్తనను ధృవీకరించాలి. ఇది టెస్ట్ విఫలమైనప్పుడు ఏమి విరిగిపోయిందో స్పష్టంగా చేస్తుంది.
- వివరణాత్మక టెస్ట్ పేర్లను ఉపయోగించండి: `it('మొత్తం ప్రతికూలంగా ఉంటే ఎర్రర్ త్రో చేయాలి')` వంటి టెస్ట్ పేరు `it('test 1')` కన్నా చాలా విలువైనది.
నివారించాల్సిన వ్యతిరేక-పద్ధతులు
- అమలు వివరాలను పరీక్షించడం: టెస్ట్లు పబ్లిక్ API ("ఏమిటి") పై దృష్టి పెట్టాలి, ప్రైవేట్ అమలు ("ఎలా") పై కాదు. ప్రైవేట్ పద్ధతులను పరీక్షించడం మీ టెస్ట్లను పెళుసుగా మరియు రీఫ్యాక్టరింగ్ను కష్టతరం చేస్తుంది.
- రీఫ్యాక్టర్ దశను విస్మరించడం: ఇది అత్యంత సాధారణ తప్పు. రీఫ్యాక్టరింగ్ను దాటవేయడం మీ ప్రొడక్షన్ కోడ్ మరియు మీ టెస్ట్ సూట్ రెండింటిలోనూ సాంకేతిక రుణానికి దారితీస్తుంది.
- పెద్ద, నెమ్మదిగా ఉండే టెస్ట్లు రాయడం: యూనిట్ టెస్ట్లు వేగంగా ఉండాలి. అవి నిజమైన డేటాబేస్లు, నెట్వర్క్ కాల్స్ లేదా ఫైల్ సిస్టమ్లపై ఆధారపడితే, అవి నెమ్మదిగా మరియు నమ్మదగనివిగా మారతాయి. మీ యూనిట్లను వేరు చేయడానికి మాక్లు మరియు స్టబ్లను ఉపయోగించండి.
విస్తృత డెవలప్మెంట్ లైఫ్సైకిల్లో TDD
TDD శూన్యంలో ఉనికిలో లేదు. ఇది ఆధునిక ఎజైల్ మరియు DevOps పద్ధతులతో, ముఖ్యంగా గ్లోబల్ బృందాల కోసం అందంగా కలిసిపోతుంది.
- TDD మరియు ఎజైల్: మీ ప్రాజెక్ట్ మేనేజ్మెంట్ సాధనం నుండి ఒక యూజర్ స్టోరీ లేదా అంగీకార ప్రమాణం నేరుగా విఫలమయ్యే టెస్ట్ల శ్రేణిగా అనువదించబడవచ్చు. ఇది మీరు వ్యాపారం కోరిన దాన్ని ఖచ్చితంగా నిర్మిస్తున్నారని నిర్ధారిస్తుంది.
- TDD మరియు నిరంతర ఇంటిగ్రేషన్/నిరంతర డిప్లాయ్మెంట్ (CI/CD): TDD ఒక నమ్మకమైన CI/CD పైప్లైన్కు పునాది. ఒక డెవలపర్ కోడ్ను పుష్ చేసిన ప్రతిసారీ, ఒక ఆటోమేటెడ్ సిస్టమ్ (GitHub యాక్షన్స్, GitLab CI, లేదా జెంకిన్స్ వంటివి) మొత్తం టెస్ట్ సూట్ను అమలు చేయగలదు. ఏదైనా టెస్ట్ విఫలమైతే, బిల్డ్ ఆపివేయబడుతుంది, బగ్స్ ప్రొడక్షన్కు చేరకుండా నివారిస్తుంది. ఇది టైమ్ జోన్లతో సంబంధం లేకుండా మొత్తం బృందానికి వేగవంతమైన, ఆటోమేటెడ్ ఫీడ్బ్యాక్ను అందిస్తుంది.
- TDD vs. BDD (బిహేవియర్-డ్రివెన్ డెవలప్మెంట్): BDD అనేది TDD యొక్క పొడిగింపు, ఇది డెవలపర్లు, QA, మరియు వ్యాపార వాటాదారుల మధ్య సహకారంపై దృష్టి పెడుతుంది. ఇది ప్రవర్తనను వివరించడానికి సహజ భాషా ఫార్మాట్ (గివెన్-వెన్-దెన్) ను ఉపయోగిస్తుంది. తరచుగా, ఒక BDD ఫీచర్ ఫైల్ అనేక TDD-శైలి యూనిట్ టెస్ట్ల సృష్టికి దారి తీస్తుంది.
ముగింపు: TDDతో మీ ప్రయాణం
టెస్ట్-డ్రివెన్ డెవలప్మెంట్ ఒక టెస్టింగ్ వ్యూహం కంటే ఎక్కువ—ఇది మనం సాఫ్ట్వేర్ డెవలప్మెంట్ను సంప్రదించే విధానంలో ఒక నమూనా మార్పు. ఇది నాణ్యత, విశ్వాసం మరియు సహకారం యొక్క సంస్కృతిని పెంపొందిస్తుంది. రెడ్-గ్రీన్-రీఫ్యాక్టర్ సైకిల్ మిమ్మల్ని శుభ్రమైన, పటిష్టమైన మరియు నిర్వహించదగిన కోడ్ వైపు నడిపించే స్థిరమైన లయను అందిస్తుంది. ఫలితంగా వచ్చే టెస్ట్ సూట్ మీ బృందాన్ని రిగ్రెషన్ల నుండి రక్షించే భద్రతా వలయంగా మరియు కొత్త సభ్యులను ఆన్బోర్డ్ చేసే జీవించే డాక్యుమెంటేషన్గా మారుతుంది.
నేర్చుకునే వక్రరేఖ నిటారుగా అనిపించవచ్చు, మరియు ప్రారంభ వేగం నెమ్మదిగా అనిపించవచ్చు. కానీ డీబగ్గింగ్ సమయం తగ్గడంలో, మెరుగైన సాఫ్ట్వేర్ డిజైన్లో, మరియు పెరిగిన డెవలపర్ విశ్వాసంలో దీర్ఘకాలిక లాభాలు అపారమైనవి. TDDలో నైపుణ్యం సాధించే ప్రయాణం క్రమశిక్షణ మరియు అభ్యాసంతో కూడుకున్నది.
ఈరోజే ప్రారంభించండి. మీ తదుపరి ప్రాజెక్ట్లో ఒక చిన్న, క్లిష్టమైనది కాని ఫీచర్ను ఎంచుకుని, ప్రక్రియకు కట్టుబడి ఉండండి. మొదట టెస్ట్ రాయండి. అది విఫలమవ్వడం చూడండి. దానిని పాస్ అయ్యేలా చేయండి. ఆపై, ముఖ్యంగా, రీఫ్యాక్టర్ చేయండి. గ్రీన్ టెస్ట్ సూట్ నుండి వచ్చే విశ్వాసాన్ని అనుభవించండి, మరియు మీరు ఇంతకు ముందు సాఫ్ట్వేర్ను మరే విధంగా ఎలా నిర్మించారో అని త్వరలో ఆశ్చర్యపోతారు.