भाग 1: पाया (हिरवा, 1–4) · भाग 2: एका unit पलीकडे (जांभळा, 5–8) · भाग 3: tests किती चांगल्या आहेत (नारिंगी, 9–12). प्रत्येक आकृती खऱ्या, deterministic lab मधून काढलेली आहे — exam/demo.py जे आकडे छापते तेच — आणि प्रत्येकीखाली एक lab आहे जिथे तुम्ही स्वतः प्रश्न बदलू शकता. गोल केलेले क्रमांक 1 → 2 → 3 पाळा.
1 💸 test का करायचे
बाकावरच सापडलेला bug एका ओळीत सुधारतो; निकालपत्रे पाठवल्यानंतर सापडला तर 15 पुनर्छपाई लागतात. test काय सिद्ध करतो — आणि काय करू शकत नाही.
🧒 सोप्या शब्दांत
दीपिकाने गुणांचे grade बनवणारा code लिहिला. कतरिनाने त्याला 5 सोपे प्रश्न विचारले, आणि पाचही बरोबर आले. मग 1200 विद्यार्थ्यांनी 200 गुणांचा पेपर दिला. 34.5% असलेली मुलगी पास व्हायला हवी होती, पण code ने F सांगितले. 15 report cards चुकीचे आले. दीपिकाच्या डेस्कवर अजून एक प्रश्न विचारला असता तर हे एका मिनिटात पकडले गेले असते.
📖 नवे शब्दtest — code साठी exam question, ज्याचे बरोबर उत्तर आधीच माहीत असतेbug — code मधली चूक, जसे 34.5 ला D ऐवजी F मिळणेround half to even — Python चे round(): 34.5 वर 35 न जाता सम 34 वर जाते
⏪ आधी
दीपिकाने grade_v1 लिहिले आणि नजरेने तपासले; ते बरोबर दिसले, म्हणून ते थेट report cards छापायला गेले.
💡 काय
Test म्हणजे code साठी exam question, ज्याचे बरोबर उत्तर आधीच माहीत असते. grade_v1 पाच सोपे प्रश्न सोडवते: 5 पैकी 5.
⚙️ कसे
1200 विद्यार्थी, 200 गुणांचा पेपर: round(34.5) = 34, म्हणून 34.5, 44.5 आणि 74.5 वर 15 report cards चुकीचे येतात.
🎯 का
दीपिकाच्या डेस्कवर एक प्रश्न म्हणजे एक failing check; cards पाठवल्यानंतर 15 reprints आणि 5 माफीपत्रे.
🚀 पुढे
पुढच्या धड्यात खरा exam question: arrange, act, assert, आणि FAIL व ERROR तपासणारा छोटा runner.
🧪 इथे करून पाहा — संपूर्ण शाळा एक पेपर देते — पेपर, वर्ग आणि rounding बदला, आणि चुकीची निकालपत्रे मोजा
Arrange, act, assert — परीक्षेचा एक प्रश्न, एका छोट्या runner मध्ये आणि standard library च्या unittest मध्ये.
🧒 सोप्या शब्दांत
चांगल्या exam question च्या तीन पायऱ्या असतात. आधी तयारी: गुण 82 आहेत. मग एकदा विचारा: grade काय? मग answer key शी जुळवा: ते A हवे. कतरिनाने असे 4 प्रश्न लिहिले. दोन pass झाले. एकाचे उत्तर चुकले, तो FAIL. एकाने code crash केला, तो ERROR.
📖 नवे शब्दarrange · act · assert — तयारी करा, एकदा विचारा, मग answer key शी जुळवाFAIL — code ने चुकीचे उत्तर दिले, जसे A हवे असताना BERROR — test ला अपेक्षित नसताना code crash झालाtest runner — प्रत्येक test चालवून pass, FAIL किंवा ERROR लिहिणारा मदतनीस
⏪ आधी
तपासणी म्हणजे print() ओळी, ज्या कोणीतरी डोळ्यांनी वाचायच्या; छापलेला grade गुपचूप बदलला तरी कोणाला कळत नसे.
💡 काय
Unit test score ठरवते (arrange), grade_v1(score) एकदा चालवते (act), आणि answer key शी जुळवते (assert).
⚙️ कसे
कतरिनाचे 4 प्रश्न: 2 pass, 74.5 FAIL (अपेक्षित 'A', मिळाले 'B') आणि 101 ERROR: ValueError out of range.
🎯 का
FAIL म्हणजे चुकीचे उत्तर; ERROR म्हणजे test ला अपेक्षित नसलेला crash. unittest 6 tests चालवते: 0 failures, 0 errors.
🚀 पुढे
पुढचा धडा विचारतो कोणते प्रश्न लिहायचे: equivalence classes, boundary values आणि decision table.
🧪 इथे करून पाहा — परीक्षेचा एक प्रश्न लिहा — score ठरवा (arrange), एका version ने चालवा (act), उत्तर तपासा (assert)
Equivalence classes, boundary values आणि decision tables — आणि 34.5 वरचा rounding bug.
🧒 सोप्या शब्दांत
कतरिना प्रत्येक गुणाबद्दल विचारू शकत नाही. म्हणून ती गट करते: 45 ते 59 मधल्या सगळ्या गुणांना C, म्हणून एक प्रश्न पुरेसा. सात प्रश्न, सगळे pass. मग ती कडांवर विचारते: 34.4, 34.5 आणि 35. 34.5 वर code F म्हणतो पण नियम D म्हणतो. पकडले! चुका कडांवरच लपतात.
📖 नवे शब्दequivalence class — सारखे वागायला हवेत असे inputs चा गट, जसे C चे सगळे गुणboundary value — दोन गटांच्या कडेवरची किंमत, जसे 35 जवळचे 34.5decision table — प्रत्येक हो/नाही जोडीचा तक्ता: 3 अटींचे 8 नियम
⏪ आधी
कतरिनाने मनात आलेले गुण निवडले: 90, 65, 50, 40, 10. सगळे pass झाले, आणि rounding bug लपूनच राहिला.
💡 काय
Equivalence classes प्रत्येक band मधून एक गुण घेतात; boundary values प्रत्येक कडेच्या थोडे खाली, नेमके आणि वर विचारतात.
⚙️ कसे
34.5 वर grade_v1 म्हणते F, दुरुस्त grade म्हणते D. सर्व 201 half-marks पैकी v1 फक्त 34.5, 44.5 आणि 74.5 वर चुकते.
🎯 का
Bugs कडांवर राहतात. Decision table 3 हो/नाही अटींचे 8 नियम करते, म्हणून promotion चा कोणताही प्रकार सुटत नाही.
🚀 पुढे
पुढच्या धड्यात answer sheets तयार होतात: योग्य defaults असलेले builders, आणि प्रत्येक test साठी नवा fixture.
🧪 इथे करून पाहा — score कडांपर्यंत सरकवा; मग decision table च्या तीन अटी ठरवा
तयार उत्तरपत्रिका: builders, setup आणि teardown, आणि कोणत्याही क्रमाने pass होणारे tests.
🧒 सोप्या शब्दांत
परीक्षेपूर्वी office प्रत्येक विद्यार्थिनीसाठी answer sheet तयार करते. कतरिनाकडेही एक तयार विद्यार्थिनी आहे: चांगले गुण आणि 90% attendance. कमी attendance तपासायला ती फक्त तेच 60% करते. एकदा दोन प्रश्नांनी एकच sheet वापरली. पहिल्याने त्यावर ऐश्वर्याचे नाव लिहिले, आणि दुसऱ्याला ती कोरी हवी होती. म्हणून आता प्रत्येक प्रश्नाला नवी sheet मिळते.
📖 नवे शब्दfixture — test सुरू होण्यापूर्वी लागणारी तयार सामग्री, जसे कोरी answer sheetbuilder — सामान्य विद्यार्थिनी बनवणारा मदतनीस, म्हणजे test फक्त एकच गोष्ट बदलतेsetup and teardown — प्रत्येक test आधी नवी sheet द्या आणि नंतर परत घ्या
⏪ आधी
प्रत्येक test स्वतःची विद्यार्थिनी हाताने बनवत असे, आणि दोन tests एकच roll list वापरत, ज्यावर पहिलीने आधीच लिहिलेले असे.
💡 काय
Fixture म्हणजे तयार answer sheet. a_student() म्हणजे कतरिना: average 75.0, grade A, promoted True, 90% attendance.
⚙️ कसे
.with_attendance(60) ने promoted False होते; .with_medical_note() जोडल्यावर True. प्रत्येक test एकच गोष्ट बदलते.
🎯 का
एकच shared sheet: enrol → empty केल्यास 1 passed, 1 failed. प्रत्येक test ला नवी sheet: दोन्ही क्रमात 2 passed.
🚀 पुढे
पुढच्या धड्यात दूरच्या attendance service ऐवजी पर्यायी परीक्षक येतात: stub, fake, spy आणि mock.
🧪 इथे करून पाहा — a_student() मधून विद्यार्थिनी तयार करा, मग दोन tests सामायिक किंवा नव्या उत्तरपत्रिकेवर चालवा
बदली परीक्षक: stub, fake, spy आणि mock — आणि जास्त mocking मुळे चुकीच्या गोष्टीची test कशी होते.
🧒 सोप्या शब्दांत
खऱ्या attendance परीक्षिका दुसऱ्या इमारतीत बसतात आणि कधी कधी रजेवर असतात. म्हणून कतरिना पर्यायी परीक्षक वापरते. Stub कडे एकच card असते: 200 पैकी 172 दिवस. Fake कडे विद्यार्थिनींची छोटी चालणारी वही असते. Spy तिला विचारलेला प्रत्येक प्रश्न लिहून ठेवते. Mock ला एकच ठरलेला प्रश्न अपेक्षित असतो आणि दुसरा आला की ती तक्रार करते.
📖 नवे शब्दtest double — हळू किंवा दूरच्या गोष्टीच्या जागी वापरलेला पर्यायstub — नेहमी तेच ठरलेले उत्तर देणारा पर्यायfake — छोटा पण चालणारा पर्याय, जसे खरोखर विद्यार्थिनी शोधू शकणारी वहीmock — कोणता नेमका call येणार हे आधीच सांगितलेला पर्याय
⏪ आधी
प्रत्येक test खऱ्या attendance service ला बोलवत असे: हळू, कधी बंद, आणि ती रजेवर असली की test fail होत असे.
💡 काय
Test doubles म्हणजे पर्यायी परीक्षक: stub ठरलेले 172/200 देतो, fake विद्यार्थिनींची छोटी चालणारी dict ठेवतो.
⚙️ कसे
Stub: 86.0%, eligible True. Fake: pupil 7 ला 70.0%, eligible नाही. Spy '/attendance/42' नोंदवतो; 503 वर error.
🎯 का
URL मध्ये '?term=1' आले, उत्तरे तीच: fake test pass होते, mock test FAIL होते. त्याने 'काय' नव्हे, 'कसे' तपासले.
🚀 पुढे
पुढच्या धड्यात खोट्या marks book ऐवजी खरा SQLite database येतो, आणि fake मध्ये कधीच न येणारा bug सापडतो.
🧪 इथे करून पाहा — AttendanceClient मध्ये पर्यायी परीक्षक जोडा — आणि तो काय उत्तर देतो ते बदला
memory मधील खरा SQLite database fake ला न सापडलेला bug शोधतो: 67, 67.5 नाही.
🧒 सोप्या शब्दांत
कतरिनाला maths मध्ये 68 आणि दीपिकाला 67 मिळाले, म्हणून वर्गाची सरासरी 67.5. Python मधल्या खोट्या marks book ने 67.5 सांगितले. खऱ्या database ने 67 सांगितले! Database मध्ये पूर्ण संख्येला पूर्ण संख्येने भागले की अर्धा भाग गळतो. खोट्या वहीत हा bug कधीच येऊ शकला नसता. फक्त खऱ्या database सोबतच्या test ने तो शोधला.
📖 नवे शब्दintegration test — तुमचा code खऱ्या गोष्टीसोबत चालवणारी test, जसे databaseinteger division — पूर्ण संख्येला पूर्ण संख्येने भागणे, ज्यात अर्धा भाग जातो: 135 / 2 = 67constraint — database पाळायला लावतो असा नियम, जसे प्रत्येक विषयात एका विद्यार्थिनीचा एकच mark
⏪ आधी
दीपिकाने class average फक्त Python dict वर तपासले, म्हणून production मध्ये चालणाऱ्या SQL ला कोणीच प्रश्न विचारला नाही.
💡 काय
Integration test तुमचा code खऱ्या गोष्टीसोबत चालवते: इथे memory मध्ये तयार केलेला खरा SQLite database.
consumer त्याला काय हवे ते लिहून ठेवतो; provider प्रत्येक release त्याच्याशी तपासतो.
🧒 सोप्या शब्दांत
कतरिनाच्या report cards ना attendance office कडून दोन आकडे लागतात: हजर दिवस आणि एकूण दिवस. ती ते एका card वर लिहून office च्या भिंतीवर लावते. Office आपला form बदलण्यापूर्वी तो तिच्या card शी जुळवून पाहते. नवा रकाना जोडणे चालते. days_present चे नाव बदलणे किंवा 200 अक्षरात लिहिणे नवा form बाहेर जाण्यापूर्वीच पकडले जाते.
📖 नवे शब्दcontract — एक बाजू काय पाठवते आणि दुसरीला काय लागते याचे लेखी वचनconsumer — data वापरणारी बाजू, इथे report cardsprovider — data पाठवणारी बाजू, इथे attendance office
⏪ आधी
Attendance office ने आपला form बदलला आणि नंतर सांगितले; पहिल्याच दिवशी report cards बिघडले.
💡 काय
Consumer-driven contract: report cards स्वतःला काय लागते ते लिहून ठेवतात, days_present: int आणि days_total: int.
⚙️ कसे
Provider आपल्या CI मध्ये contract पुन्हा चालवतो: v1 pass, v2 late_days जोडूनही pass, v3 आणि v4 थांबवले जातात.
🎯 का
नवीन field चालते; नाव बदलणे ('present') किंवा type बदलणे (days_total मजकूर म्हणून) चालत नाही, ship आधीच पकडले जाते.
🚀 पुढे
पुढच्या धड्यात शाळेचा पूर्ण दिवस end to end चालतो, आणि suite मध्ये कोणत्या प्रकारच्या किती tests हव्यात ते पाहतो.
🧪 इथे करून पाहा — provider चा response बदला आणि consumer च्या कार्डाशी तपासा
End-to-end tests, आणि वेळ व flakiness मध्ये pyramid विरुद्ध trophy विरुद्ध ice-cream cone.
🧒 सोप्या शब्दांत
शाळा तपासायचे तीन मार्ग आहेत. डेस्कवरचा unit प्रश्न काही सेकंद घेतो. Marks book ची integration तपासणी थोडा जास्त वेळ घेते. शाळेचा पूर्ण दिवस सगळे एकत्र तपासतो, पण खूप वेळ लागतो आणि उशिरा आलेली bus तो बिघडवू शकते. म्हणून छोटे प्रश्न भरपूर आणि पूर्ण दिवस थोडेच ठेवा. बहुतेक पूर्ण दिवस म्हणजे वितळणारा ice-cream cone.
📖 नवे शब्दend-to-end test — database पासून report card पर्यंत पूर्ण app चालवणारी testtest pyramid — खूप unit tests, कमी integration tests, अगदी थोड्या e2e testsflaky failure — code शी काहीही संबंध नसलेल्या कारणाने fail होणारी test
⏪ आधी
Team बहुतेक पूर्ण app मधून click करून तपासत असे; प्रत्येक run ला खूप वेळ लागे आणि उशिरा आलेली bus ते वारंवार मोडत असे.
💡 काय
E2e test सगळे भाग एकत्र चालवते: database → attendance → report card, ऐश्वर्याला 74.33, B, promoted True.
⚙️ कसे
Cost model मध्ये pyramid ला एका run ला 60.0 s लागतात, trophy ला 80.8 s, आणि ice-cream cone ला 1005.2 s.
🎯 का
E2e tests जितक्या जास्त तितक्या flaky failures: pyramid चे 17% runs, trophy चे 23%, ice-cream cone चे 87%.
🚀 पुढे
पुढच्या धड्यात प्रश्न machine लिहिते: एक नियम सांगा, seed वरून 100 inputs तयार करा, आणि shrink करा.
🧪 इथे करून पाहा — suite ला आकार द्या — एक run किती वेळ घेतो, आणि किती वेळा flaky failure येते?
एक नियम सांगा, एका seed पासून 100 inputs generate करा, आणि failure ला सोप्या case पर्यंत shrink करा.
🧒 सोप्या शब्दांत
कतरिना एकेक प्रश्नाऐवजी एक नियम लिहिते: .5 ने संपणाऱ्या गुणाला पुढच्या पूर्ण संख्येइतकाच grade मिळायला हवा. एक प्रश्न-यंत्र 100 आकडे निवडून नियम तपासते. 9 व्या प्रयत्नात ते 74 निवडते: 74.5 ला B, पण 75 ला A. मग ते सोपी चूक शोधते: 44, मग 34. उत्तर 34.5, तोच जुना bug.
📖 नवे शब्दproperty — फक्त एका उदाहरणासाठी नव्हे, प्रत्येक input साठी खरा असायला हवा असा नियमseed — फाशांचा सुरुवातीचा आकडा, म्हणजे तेच 100 प्रश्न पुन्हा चालवता येतातshrinking — fail होणारा input अजून fail होणाऱ्या सोप्या input मध्ये बदलणे: 74 → 44 → 34
⏪ आधी
कतरिना प्रत्येक test score हाताने निवडत असे, म्हणून code ला फक्त तिला सुचलेल्या आकड्यांबद्दलच विचारले जाई.
💡 काय
Property-based testing एक नियम सांगते, grade(n + 0.5) == grade(n + 1), आणि seeded machine 100 random n तपासते.
⚙️ कसे
Seed 3 वर grade_v1 run 9 मध्ये 74.5 ला fail होते; shrinking लहान n वापरून 74 → 44 → 34, म्हणजे 34.5.
🎯 का
हाताने एकही score न निवडता धडा 03 चा bug सापडला; दुरुस्त grade 100 runs pass करते, आणि seed failure पुन्हा दाखवतो.
🚀 पुढे
पुढचा धडा tests नाच गुण देतो: 100% coverage असूनही चुका सुटू शकतात, ज्या mutation testing पकडते.
🧪 इथे करून पाहा — प्रश्नयंत्र — seed, code आणि नियम बदला; ते fail होताना आणि लहान होताना पाहा
100% line coverage जी 10 पैकी फक्त 4 mutants मारते — coverage काय चालले ते दाखवते, काय तपासले ते नाही.
🧒 सोप्या शब्दांत
कतरिनाला आपला exam paper चांगला आहे का ते जाणून घ्यायचे आहे. 7 प्रश्नांचा तिचा weak paper code ची प्रत्येक line चालवतो: 100%. मग ऐश्वर्या code च्या 10 copies बनवते, प्रत्येकीत एक छोटी पेरलेली चूक. Weak paper त्यातल्या फक्त 4 पकडतो. कडांवरचे प्रश्न असलेला strong paper 9 पकडतो. शेवटची तर खरी चूकच नाही.
📖 नवे शब्दcoverage — tests चालताना code च्या कोणत्या lines चालल्याmutant — एक छोटी पेरलेली चूक असलेली code ची copykilled — test ने mutant ची चूक ओळखली आणि fail झालीequivalent mutant — अगदी तसाच वागणारा बदल, म्हणून कोणतीही test तो पकडू शकत नाही
⏪ आधी
Team line coverage वर विश्वास ठेवत असे: tests चालताना प्रत्येक line चालली, तर paper पुरेसा चांगला मानला जाई.
💡 काय
Mutation testing grade() च्या एका copy मध्ये एक छोटी चूक पेरते, ज्याला mutant म्हणतात, आणि कोणती test ती ओळखते ते पाहते.
⚙️ कसे
7 प्रश्नांच्या WEAK suite ला 12/12 line coverage आहे, पण ती 10 पैकी फक्त 4 mutants मारते; 21 ची STRONG suite 9/10 मारते.
🎯 का
Coverage कोणत्या lines चालल्या ते दाखवते, काय तपासले ते नाही. शेवटचा survivor, s > 74, equivalent आहे: कोणतीही test त्याला मारू शकत नाही.
🚀 पुढे
पुढचा धडा code न बदलता pass आणि fail होणाऱ्या tests शोधतो: flaky tests चे हलणारे भिंतीवरचे घड्याळ.
🧪 इथे करून पाहा — प्रश्नपत्रिकेतील प्रश्न निवडा — coverage विरुद्ध मारलेले mutants
डुगडुगणारे घड्याळ: वेळ, क्रम, randomness आणि वाट पाहणे — पुन्हा चालवून सापडतात, त्यांना पक्के करून सुधारतात.
🧒 सोप्या शब्दांत
परीक्षा हॉलमधले घड्याळ हलते. बहुतेक दिवस ते बरोबर असते; काही दिवस ते उडी मारते. Flaky test अशीच असते: code बदलला नाही, पण निकाल बदलला. ऐश्वर्या प्रत्येक test 1000 वेळा चालवते. एक 33 वेळा fail होते, फक्त 23:00 नंतर. दुसरी एक list वाटून घेते आणि 6 पैकी 5 क्रमांत fail होते. ती बदलणारी गोष्ट शोधते आणि fixed clock ने ती बांधून ठेवते.
📖 नवे शब्दflaky test — त्याच code वर कधी pass तर कधी fail होणारी testrerun — flake पकडण्यासाठी काहीही न बदलता तीच test अनेकदा चालवणेinjected clock — code ला खरे घड्याळ वाचू न देता ठरलेली वेळ देणे
⏪ आधी
लाल build हिरवा होईपर्यंत पुन्हा चालवला जाई, आणि त्याच code ने वेगळे उत्तर का दिले हे कोणी विचारत नसे.
💡 काय
Flaky test त्याच code वर कधी pass तर कधी fail होते. ऐश्वर्या प्रत्येक test काहीही न बदलता 1000 वेळा चालवते.
⚙️ कसे
Time 33 वेळा fail (23:00 नंतर), randomness 36, 200 ms sleep 76, आणि shared ROLL वर 6 पैकी 5 test orders fail.
🎯 का
प्रत्येक flake मागे एक बदलणारी गोष्ट असते. ती बांधा: fixed clock ने 1000 passed, 0 failed; seed; 'done' ची वाट पाहा.
🚀 पुढे
पुढच्या धड्यात आधी test लिहिली जाते (red, green, refactor), आणि CI फक्त बदलाला लागणाऱ्या tests चालवते.
🧪 इथे करून पाहा — code न बदलता test पुन्हा चालवा — मग बदलणारी गोष्ट पक्की करा
Red, green, refactor; बदलाला लागू असलेलेच tests चालवा — आणि संपूर्ण चित्र.
🧒 सोप्या शब्दांत
एक नवा नियम येतो. कतरिना आधी 5 प्रश्न लिहिते, आणि पाचही fail होतात, कारण अजून code नाही. हे red. दीपिका सर्वात साधा code लिहिते: 5 पैकी 5 pass, green. मग ती तो नीटनेटका करते आणि तरीही 5 पैकी 5 pass. प्रत्येक बदलानंतर CI hall फक्त त्या बदलाला लागणाऱ्या tests चालवतो: 105 पैकी 28. Main मध्ये जाण्यापूर्वी सगळ्या 105 चालतात.
📖 नवे शब्दTDD — test-driven development: आधी fail होणारी test, मग codered · green · refactor — आधी fail, मग सर्वात साध्या code ने pass, मग न मोडता नीटनेटके करणेCI — प्रत्येक बदलावर tests आपोआप चालवणारा मदतनीसtest selection — बदलाचा परिणाम होऊ शकणाऱ्या tests च फक्त चालवणे
⏪ आधी
आधी code येत असे आणि tests नंतर, कधी कधी तर नाहीच; प्रत्येक बदलावर एकतर सगळ्या 105 tests चालत किंवा एकही नाही.
💡 काय
TDD: आधी 5 tests लिहा (red, 0/5), मग सर्वात साधा code (green, 5/5), मग तो नीटनेटका करा (refactor, तरीही 5/5).
⚙️ कसे
Test selection: attendance client मधील बदल 6 पैकी 3 suites, 105 पैकी 28 tests चालवतो; grade() मधील बदल 69 चालवतो.
🎯 का
Red सिद्ध करते की test fail होऊ शकते; CI lint → unit → integration → contract → e2e चालवते, पहिल्या red ला थांबते, main वर सगळ्या 105.
🚀 पुढे
पुढे कुठे: CI/CD school या tests खऱ्या pipelines मध्ये चालवते, आणि API school contracts design करते.
🧪 इथे करून पाहा — नवा नियम टप्प्याटप्प्याने TDD करा; मग बदल कशाला स्पर्श करतो ते निवडा