Wie man Qualität (nicht) misst

 

in der Softwareentwicklung

@MichaKutz

@mkutz@mstdn.social

Warum wollen wir Qualität messen?

ein neues Feature hinzufügen

Qualität verbessern

Was kann schon schief gehen…

Goodharts Gesetz

Jede beobachtete statistische Kennzahl ist nur zu gebrauchen, solange auf sie kein Druck ausgeübt wird.

Negativer Einfluß auf

Motivation und Kollaboration

Wie findet man die richtigen Metriken?

Ziel

Gehen wir in die richtige Richtung?

Wo sind wir?

Frage

Metrik

GQM

Welche Qualität?

Wie fehlerhaft?

Wie beliebt?

Wie funktional?

Anzahl gefundener Fehler

im Testsystem vs Produktion

Wie fehlerhaft?

Wie effektiv ist der Testprozess?

Unerfüllte Service Level Objectives

Wie fehlerhaft?

Wie fehlerhaft?

Wie beliebt?

Wie funktional?

Anzahl von Benutzerbeschwerden

Wie beliebt?

Wie viele Leute beschweren sich?

Benutzerumfragen und Platform-Bewertungen

Wie beliebt?

Wie fehlerhaft?

Wie beliebt?

Wie funktional?

User Experience Tests

Wie funktional?

User Tracking

Wie funktional?

Wie fehlerhaft?

Wie beliebt?

Wie funktional?

Wie fehlerhaft?

Wie funktional?

Wie beliebt?

UX Tests

User Tracking/
Observability

Service Level Objectives

Benutzer-beschwerden

Wie gut geschützt?

Wie wartbar?

Wie kompetent ist das Team?

Code-Abdeckung

@Test
void strike() {
  var game = new Game();
  var firstRollPins = 10;
  var secondRollPins = 5;
  var thirdRollPins = 3;
  game.roll(firstRollPins);
  game.roll(secondRollPins);
  game.roll(thirdRollPins);
  
  var score = game.score();

  assertThat(score)
    .isEqualTo(
      firstRollPins +
      (secondRollPins + thirdRollPins) * 2);
}
public int score() {
  int score = firstRoll + secondRoll;
  if (previous != null) {
    if (previous.strike) {
      score *= 2;
    } else if (previous.spare) {
      score += firstRoll;
    }
  }
  return score;
}
@Test
void strike() {
  var game = new Game();
  var firstRollPins = 10;
  var secondRollPins = 5;
  var thirdRollPins = 3;
  game.roll(firstRollPins);
  game.roll(secondRollPins);
  game.roll(thirdRollPins);
  
  var score = game.score();

  // assertThat(score)
  //  .isEqualTo(
  //    firstRollPins +
  //    (secondRollPins + thirdRollPins) * 2);
}

Wie gut geschützt?

Wie viel Code wird nicht ausgeführt durch Tests?

Mutation Testing: Überlebende Mutationen

@Test
void strike() {
  var game = new Game();
  var firstRollPins = 10;
  var secondRollPins = 5;
  var thirdRollPins = 3;
  game.roll(firstRollPins);
  game.roll(secondRollPins);
  game.roll(thirdRollPins);
  
  var score = game.score();

  assertThat(score
    .isEqualTo(
      firstRollPins +
      (secondRollPins + thirdRollPins) * 2);
}
public int score() {
  int score = firstRoll + secondRoll;
  if (previous != null) {
    if (previous.strike) {
      score *= 2;
    } else if (previous.spare) {
      score += firstRoll;
    }
  }
  return score;
}
AssertionFailedError:
expected: 26
 but was: 14

Wie gut geschützt?

Wie gut geschützt?

Wie wartbar?

Wie kompetent ist das Team?

Team-Umfragen

Wie kompetent ist das Team?

Wie effektiv kannst du mit dem Code arbeiten?

Wie zuversichtlich bist du vor Deployments in Produktion?

Was würdest du brauchen um die Werte zu verbessern?

Wie gut geschützt?

Wie wartbar?

Wie kompetent ist das Team?

Statische Code Analyse: Komplexität

public int score() {
  return firstRoll + secondRoll;
}
public int score() {
  int score = firstRoll + secondRoll;
  if (previous != null && previous.spare) {
    score += firstRoll;
  }
  return score;
}
public int score() {
  int score = firstRoll + secondRoll;
  if (previous != null) {
    if (previous.strike) {
      score *= 2;
    } else if (previous.spare) {
      score += firstRoll;
    }
  }
  return score;
}
previous
  .spare
score *= 2;
previous
  .strike
score += firstRoll;
previous != null
  && previous.spare
int score = firstRoll
  + secondRoll;
return score;

Wie wartbar?

Static Code Analysis: Code Smells

# Code Smells

- long methods,
- huge classes,
- many parameters,
- code duplicates,
- methods with complexity > 7,
- …

Wie wartbar?

Wie gut geschützt?

Wie wartbar?

Wie kompetent ist das Team?

Wie wartbar?

Wie kompetent ist das Team?

Wie gut geschützt?

Code
Smells

Code
Komplexität

Mutation
Testing

Team-
Umfragen

Wie produktiv?

Wie schnell?

Wie sicher?

Velocity

v = \frac{P_{estimate}}{t_{delivery} - t_{commit1}}

Wie schnell?

Wie gut sind unsere Schätzungen?

Delivery Lead Time

\Delta t_{delivery} = t_{delivery} - t_{commit1}

Wie schnell?

Wie produktiv?

Wie schnell?

Wie sicher?

Fehlerrate bei Änderung

08:07:23 Deploy basket-service ✓
09:06:11 Migrate checkout-service DB ✓
09:56:54 Deploy checkout-service ✓









08:07:23 Deploy basket-service ✓
09:06:11 Migrate checkout-service DB ✓
09:56:54 Deploy checkout-service ✓
10:19:44 Deploy order-managment-service ✗
10:39:27 Rollback order-managemet-service ✓







08:07:23 Deploy basket-service ✓
09:06:11 Migrate checkout-service DB ✓
09:56:54 Deploy checkout-service ✓
10:19:44 Deploy order-managment-service ✗
10:39:27 Rollback order-managemet-service ✓
11:09:59 Update database cluster ✓
12:27:32 Migrate order-managemet-service DB ✓
13:19:22 Deploy order-managemet-service ✓




08:07:23 Deploy basket-service ✓
09:06:11 Migrate checkout-service DB ✓
09:56:54 Deploy checkout-service ✓
10:19:44 Deploy order-managment-service ✗
10:39:27 Rollback order-managemet-service ✓
11:09:59 Update database cluster ✓
12:27:32 Migrate order-managemet-service DB ✓
13:19:22 Deploy order-managemet-service ✓
14:45:55 Update database-cluster ✗
15:50:49 Update database-cluster ✓


08:07:23 Deploy basket-service ✓
09:06:11 Migrate checkout-service DB ✓
09:56:54 Deploy checkout-service ✓
10:19:44 Deploy order-managment-service ✗
10:39:27 Rollback order-managemet-service ✓
11:09:59 Update database cluster ✓
12:27:32 Migrate order-managemet-service DB ✓
13:19:22 Deploy order-managemet-service ✓
14:45:55 Update database-cluster ✗
15:50:49 Update database-cluster ✓
16:39:11 Deploy product-service ✓
17:44:56 Deploy customer-data-service ✓

Wie sicher?

Mittlere Reperaturzeit

08:07:23 Deploy basket-service ✓
09:06:11 Migrate checkout-service DB ✓
09:56:54 Deploy checkout-service ✓
10:19:44 Deploy order-managment-service ✗
10:39:27 Rollback order-managemet-service ✓
11:09:59 Update database cluster ✓
12:27:32 Migrate order-managemet-service DB ✓
13:19:22 Deploy order-managemet-service ✓
14:45:55 Update database-cluster ✗
15:50:49 Update database-cluster ✓
16:39:11 Deploy product-service ✓
17:44:56 Deploy customer-data-service ✓

Wie sicher?

Wie produktiv?

Wie schnell?

Wie sicher?

Deployment-Frequenz

Wie produktiv?

Delivery Lead Time

Deployment-Frequenz

Fehlerrate bei Änderung

Mittlere Reperaturzeit

Wie produktiv?

Wie schnell?

Wie sicher?

Wie produktiv?

Wie sicher?

Wie schnell?

Mittlere
Reperaturzeit

Fehlerrate bei Änderung

Deployment
Frequenz

Delivery
Lead Time

Wie produktiv?

Wie sicher?

Wie schnell?

Wie wartbar?

Wie kompetent ist das Team?

Wie gut geschützt?

Wie fehlerhaft?

Wie funktional?

Wie beliebt?

UX Tests

User Tracking/
Observability

Service Level Objectives

Benutzer-beschwerden

Code
Smells

Code
Komplexität

Mutation
Testing

Mittlere
Reperaturzeit

Fehlerrate bei Änderung

Deployment
Frequenz

Delivery
Lead Time

Team-
Umfragen

@MichaKutz

@mkutz@mstdn.social

Not everything that counts can be counted,
and not everything that can be counted counts.

Slides

Wie man Qualität (nicht) misst

By Michael Kutz

Wie man Qualität (nicht) misst

This presentation explores the topic of measuring quality in software development and the potential pitfalls that can arise from improper measurement. It discusses the importance of finding the right metrics and addresses various aspects of quality, including defectiveness, effectiveness, likability, and functionality.

  • 541