4.5.15 · HinglishSoftware Engineering

Code coverage — line, branch, path coverage

1,946 words9 min readRead in English

4.5.15 · Coding › Software Engineering


Code coverage exist KYUN karta hai?

Hum care KYUN karte hain? Untested code ek blind spot hai. Agar koi line testing ke dauran kabhi run nahi hoti, toh aapke paas zero evidence hai ki woh kaam karti hai. Coverage in blind spots ko sasta aur automatically surface karta hai.

YEH KYA NAHI HAI: Coverage execution measure karta hai, correctness nahi. Ek test ek line execute kar sakta hai aur phir bhi kuch assert nahi karta (koi assert nahi), jo 0% confidence ke saath 100% coverage deta hai. Isko baad mein steel-man karo.


Teen levels (sabse weak → sabse strong)

Hum coverage ko us unit ke hisaab se classify karte hain jo hum count karte hain. Bade units = zyada strong guarantee = reach karna mushkil.

Level Unit counted Pakadta hai
Line (statement) har executable line unexecuted lines
Branch (decision) har decision ke true/false outcome na liye gaye decision outcomes
Path code mein har end-to-end route branches ke unexercised combinations

Figure — Code coverage — line, branch, path coverage

Derivation: branch ≥ line kyun, aur path ≥ branch kyun (ek hierarchy)

Yeh function lo:

def grade(x):
    if x > 50:        # decision D1
        return "pass"
    return "fail"

Step 1 — Lines count karo. Executable lines: if x>50, return "pass", return "fail" → 3 lines. Kyun? Hum woh statements count karte hain jo runtime par actually kuch karte hain.

Step 2 — Ek test grade(60). if run karta hai, return "pass" run karta hai. Woh 2/3 lines = 66% line hai. return "fail" kabhi nahi chala. Yeh step kyun? Yeh dikhane ke liye ki ek test kabhi-kabhi sab kuch hit nahi karta.

Step 3 — Branches count karo. D1 ke do outcomes hain: True aur False → 2 branch outcomes. grade(60) sirf True outcome leta hai → 1/2 = 50% branch. Yeh step kyun? Notice karo branch% (50) ≤ line% (66): branch stricter hai, yeh na liye gaye False path ko zyada punish karta hai.

Step 4 — Full branch coverage. grade(40) add karo (False leta hai). Ab dono outcomes hit hote hain → 100% branch, aur incidentally 100% line. Theorem (informal): 100% branch ⟹ 100% line (har decision outcome lena har line ko run karne par majboor karta hai), lekin ulta sach nahi hai. Toh branch, line ko subsume karta hai. Isi tarah path, branch ko subsume karta hai.


Worked Example — Path explosion

def f(a, b):
    if a: x = 1     # D1
    else: x = 2
    if b: y = 1     # D2
    else: y = 2
    return x + y

Step 1 — Lines: ~5 → ek test lagbhag sab cover karta hai → aasaan 100% line. Step 2 — Branches: D1{T,F}, D2{T,F} = 4 outcomes. Tests (T,T) aur (F,F) saare 4 cover karte hain → sirf 2 tests mein 100% branch. Yeh step kyun? Branch coverage ko combinations ki zaroorat nahi hai, sirf yeh ki har outcome kam se kam ek baar aaye. Step 3 — Paths: program mein routes = combinations: (T,T),(T,F),(F,T),(F,F) = paths. Hamare 2 tests ne sirf TT aur FF cover kiya → 2/4 = 50% path. Yeh kyun matter karta hai: Ek bug jo sirf tab appear hota hai jab a=True AND b=False hai, woh 100% branch coverage ke liye invisible hai lekin path coverage se pakad mein aata hai. Yahi woh value hai jo path add karta hai — aur isliye yeh ka cost laata hai.


Worked Example — Short-circuit ek branch chhupata hai

if user != None and user.active:   # do conditions!
    login()

Step 1: Line coverage EK line dekhta hai; ek test usse run karta hai = 100% line. Step 2: Branch coverage (decision) poori condition ka True/False dekhta hai. Step 3: Condition coverage (ek finer cousin) chaahta hai ki har sub-condition user!=None aur user.active T aur F dono ho. Yeh kyun matter karta hai: user=None short-circuit karta hai aur user.active kabhi evaluate nahi karta. Sirf line/decision coverage report karne wale tools ise mask karte hain. Fix yeh hai: safety-critical code ke liye MC/DC (Modified Condition/Decision Coverage) use karo, jahan har condition independently outcome ko affect kare.



80/20 takeaway

  • Woh 20% jo aapko zaroor pata hona chahiye: Line ⊂ Branch ⊂ Path strictness mein. Branch = har if-outcome kam se kam ek baar. Path = har combination = blowup. 100% coverage ≠ correct.
  • 80% real-world practice: critical modules par high branch coverage aim karo, path/MC/DC sirf safety-critical code ke liye use karo, aur coverage ko mutation testing se back karo.

Recall Feynman: ek 12-saal ke bacche ko samjhao

Socho aapka code ek maze hai aur aapke tests log hain jo usme walk kar rahe hain.

  • Line coverage: Kya kisi ne har floor tile par qadam rakha? (Shayad, lekin sab ek hi tarah chale.)
  • Branch coverage: Har fork par, kya koi left gaya AUR koi right gaya? (Behtar — dono directions try ki gayi.)
  • Path coverage: Kya logon ne start se exit tak har possible complete route try ki? (Sabse best — lekin ek bade maze mein lakhon routes hote hain, toh yeh thakaan bhara hai.) Maze mein walk karna prove karta hai ki aap ek room tak pahunch sakte hain. Yeh prove NAHI karta ki room safe hai — uske liye aapko actually room check karna hoga (assert). Isliye "100% chala" ka matlab "100% safe" nahi hai.

Flashcards

Code coverage kya measure karta hai?
Source code ka woh percentage jo test suite run hone ke dauran execute hota hai — execution, correctness nahi.
Line (statement) coverage formula
(executable lines executed ÷ total executable lines) × 100%.
Branch (decision) coverage formula
(branch outcomes taken ÷ total branch outcomes) × 100%; har decision ke 2 outcomes hote hain (T/F).
Branch coverage, line coverage se stricter kyun hai?
Ek if ek line hai lekin do branch outcomes hain; line ko ek baar run karna 100% line deta hai lekin sirf 50% branch tab tak, jab tak T aur F dono na liye jaayein.
Kya 100% branch coverage se 100% line coverage imply hoti hai?
Haan — har decision outcome lena har line ko execute karne par majboor karta hai. Ulta false hai.
n sequential independent if-statements kitne paths create karte hain?
— path coverage exponentially badhti hai, aksar infeasible ho jaati hai.
100% coverage correctness ka proof kyun nahi hai?
Ek test kuch assert kiye bina code execute kar sakta hai; coverage execution measure karta hai, yeh nahi ki results check hue ya nahi.
Decision/branch coverage aur condition coverage mein kya fark hai?
Decision = poori condition ka T/F; Condition = har boolean sub-term ka T/F. a and b = 1 decision, 2 conditions. Yeh alag hain.
a and b mein branches kya chhupata hai?
Short-circuit evaluation — agar a False hai, b kabhi evaluate nahi hota, toh uske outcomes untested reh sakte hain.
MC/DC kya hai aur kab use hota hai?
Modified Condition/Decision Coverage — har condition independently outcome ko affect karti hai; safety-critical (jaise avionics) software mein required hai.
Test quality check karne ke liye coverage ko kaun si technique complement karti hai?
Mutation testing — yeh code ko mutate karta hai (jaise >>=) aur check karta hai ki tests fail hoti hain ya nahi.
Coverage strength ki subset hierarchy?
Line ⊂ Branch ⊂ Path (aur Path, Branch ko subsume karta hai, Branch, Line ko subsume karta hai).

Connections

  • Unit Testing — coverage unit/integration tests run karke measure hoti hai.
  • Mutation Testing — coverage ke "kya aapne assert kiya?" blind spot ko fix karta hai.
  • Cyclomatic Complexity — branch coverage ke liye zaroori tests ki lower bound deta hai.
  • Control Flow Graph — branches aur paths CFG mein edges/routes hain.
  • Test-Driven Development — TDD naturally high branch coverage produce karta hai.
  • MC-DC Coverage — safety-critical systems ke liye stricter standard.

Concept Map

answers

collected by

formula

denominator = lines

denominator = branch outcomes

denominator = paths

one if is 2 outcomes

n ifs give 2^n routes

grows exponentially

weakest, path strongest

measures execution not correctness

Code Coverage metric

How much code ran during tests

Instrumenting code

hit ÷ total x 100%

Line coverage

Branch coverage

Path coverage

Often infeasible

Hierarchy branch >= line, path >= branch

Thermometer not a cure