Code Coverage

Code Coverage (Testabdeckung) ist eine Metrik, die angibt, wie viel Prozent des Codes durch Unit Testings abgedeckt ist.

Code Coverage zeigt, welche Teile des Codes getestet wurden und welche nicht.

Code Coverage Visualisierung:

Projekt mit 100 Zeilen Code:
┌───────────────────────────────┐
│ ███████████░░░░░░░░░░░░░░░░░░ │ 50% Coverage
└───────────────────────────────┘
│← getestet →│←  nicht getestet →│

Arten der Coverage:

┌──────────────────────────────────┐
│        Code Coverage             │
└────────────┬─────────────────────┘
             │
    ┌────────┼────────┬─────────┐
    │        │        │         │
┌───▼───┐ ┌─▼──┐ ┌───▼───┐ ┌───▼────┐
│Line   │ │Branc│ │Function│ │Condition│
│Cover. │ │Cover│ │Coverage│ │Coverage │
└───────┘ └────┘ └────────┘ └─────────┘

Prozess-Ablauf:

  Code schreiben
       │
       ▼
  Tests schreiben
       │
       ▼
  Tests ausführen
       │
       ▼
  ┌────────────┐
  │  Coverage  │
  │  messen    │
  └─────┬──────┘
        │
        ▼
  ┌─────────────┐
  │ Report      │
  │ analysieren │
  └─────┬───────┘
        │
    ┌───▼────┐
    │ < 80%? │──Ja──> Mehr Tests schreiben
    └───┬────┘                │
        │                     │
       Nein                   │
        │                     │
        └─────────────────────┘
        │
        ▼
     Fertig!

Arten von Code Coverage

Die 4 Hauptarten

1. Line Coverage (Zeilenabdeckung):
  ┌──────────────────────┐
  │ 1: public int add()  │ ✓ getestet
  │ 2: {                 │ ✓
  │ 3:   return a + b;   │ ✓
  │ 4: }                 │ ✓
  │ 5: public int sub()  │ ✗ nicht getestet
  │ 6: {                 │ ✗
  │ 7:   return a - b;   │ ✗
  │ 8: }                 │ ✗
  └──────────────────────┘
  Coverage: 50% (4 von 8 Zeilen)

2. Branch Coverage (Zweigabdeckung):
  if (x > 0) {        ← Bedingung
      return true;    ← Branch 1 (✓ getestet)
  } else {
      return false;   ← Branch 2 (✗ nicht getestet)
  }
  Branch Coverage: 50%

3. Function Coverage (Funktionsabdeckung):
  ┌─────────────┬──────────┐
  │ Funktion    │ Getestet?│
  ├─────────────┼──────────┤
  │ add()       │    ✓     │
  │ subtract()  │    ✓     │
  │ multiply()  │    ✗     │
  │ divide()    │    ✗     │
  └─────────────┴──────────┘
  Function Coverage: 50%

4. Condition Coverage (Bedingungsabdeckung):
  if (a > 0 && b > 0) {
     ↑        ↑
  Bed. 1   Bed. 2

  Tests:
  - Test 1: a=5, b=5   → beide true  ✓
  - Test 2: a=-1, b=5  → a false     ✗
  - Test 3: a=5, b=-1  → b false     ✗
  - Test 4: a=-1, b=-1 → beide false ✗

Beispiel mit visualisierter Coverage

Code-Beispiel

public class Calculator {

   // Methode 1 (getestet)
   public int add(int a, int b) {          // ✓
       return a + b;                       // ✓
   }                                       // ✓

   // Methode 2 (getestet mit Branch)
   public int divide(int a, int b) {       // ✓
       if (b == 0) {                       // ✓ beide Branches
           throw new ArithmeticException(); // ✓
       }                                   // ✓
       return a / b;                       // ✓
   }                                       // ✓

   // Methode 3 (NICHT getestet)
   public int multiply(int a, int b) {     // ✗
       return a * b;                       // ✗
   }                                       // ✗
}
Coverage-Report:

┌─────────────┬──────────┬───────────┐
│ Metrik      │ Getestet │ Coverage  │
├─────────────┼──────────┼───────────┤
│ Lines       │  9 / 12  │   75%     │
│ Branches    │  2 / 2   │  100%     │
│ Functions   │  2 / 3   │   67%     │
└─────────────┴──────────┴───────────┘

Visualisiert:
Calculator.java
┌──────────────────────────────┐
│ ██████████░░░░░░░░░░░░░      │ add() - 100%
│ ████████████████████████     │ divide() - 100%
│ ░░░░░░░░░░░░░░░░░░░░░░░░     │ multiply() - 0%
└──────────────────────────────┘
Gesamt: 75%

Coverage-Tools

Gängige Tools

Java:

  • JaCoCo (am häufigsten)
  • Cobertura
  • Emma

C#/.NET:

  • dotCover (JetBrains)
  • OpenCover
  • Coverlet

Python:

JavaScript:

  • Istanbul
  • Jest (built-in)

Allgemein:

  • SonarQube (Code-Qualität + Coverage)

Coverage-Ziele

Coverage-Levels:

┌─────────┬──────────────────────────────┐
│ < 50%   │ ░░░░░░░░░░░░░               │ Schlecht!
├─────────┼──────────────────────────────┤
│ 50-70%  │ ████████░░░░░░░░░░░░        │ Akzeptabel
├─────────┼──────────────────────────────┤
│ 70-85%  │ ████████████████░░░░        │ Gut
├─────────┼──────────────────────────────┤
│ 85-95%  │ ████████████████████░░      │ Sehr gut
├─────────┼──────────────────────────────┤
│ > 95%   │ ████████████████████████    │ Exzellent
└─────────┴──────────────────────────────┘

Typische Ziele nach Projekt:

Kritische Systeme    ████████████████████████  95-100%
(Banking, Medical)

Normale Software     ██████████████████░░░░░░  75-85%

Legacy Code          ████████░░░░░░░░░░░░░░░░  40-60%
Prüfungsrelevant

Was ist Code Coverage?

  • Metrik für Test-Qualität
  • Zeigt, wie viel Code getestet ist
  • In Prozent ausgedrückt (0-100%)

Arten:

  • Line Coverage: Welche Zeilen wurden ausgeführt?
  • Branch Coverage: Welche Verzweigungen wurden getestet?
  • Function Coverage: Welche Funktionen wurden aufgerufen?

Ziel:

  • Mindestens 70-80% für gute Software
  • 100% ist selten sinnvoll/erreichbar
Hohe Coverage = Gute Tests?

NEIN!

// Test mit 100% Coverage, aber OHNE Assertions:
@Test
public void testAdd() {
   calculator.add(2, 3);  // Wird ausgeführt
   // Aber: Keine Überprüfung des Ergebnisses!
}

Richtig:

@Test
public void testAdd() {
   int result = calculator.add(2, 3);
   assertEquals(5, result);  // ✓ Überprüfung!
}

Merke: Coverage sagt NUR, dass Code ausgeführt wurde, NICHT dass er richtig getestet wurde!

Best Practices

  1. Realistische Ziele setzen
  • 80% ist oft besser als 100%
  • Kritische Teile zu 100% testen
  1. Coverage als Werkzeug nutzen
  • Nicht getestete Bereiche finden
  • Nicht als einzige Metrik verwenden
  1. Wichtigen Code priorisieren
Prio 1: Business Logic     → 95%+
Prio 2: Helper Functions   → 80%+
Prio 3: Getters/Setters    → 50%+
  1. Coverage im CI/CD
  • Automatisch bei jedem Build
  • Mindest-Coverage festlegen
  • Build schlägt fehl bei < Ziel

Coverage-Report lesen

JaCoCo Coverage Report:

Package: com.example.calculator
┌────────────────┬──────┬─────────┬──────────┐
│ Class          │Lines │ Branches│ Functions│
├────────────────┼──────┼─────────┼──────────┤
│ Calculator     │ 85%  │  75%    │   100%   │ ✓
│ Scientific     │ 45%  │  30%    │    60%   │ ⚠
│ Helper         │ 90%  │  80%    │    90%   │ ✓
├────────────────┼──────┼─────────┼──────────┤
│ TOTAL          │ 73%  │  62%    │    83%   │
└────────────────┴──────┴─────────┴──────────┘

→ Scientific.java braucht mehr Tests!
→ Branch Coverage insgesamt zu niedrig

Siehe auch