Step by step kya-kya padhaya gaya hai
- Testing — Motivation & Terminologies: testing kyun zaroori hai, test case kya hota hai (I, S, R), test suite, testing ki activities, test cases "design" kyun karte hain, aur testing ke levels ka intro.
- Unit Testing: unit testing kyun, kab, kaun karta hai. Testing environment = stub + driver. Phir pytest ka pura demo — assert, fixtures, exceptions, mocking.
- Blackbox & Whitebox Testing: equivalence classes, boundary value analysis (blackbox) aur branch / multiple condition / path coverage + cyclomatic complexity (whitebox).
- Integration & System Testing: Big Bang, Bottom-Up, Top-Down, Mixed. Phir alpha, beta, acceptance, smoke aur performance/stress testing.
- Test-Driven Development (TDD): pehle test likho, phir code. RED → GREEN → REFACTOR mantra.
Pehle ke weeks me focus tha "building the right thing" (requirements, user stories). Ab focus shift hota hai "building it right" — yaani jo bana rahe ho, wo sach me sahi kaam kar raha hai ya nahi.
Testing — Motivation aur Terminologies
Yeh foundation lecture hai. Isme jitne bhi terms aate hain (test case, test suite, levels), wo poore week me baar-baar use honge — isliye yahan thoda dhyaan se.
Testing kyun important hai?
Software me chhoti si error bhi pura system crash kara sakti hai. Lecture me do classic examples diye gaye:
- Integer overflow jaisi simple si galti se poore system ka crash.
- Real-world failures — airport system failure aur spacecraft crash. Inme crore-crore ka nuksaan hua sirf bugs ki wajah se.
Matlab: testing "optional extra" nahi hai, development ka core part hai.
Testing me hum basically karte kya hain?
Socho tumne koi assignment ka program submit kiya. Tumne kya kiya tha? Yehi 7 steps:
Program ko kuch values do, jo output aaya usko expected output se compare karo.
Agar mismatch hai to wo failure hai. Ab dhoondo galti kahan hai aur kyun hai.
Code badlo aur phir se saare test cases chalao.
Test Case = Triplet [I, S, R]
Yeh sabse zyada poocha jaane wala definition hai. Ek test case sirf "input" nahi hota — teen cheezein hoti hain:
| Symbol | Kya hai | Seller Portal ka example |
|---|---|---|
I | Input — jo data program ko diya jaata hai | Item ki details bhari (name, price, qty) aur "Add Item" click kiya |
S | State — program us waqt kis state me hai | User login ho chuka hai aur catalog page par hai |
R | Result expected — program se kya output expected hai | Catalog page naye item ke saath update ho jaana chahiye |
Test Suite = ek given program ko test karne ke liye design kiye gaye saare test cases ka set. Yaani test case = 1 unit, test suite = collection.
Log sirf "input → output" yaad rakhte hain aur State (S) bhool jaate hain. MCQ me "which is NOT part of a test case" type question aata hai — execution time, developer name, code coverage jaise distractors ke saath. Answer: sirf I, S, R hi hain.
Testing activities ka summary
- Test suite design — appropriate test cases socho aur banao.
- Run test cases & check results — har test case chalao, expected vs actual compare karo. Mismatch = failure, note kar lo.
- Locate error — jo test fail hua, developer usko dekh kar error dhoondta hai.
- Error correction — code fix karo, phir se test karo.
Note: yeh kaam tester karta hai aur developer ko report karta hai — par bahut baar tester aur developer same hi banda hota hai.
Test cases "design" kyun karein? Random ya exhaustive kyun nahi?
Do sawaal aate hain, dono ka jawab lecture me hai:
❌ Random testing kaafi nahi hai
Bahut saare random values daal dene se guarantee nahi milti ki zyadatar errors pakde jaayenge. Classic example:
# Sahi program — min of two values if (x < y): min = x else: min = y # Buggy program — else me bhi x hai! if (x < y): min = x else: min = x <-- BUG
Agar tumhare random values me hamesha x < y hi nikla — jaise (1,2), (3,4), (1000,10000) — to
ye bug kabhi pakda hi nahi jaayega. Bug tab pakdega jab koi aisi value aaye jahan y < x ho.
Aur wo shayad tab pata chale jab software production me chal raha ho. 😬
❌ Exhaustive testing possible nahi hai
Kisi bhi software system me input values ka domain bahut bada hota hai — saari possible values test karna practically impossible.
✅ Isliye: minimal test suite design karo
Aisa minimal test suite banao jisme har test case ka ek specific kaam ho — har test case ek particular type ki error pakadne ke liye designed ho. Kam test cases, par har ek meaningful.
Test case design ke 2 raste
Blackbox Testing
Sirf input–output behaviour analyse karo. Code ke andar bilkul mat jhaanko. Program ek black box hai — tumhe bas pata hai ki wo karta kya hai.
Min example: aise pairs do jinme relationship alag ho — (a) pehli value chhoti, (b) doosri value chhoti, (c) dono equal.
Doosra naam: Functional Testing.
Whitebox Testing
Program ka structure analyse karo. Program transparent hai — code dikh raha hai. Test cases aise design karo ki code ka har path execute ho jaaye.
Min example: ek test case jo if branch le, doosra jo else branch le.
Doosra naam: Structural Testing. Idea: Test Coverage.
Yeh check karna ki tumhara test suite program ke saare possible paths (start se end tak) cover kar raha hai ya nahi.
Testing ke different levels
Yeh pura week isi ladder par chalta hai — neeche se upar:
| Level | Kya test hota hai | Kaun karta hai |
|---|---|---|
| Unit Testing | Program ke individual functions / units | Jo developer code likhta hai |
| Integration Testing | Units ko incrementally jodte jaao, har step ke baad test | Development team |
| System Testing → Alpha | Poora integrated system | Organisation ke andar ki test team |
| System Testing → Beta | Poora integrated system | Customers ka ek select group (bahar) |
| Acceptance Testing | Requirements / user stories satisfy ho rahe hain ya nahi | Customer — wahi decide karta hai delivery accept karni hai ya nahi |
| Performance Testing | Non-functional requirements | Test team |
Unit Testing
Sabse pehla level. Individual functions/units ko alag-alag test karna. Yahan pytest ka pura practical demo bhi hai — yeh programming assignment me directly kaam aata hai.
Unit testing kyun? Seedha integrate karke ek baar me test kyun nahi?
Yeh reflection spot ka sawaal hai. Do solid reasons:
Modules alag-alag developers banate hain. Jab main apna module bana raha hoon, tab doosre modules shayad bane hi nahi hain. To shuru me integration ya system testing possible hi nahi hai.
Agar poore integrated set me error mila, to pata kaise chalega kis module me error hai? Har unit alag test kiya hoga, to har module ke bugs wahin resolve ho jaayenge.
Unit testing: Kab, Kaun, Kya
| Question | Answer |
|---|---|
| Kab? | Module ki coding ke dauraan — testing phase me nahi. Aise nahi ki pehle pura module bana lo phir test karo. Jaise-jaise code likh rahe ho, waise-waise unit test bhi. |
| Kaun? | Wahi banda jo us module ka code likh raha hai. |
| Kya involve hai? | (1) Unit test cases design karna, (2) unit under test ke liye testing environment design karna. |
Testing Environment: Stub aur Driver
Problem samjho: mera module function_1(), function_2(), function_3() ko call karta hai —
par wo abhi bane hi nahi hain (koi aur developer bana raha hai). Upar se mere module ko kuch non-local / global data bhi chahiye
jo abhi available nahi hai. To test kaise karein? Answer: stub aur driver bana lo.
Wo function jise mera module call karta hai, uska nakli version. Uske I/O parameters (signature) bilkul same hote hain, par behaviour bahut simplified hota hai.
Yaad rakhne ka tarika: Stub = neeche wala (jise call kiya jaata hai).
Wo module jisme non-local data structures hote hain jinhe module under test access karta hai. Yeh module ko call karke chalata hai.
Yaad rakhne ka tarika: Driver = upar wala (jo drive/call karta hai).
Python me unit testing tools
Do popular tools:
unittest— Python ki built-in standard library testing ke liye.pytest— bahut popular tool, boilerplate code kam karta hai. Course me yahi use hota hai.
pytest ka pura walkthrough
Lecture me seller portal ka example liya gaya. Setup ye hai:
# product.py class Product: # product add karna, details dekhna ... # inventory.py class SellerInventory: # seller_inventory_map = dictionary {product_id : num_items} def add_items_to_inventory(self, product, num): ... def delete_items_from_inventory(self, product, num): # agar delete karne wale items zyada hain to ValueError raise ... def get_total_items(self): pass # ABHI IMPLEMENT NAHI HUA — koi aur developer bana raha hai
Step 1 — Install aur naming rules
$ pip install pytest $ pytest # folder me tests dhoondhta hai
File ka naam test_ se shuru hona chahiye → test_seller_portal.py
Function ka naam bhi test_ se shuru hona chahiye → def test_double():
Lecture me demo kiya gaya: test_ hataate hi pytest bolta hai "no tests ran".
Step 2 — Pehla simple test (assert)
# test_seller_portal.py def double(n): # normal function (test_ nahi hai) return n * 2 def test_double(): # yeh TEST CASE hai assert double(10) == 20
Test case likhne ka core keyword: assert. Agar condition True → pass, False → fail.
Step 3 — Actual class ko test karna
from product import Product from inventory import SellerInventory def test_add_new_item_to_inventory(): inventory = SellerInventory("S1") inventory.add_items_to_inventory(P1, 10) assert inventory.seller_inventory_map[P1] == 10 def test_add_previously_added_item_to_inventory(): inventory = SellerInventory("S1") inventory.add_items_to_inventory(P1, 10) inventory.add_items_to_inventory(P1, 10) assert inventory.seller_inventory_map[P1] == 20 # update hona chahiye, replace nahi
Lecture me deliberately bug dala gaya (+ hata diya) — tab pytest ne AssertionError: 10 != 20 diya.
Matlab function replace kar raha tha, add nahi. Fix karke dobara run kiya → pass. Yehi to testing ka point hai.
Good practice: test method ka naam hi bata de ki wo kya test kar raha hai —
test_add_previously_added_item_to_inventory jaisa descriptive naam.
Step 4 — Fixtures (repeated setup hatane ke liye)
Problem: har test me inventory = SellerInventory("S1") baar-baar likhna pad raha hai. Solution = fixture.
import pytest @pytest.fixture def inventory(): return SellerInventory("S1") # initialization ek hi jagah def test_add_new_item(inventory): # fixture ko parameter ki tarah pass karo inventory.add_items_to_inventory(P1, 10) assert inventory.seller_inventory_map[P1] == 10
Fixture kya karta hai: aisi cheezein initialize/create karta hai jo saare test cases me chahiye hoti hain.
Step 5 — Exceptions test karna
Agar delete karne wale items inventory se zyada hain, to code ValueError raise karta hai. Isko test karne ke liye pytest.raises:
def test_delete_more_items_than_available(inventory): inventory.add_items_to_inventory(P1, 10) with pytest.raises(ValueError): inventory.delete_items_from_inventory(P1, 20) # 20 > 10 → error aana chahiye
Lecture me ek important observation: agar 20 ki jagah 5 likh dete (10 > 5, koi error nahi),
to ye test fail hota — kyunki expected exception raise hi nahi hua. Yani test sahi kaam kar raha hai.
Step 6 — Stub / Mock banana (sabse important part)
Problem: get_total_items() abhi implement nahi hua (dusra developer bana raha hai). Test chalao to
None != 30 aata hai — fail. Ab kya karein? Stub bana lo — ek mock/dummy method jo us functionality ko mimic kare.
def mock_get_total_items(inventory): # <-- yeh hamara STUB hai total = 0 for pid, num in inventory.seller_inventory_map.items(): total += num return total def test_get_total_items(inventory, mocker): inventory.add_items_to_inventory(P1, 10) inventory.add_items_to_inventory(P2, 20) # asli get_total_items ki jagah hamara mock chalega inventory.get_total_items = mocker.Mock(side_effect=mock_get_total_items) assert inventory.get_total_items(inventory) == 30 # PASS ✓
Yeh exactly wahi stub concept hai jo theory me padha tha — bas pytest me implement kiya gaya.
side_effect batata hai ki asli function ki jagah kaunsa function chalana hai.
Unit testing summary — pytest checklist
| Kaam | pytest me kaise |
|---|---|
| Test file banana | File name test_*.py |
| Test case banana | Function name test_*() |
| Check karna | assert <condition> |
| Repeated setup hatana | @pytest.fixture |
| Exception test karna | with pytest.raises(ValueError): |
| Adhoora function handle karna | mocker.Mock(side_effect=...) → stub |
Blackbox aur Whitebox Testing
Unit testing "kya" karna hai bataata hai. Blackbox/Whitebox bataate hain ki test cases design kaise karne hain. Numerical-type questions yahin se aate hain.
Part A — Blackbox Testing (Functional Testing)
Program ek black box hai. Code ka design ya structure ka koi knowledge nahi chahiye. Sirf input–output value pairs examine karke test cases banate hain.
1. Equivalence Classes
Input values ke poore domain ko aise classes/partitions me baant do ki ek class ke har input par program same behave kare. Phir har class se sirf ek representative value uthao — poori class test ho gayi.
min(x, y) — 2 values ka minimum
3 equivalence classes:
x > y→ e.g. (20, 10) ya (50, 40)x < y→ e.g. (10, 20)x = y→ e.g. (10, 10)
(20,10) aur (50,40) same class me hain — dono ki zarurat nahi, ek kaafi hai.
isPrime(num)
2 equivalence classes:
- Prime numbers → koi bhi ek prime, e.g. 7
- Non-prime numbers → koi bhi ek non-prime, e.g. 9
Bas 2 test cases se dono classes cover.
2. Boundary Value Analysis (BVA)
Programmers ki sabse common galti: boundaries par gadbad. < lagau ya <=?
range(n) likhu ya range(n-1)? Isliye equivalence classes ke boundaries ki values se test cases banate hain.
isPrime(num)ke liye boundary values → 0 aur 1 check karo.- Loop ranges, array indices, "<" vs "<=" — yahi jagah bugs milte hain.
Blackbox testing ka 4-step recipe
- Requirements/specifications se input aur output structures/values identify karo.
- Equivalence classes identify karo.
- Har equivalence class se ek representative test case design karo.
- Boundary value test cases design karo.
Part B — Whitebox Testing (Structural Testing)
Ab code dikh raha hai. Program ka structure analyse karte hain kuch heuristics se — aur main heuristic hai coverage: kya hum program ke saare (ya almost saare) parts execute kar paa rahe hain?
Yeh pura section isi ek program par based hai:
1 def isPrime(num): 2 if num == 0 or num == 1: 3 return False 4 for n in range(2, num): 5 if num % n == 0: 6 return False 7 return True
Coverage-based testing ke 3 types:
1️⃣ Branch Coverage
Program ka har branch kam se kam ek baar execute hona chahiye. Yaani har branch condition ko ek baar True aur ek baar False banana hai.
min example: if (x<y) min=x else min=y
- Test case 1:
x < y→ condition True - Test case 2:
x ≥ y→ condition False
isPrime ke liye (Reflection Spot ka answer):
| Test case | Line 2 condition | Line 5 condition |
|---|---|---|
0 | True ✓ | — |
2 | False ✓ | loop chalta hi nahi |
3 | False | False ✓ (prime) |
4 | False | True ✓ (non-prime) |
Answer: Test cases = {0, 2, 3, 4}
2️⃣ Multiple Condition Coverage (MCC)
Jab condition composite ho (or / and se judi ho), tab har
component condition ko alag-alag True aur False banana hai.
isPrime me: num == 0 or num == 1 → components hain num==0 aur num==1.
Test cases {0, 1} multiple condition coverage achieve karte hain.
Ab wo example jisse branch vs MCC ka farak clear hota hai:
if (num < 50 || num > 150) doSomething(); else doSomethingElse();
{49, 100}
- 49 →
num<50True → poori condition True →ifchala - 100 → dono False → poori condition False →
elsechala
Dono branch cover ho gaye. Par num>150 kabhi True hua hi nahi!
{49, 100, 200}
- 49 → 1st component True
- 100 → dono components False
- 200 → 2nd component True ✓
Ab har component ne True aur False dono values li.
Kuch cases me Multiple Condition Coverage, Branch Coverage se stronger testing strategy hai — kyunki branch coverage composite condition ke chhupe hue components miss kar sakta hai.
3️⃣ Path Coverage
Ek test suite path coverage achieve karta hai agar wo program ke saare linearly independent paths ko kam se kam ek baar access kar le. Paths dhoondhne ke liye banate hain Control Flow Graph (CFG).
CFG kaise banta hai: har line number ka ek node, aur agar control ek line se doosri line par ja sakta hai to un dono ke beech ek edge.
Interactive: koi bhi path button dabao — CFG me wo path highlight hoga.
| Path | Kya ho raha hai | Test case |
|---|---|---|
{1,2,3} | num 0 ya 1 hai → seedha return False | 0 / 1 |
{1,2,4,7} | for loop me enter hi nahi hua (range(2,2) khaali) → return True | 2 |
{1,2,4,5,6} | loop me gaye, num%n==0 True → non-prime → return False | 4 |
{1,2,4,5,4,7} | loop kai baar chala, kabhi divisible nahi mila → prime → return True | 3 |
Cyclomatic Complexity — kitne paths honge?
Cyclomatic Complexity = (No. of decision statements + loop statements) + 1
isPrime me: num==0 or num==1 (1) + for loop (2) + num%n==0 (3)
→ 3 + 1 = 4. Isliye 4 paths aur kam se kam 4 test cases chahiye.
Blackbox vs Whitebox — ek nazar me
| Point | Blackbox | Whitebox |
|---|---|---|
| Doosra naam | Functional Testing | Structural Testing |
| Code dikhta hai? | Nahi | Haan |
| Base | Input/output values, requirements | Program ka structure |
| Techniques | Equivalence classes, Boundary Value Analysis | Branch, Multiple Condition, Path coverage |
| Metric | — | Coverage, Cyclomatic Complexity |
Integration aur System Testing
Units test ho gaye. Ab unhe jodna hai — aur jodte waqt jo naye bugs paida hote hain unhe pakadna hai. Yeh section MCQ ke liye goldmine hai.
Integration Testing
| Question | Answer |
|---|---|
| Kab? | Jab kam se kam kuch (ya saare) modules unit testing se guzar chuke hon. |
| Objective? | Module interfaces par errors detect karna. |
| Errors kahan? | Module ke andar ke errors to unit testing me fix ho gaye. Ab error tab aayega jab ek module doosre module ko call kare — parameter passing me galti, modules ke beech communication me gadbad, wagairah. |
Integration ke 4 approaches — interactive
Setup: M1 top par hai aur M2, M3, M4 ko call karta hai. M5 sabse neeche hai.
Button dabao aur dekho kaunsa approach kis order me integrate karta hai.
Big Bang Approach
- Saare modules ek hi step me integrate kar diye jaate hain.
- Problem: errors ko localize karna mushkil — error kisi bhi module me ho sakta hai, fix karna mehnga.
- Sirf chhote systems ke liye meaningful. Bade systems me kabhi use nahi hota.
Bottom-Up Approach
- Har subsystem ke modules pehle integrate hote hain. E.g. {M1,M2,M3} ek subsystem, {M4,M5} doosra.
- Pehle har subsystem ka integration test, phir subsystems ko incrementally jodte jaao.
- Stubs ki zarurat NAHI — kyunki relevant modules seedha integrate ho rahe hain, mock karne ki zarurat nahi.
- Drivers CHAHIYE — global variable calls simulate karne ke liye.
Top-Down Approach
- Root module se shuru + uske 1–2 subordinate modules.
- Hierarchical software ke liye suitable. Top modules pehle test, phir agla level, phir agla.
- Drivers ki zarurat NAHI — top se shuru kar rahe hain, isliye relevant global variables har stage par available hain.
- Stubs CHAHIYE — neeche wale modules abhi nahi hain, unke calls mock karne padenge. (M2,M3,M4 test karte waqt M5 ka stub chahiye.)
Mixed Approach
- Top-down aur bottom-up dono ka combination.
- Integration testing tab hoti hai jab-jab modules available hote jaate hain (unit testing ke baad).
- Practically sabse zyada realistic approach.
BOTTOM-UP → Drivers ✅ | Stubs ❌
TOP-DOWN → Stubs ✅ | Drivers ❌
Yaad karne ka trick: Jo taraf se shuru kar rahe ho, wo taraf asli hai — dusri taraf ka nakli banana padega. Bottom se shuru → neeche asli hai, upar wala (driver) nakli. Top se shuru → upar asli hai, neeche wala (stub) nakli.
System Testing
Ab poora integrated system test hota hai. Pehle kaun test kar raha hai ke hisaab se 3 types:
Organisation ke andar ki test team karti hai. Product abhi customer tak nahi gaya.
Customers ka ek select group (organisation ke bahar) test karta hai.
Customer ko system diya jaata hai. Wo dekhta hai requirements/user stories satisfy hue ya nahi, aur decide karta hai delivery accept karni hai ya nahi.
System testing ke aur types
Smoke Testing
- Initial system testing se PEHLE kiya jaata hai (alpha/beta bhejne se pehle).
- Sirf check karte hain ki basic functionalities kaam kar rahi hain ya nahi.
- Thode se basic test cases design kiye jaate hain.
- Seller portal example: Add Products, Add Catalogue, Inventory — ye basic cheezein chal rahi hain?
Performance Testing
- Check karta hai ki system non-functional requirements meet karta hai ya nahi.
- Ab tak unit aur integration testing sirf functional requirements dekh rahe the.
- Stress Testing iska ek type hai: input data volume, input data rate, processing time, memory utilisation — sab kuch designed capacity se aage tak test karo.
- Example: DB par expected capacity se zyada transactions simulate karo aur dekho system kaise handle karta hai.
- Purpose: performance, reliability, robustness check karna.
Test-Driven Development (TDD)
Ab tak jitna padha — sab me code pehle likha, test baad me. TDD ye ulta kar deta hai. Agile processes me specially use hota hai.
TDD ka core idea
- Functionality implement karne se pehle uska test likho.
- Design aur development ko tests se drive karo.
- Iteratively chalo: test likho → functionality banao → agla test likho → agli sub-functionality banao → …
- Saari activities chhote-chhote features verify karne ke around organise hoti hain.
RED → GREEN → REFACTOR (TDD ka mantra)
1. RED — Test likho aur use FAIL hote dekho
Requirement/feature/user story ko test ke form me express karo. Abhi tak code likha hi nahi hai — sirf bata rahe ho ki test kya hai. Test chalao. Obviously fail hoga, kyunki feature implement hi nahi hui. Hum deliberately test banate hain aur use fail karate hain.
TDD ke steps (slide-wise)
- Functionality/feature/requirement ko test ke form me express karo.
- Test create karo, run karo — FAIL hote dekho.
- Test ki need pura karne ke liye minimum code likho. (Pura feature nahi — sirf itna jitna test pass karne ke liye chahiye.)
- Run karo — PASS hote dekho.
- REFACTOR karo — code ki quality sudharo, modular banao, elegant banao, achhi coding practices lagao. Refactor ke baad bhi test pass hona chahiye.
- Agli sub-functionality ke liye poora cycle dohrao.
Live example: TDD se isPrime() banana
Lecture me step-by-step yehi build kiya gaya. Dhyan do ki code har baar test ke reaction me badal raha hai:
Iteration 1 — non-prime number ka test
# test_isprime.py — RED from isprime import isPrime def test_number_is_not_prime(): assert isPrime(4) == False # pytest chalao → FAIL (function khaali hai) # isprime.py — GREEN (minimum code) def isPrime(num): for i in range(2, num): if num % i == 0: return False # pytest chalao → PASS ✓
Notice: abhi return True likha hi nahi. Kyunki abhi tak koi test uski demand nahi kar raha. Yehi "minimum code" ka matlab hai.
Iteration 2 — prime number ka test
# RED def test_number_is_prime(): assert isPrime(5) == True # FAIL — abhi True return hi nahi hota # GREEN def isPrime(num): for i in range(2, num): if num % i == 0: return False return True # naya line
Dono test ab pass. Function incrementally build ho raha hai.
Iteration 3 — boundary cases: 2, 1, 0
def test_two_is_prime(): assert isPrime(2) == True # pehle se PASS ✓ def test_one_not_prime(): assert isPrime(1) == False # FAIL ✗ def test_zero_not_prime(): assert isPrime(0) == False # FAIL ✗ # GREEN — 0 aur 1 handle karo def isPrime(num): if num == 0 or num == 1: return False for i in range(2, num): if num % i == 0: return False return True # ✓ ab saare test pass
Dekha? Yeh exactly wahi isPrime hai jo whitebox testing wale section me tha.
TDD ne boundary values (0, 1) khud hi surface kar diye.
Tum ek saath test bhi kar rahe ho aur application build bhi kar rahe ho. Test cases hi development ko drive kar rahe hain — isliye naam "Test-Driven Development". Simple se complex, dono tarah ke programs isse ban sakte hain.
TDD vs Normal Testing
| Point | Normal (Test-After) | TDD |
|---|---|---|
| Order | Code → phir test | Test → phir code |
| Pehla test result | Ideally pass | Deliberately FAIL |
| Kitna code likhte ho | Poora feature | Minimum code jo test pass kara de |
| Refactoring | Optional / baad me | Cycle ka built-in step |
| Kahan popular | Traditional processes | Agile processes |
Cheat Sheet — revision ke liye
Exam se 15 minute pehle sirf yeh padh lena kaafi hai.
One-liners jo ratt lene chahiye
- Test case = triplet [I, S, R] — Input, State, expected Result.
- Test suite = saare designed test cases ka set.
- Random / exhaustive testing kaafi nahi → minimal designed test suite chahiye.
- Blackbox = Functional. Whitebox = Structural.
- Unit testing coding ke dauraan, code likhne wale developer dwara.
- Stub = called function ka dummy (same signature, simplified behaviour).
- Driver = non-local data structures rakhta hai, module ko call karta hai.
- pytest: file
test_*.py, functiontest_*(), checkassert. - Equivalence class = ek class ke saare inputs par program same behave karta hai → 1 representative kaafi.
- BVA = equivalence classes ke boundaries par test (isPrime → 0, 1).
- Cyclomatic Complexity = decision + loop statements + 1 = paths ki sankhya = minimum test cases.
- MCC > Branch coverage (stronger).
- Bottom-Up → Drivers chahiye, Stubs nahi. Top-Down → Stubs chahiye, Drivers nahi.
- Big Bang → error localize karna mushkil, sirf chhote systems.
- Alpha = andar ki team. Beta = select customers. Acceptance = customer delivery decide karta hai.
- Smoke testing = system testing se pehle, basic functionalities check.
- Stress testing ⊂ Performance testing → non-functional requirements.
- TDD = RED (fail) → GREEN (minimum code, pass) → REFACTOR.
Poora week ek diagram me
SOFTWARE TESTING │ ├── Terminology ── Test Case [I,S,R] → Test Suite │ ├── LEVELS │ ├── Unit Testing ──── Stub + Driver ── pytest │ │ └── Test case design kaise? │ │ ├── BLACKBOX ── Equivalence Classes + Boundary Value Analysis │ │ └── WHITEBOX ── Branch / Multiple Condition / Path coverage │ │ └── Cyclomatic Complexity = D + L + 1 │ │ │ ├── Integration Testing ── Big Bang | Bottom-Up | Top-Down | Mixed │ │ (interface errors pakadna) │ │ │ ├── System Testing ── Alpha | Beta | Smoke | Performance (Stress) │ │ │ └── Acceptance Testing ── customer decides │ └── PROCESS ── TDD: RED → GREEN → REFACTOR
Assignment Practice — Q&A
Option par click karo — turant pata chal jaayega sahi hai ya galat, aur neeche explanation bhi aa jaayega. Score bottom-right corner me dikhta rahega.
Project me tumne sirf lecture PDFs aur slides diye the — Week 9 ka actual assignment file nahi tha. Isliye maine graded assignment ke exact pattern par 26 MCQs + 5 descriptive/programming questions banaye hain jo poore syllabus ko cover karte hain. Assignment ka PDF upload kar dena — main uske exact questions bhi inhi notes me merge kar dunga.
Part A — Terminologies
Ek test case ke triplet [I, S, R] me nimnalikhit me se kya shaamil NAHI hai?
"Ek given program ko test karne ke liye design kiye gaye saare test cases ka set" — isko kya kehte hain?
Hum test cases ko carefully "design" kyun karte hain, bajaye bahut saari random values test karne ke?
if(x<y) min=x else min=x wale buggy program me agar saari random values me
x<y hi hua, to bug kabhi pakda hi nahi jaayega. Isliye minimal, designed test suite chahiye jisme
har test case ek particular type ki error pakde.Part B — Unit Testing, Stub & Driver
Unit testing ke baare me sahi statement chuniye:
Stub kya hota hai?
Driver module me kya hota hai?
pytest ke saath, nimnalikhit me se kaunsa file/function naam detect NAHI hoga?
test_ prefix chahiye — file name aur function name dono me.
inventory_test.py aur check_add_item() me prefix nahi hai → "no tests ran".pytest me @pytest.fixture ka main purpose kya hai?
SellerInventory("S1") banane ki jagah ek fixture bana do.delete_items_from_inventory() uparse zyada items delete karne par ValueError raise karta hai.
Ise pytest me test karne ka sahi tareeka?
pytest.raises() use hota hai —
with pytest.raises(ValueError): block ke andar wo call rakho jisse exception expected hai.get_total_items() abhi kisi aur developer dwara implement ho raha hai, par tumhe apna module abhi test karna hai. Kya karoge?
inventory.get_total_items = mocker.Mock(side_effect=mock_get_total_items)Part C — Blackbox & Whitebox
Function isPrime(num) ke liye equivalence classes kya honge?
isPrime(num) ke liye boundary value analysis me kaunsi values check karni chahiye?
< vs <=, range(n) vs range(n-1)).Diye gaye isPrime code ke liye branch coverage guarantee karne wale test cases:
Code: if (num < 50 || num > 150) doSomething(); else doSomethingElse();
Test set {49, 100, 200} kya achieve karta hai?
num>150 component bhi True hota hai → multiple condition coverage.
Isliye MCC kabhi-kabhi branch coverage se stronger hota hai.Diye gaye isPrime function ki cyclomatic complexity kitni hai?
num==0 or num==1, (2) for loop, (3) num%n==0. To 3 + 1 = 4.
Matlab 4 linearly independent paths aur kam se kam 4 test cases.Path coverage ke liye linearly independent paths kis se nikaalte hain?
Nimnalikhit me se kaunsi technique blackbox testing ki hai?
Part D — Integration & System Testing
Pure bottom-up integration testing me:
Top-down integration testing me:
Big bang approach ki sabse badi problem kya hai?
Integration testing ka main objective kya hai?
Smoke testing ke baare me sahi statement chuniye:
Stress testing kis cheez ka type hai aur kya check karta hai?
Beta testing kaun karta hai?
Part E — TDD
TDD ka sahi order kya hai?
TDD ke GREEN step me kitna code likhna chahiye?
Part F — Descriptive / Programming questions
Yeh wo type hain jo programming assignment ya long-answer me aate hain. Pehle khud try karo, phir answer kholo.
D1. Ek function calculate_discount(price, is_member) ke liye blackbox test cases design karo.
Step 1 — Input/output identify karo: inputs = price (number), is_member (boolean). Output = discounted price.
Step 2 — Equivalence classes:
- is_member = True, price valid (positive)
- is_member = False, price valid (positive)
- Invalid price (negative)
Step 3 — Har class se ek representative: (1000, True), (1000, False), (-50, True)
Step 4 — Boundary values: price = 0, price = 1, aur agar discount slabs hain (e.g. 500 se upar) to 499, 500, 501.
Yaad rakho: answer likhte waqt ye 4 steps hi structure hain — identify I/O → equivalence classes → representative test cases → boundary tests.
D2. SellerInventory class ke liye pytest test suite likho (fixture + exception ke saath).
import pytest from inventory import SellerInventory @pytest.fixture def inventory(): return SellerInventory("S1") def test_add_new_item_to_inventory(inventory): inventory.add_items_to_inventory("P1", 10) assert inventory.seller_inventory_map["P1"] == 10 def test_add_previously_added_item(inventory): inventory.add_items_to_inventory("P1", 10) inventory.add_items_to_inventory("P1", 10) assert inventory.seller_inventory_map["P1"] == 20 def test_delete_items_less_than_total(inventory): inventory.add_items_to_inventory("P1", 10) inventory.delete_items_from_inventory("P1", 5) assert inventory.seller_inventory_map["P1"] == 5 def test_delete_items_more_than_total(inventory): inventory.add_items_to_inventory("P1", 10) with pytest.raises(ValueError): inventory.delete_items_from_inventory("P1", 20)
Marks kahan milte hain: descriptive test names, fixture ka use (repeated init nahi),
aur exception ke liye pytest.raises.
D3. Neeche diye function ka control flow graph banao aur cyclomatic complexity nikalo.
1 def grade(marks): 2 if marks < 0 or marks > 100: 3 return "Invalid" 4 if marks >= 40: 5 return "Pass" 6 return "Fail"
Edges: 1→2, 2→3, 2→4, 4→5, 4→6
Paths: {1,2,3}, {1,2,4,5}, {1,2,4,6} → 3 paths
Cyclomatic complexity: decision statements = 2 (line 2 aur line 4), loops = 0 → 2 + 1 = 3 ✓ (paths se match)
Branch coverage test cases: marks = -5 (ya 105), marks = 70, marks = 20
Multiple condition coverage ke liye extra: line 2 ki composite condition ke dono components ko True karna hai → marks = -5 (pehla True) aur marks = 105 (doosra True), plus marks = 70 (dono False).
D4. Stub aur Driver me farak, ek example ke saath.
| Point | Stub | Driver |
|---|---|---|
| Position | Module under test ke neeche (jise call kiya jaata hai) | Module under test ke upar (jo call karta hai) |
| Kya replace karta hai | Wo functions jinhe module call karta hai | Wo calling code + non-local/global data |
| Property | Same I/O parameters, highly simplified behaviour | Non-local data structures rakhta hai |
| Top-down me | Chahiye | Nahi chahiye |
| Bottom-up me | Nahi chahiye | Chahiye |
Example: Seller portal ka module get_total_items() call karta hai jo abhi nahi bana —
to mock_get_total_items() ek stub hai. Aur agar module ko global inventory data chahiye jo abhi available nahi,
to wo data supply karne wala test code driver hai.
D5. TDD se is_palindrome(s) function banao — RED/GREEN/REFACTOR dikhate hue.
# --- RED 1 --- def test_simple_palindrome(): assert is_palindrome("madam") == True # FAIL # --- GREEN 1 (minimum code) --- def is_palindrome(s): return s == s[::-1] # --- RED 2 --- def test_not_palindrome(): assert is_palindrome("hello") == False # pehle se PASS def test_case_insensitive(): assert is_palindrome("Madam") == True # FAIL # --- GREEN 2 --- def is_palindrome(s): s = s.lower() return s == s[::-1] # --- RED 3 (boundary) --- def test_empty_string(): assert is_palindrome("") == True # --- REFACTOR --- def is_palindrome(s): cleaned = s.lower().replace(" ", "") return cleaned == cleaned[::-1]
Answer likhte waqt highlight karo: har feature ke liye pehle failing test, phir minimum code, phir refactor — aur refactor ke baad saare purane tests bhi pass hone chahiye.