let’s dev GmbH & Co. KG - Die Marke für wegweisende Individualsoftware

Blog

Top!

let’s dev | Scroll to top
let’s dev | Scroll to next content item

Hello

let’s dev | Scroll to previous content item
let’s dev Blog | 100% Code-Coverage bei Software Tests – eine sinnvolle Zielsetzung?
by Raphael
06. März 2020

100% Code-Coverage bei Software Tests – eine sinnvolle Zielsetzung?

Im Gegensatz zu anderen Produktionsbranchen, wie etwa der Autoindustrie, kann man an Software und ihren Komponenten keine physischen Messungen vornehmen, um Qualität sicherzustellen. Die Software Branche benötigt aber auch Werkzeuge zur Qualitätssicherung. Hier kommen die sogenannten Software Tests zum Einsatz.

Was sind Software Tests?

Glenford J. Myers und Corey Sandler definieren Software Tests in ihrem Buch “The Art of Software Testing” folgendermaßen:

“Testing is the process of executing a program with the intent of finding errors”

Tests sind also der Prozess, ein Programm mehrfach auszuführen um Fehler zu finden. Dies kann sowohl manuell durch Tester passieren als auch automatisch durch kleine Programme, die das Textprogramm ausführen und testen. Im folgenden werden die automatischen Tests betrachtet.

Automatische Software Tests kann man im Grunde in zwei Kategorien aufteilen: Funktionale Tests und Non-Funktionale Tests. Unter funktionalen Tests versteht man Tests, bei denen die Software oder Teile der Software auf Korrektheit überprüft werden. Beispielsweise, ob sich die Software in einer bestimmten Situation so verhält, wie in den Spezifikationen festgelegt wurde. Nicht funktionale Tests beziehen sich auf Eigenschaften von Software, wie etwa die Performance oder das Einhalten von Guidelines.

Welche Arten funktionaler Tests gibt es?

Es gibt viele verschiedene Arten funktionaler Tests, hier sollen aber nur drei Arten näher beleuchtet werden. Diese sind Unit-Tests, Integration-Tests und System Tests.

Ein Unit-Test ist ein Test einer Komponente. Damit ein Test als Unit-Test gilt, muss der Input kontrollierbar sein und die getestete Komponente keine Abhängigkeit zu einer anderen Komponenten haben. Ein Beispiel wäre eine Methode, die den ersten Übergabeparameter durch den zweiten Übergabeparameter teilt. Hier z.B. kann getestet werden, ob die Rechnung korrekt durchgeführt wird und ob das Teilen durch 0 behandelt wird.

Ein Integration-Test findet statt, sobald mehr als eine Komponente gleichzeitig abgetestet wird. Etwa wenn unsere Methode für das Teilen zweier Zahlen eine weitere Methode aufrufen würde.

System Tests oder auch End-to-End Tests sind Tests, die einen Prozess, die durch Programmspezifikationen festgelegt sind, abtastet. UI-Tests sind ein Beispiel für solche Tests.

So könnte in einer Spezifikation für ein Android Programm stehen: Bei Druck auf den Floating Action Button öffnet sich ein neues Fenster, in welchem ein neues Flugzeug hinzugefügt werden kann. Ein UI-Test würde dann den Button drücken und überprüfen, ob sich tatsächlich dieses spezifizierte Fenster öffnet. Wie man UI-Tests in Android mit Espresso schreibt, könnt ihr in dem zugehörigen Blogbeitrag nachlesen.

Was versteht man unter Code-Coverage?

Code-Coverage ist eine Metrik, die verwendet wird um zu messen, welche Teile der Software durch Tests abgedeckt werden. Genauer heißt das, welche Teile des Codes durch das Ausführen der Tests durchlaufen werden. Hierbei ist noch zu beachten, dass es zwei Begriffe gibt, die zwar oft synonym verwendet werde, jedoch unterschiedliches aussagen. Diese Begriffe sind Code-Coverage und Test-Coverage (Testabdeckung).

Während bei Code-Coverage ausschließlich die Abdeckung des Codes durch Ausführung der Tests berechnet wird, versteht man unter Test-Coverage die vollständige Abdeckung des Programms durch alle automatischen und manuellen Tests. Code-Coverage wird meist von Tools wie etwa Cobertura oder Jacoco berechnet und visualisiert.

Screenshot JaCoCo

Code-Coverage kann in verschiedenen Arten gemessen werden:

Diese verschiedenen Messwerte können in einigen Fällen stark voneinander abweichen. Hier ein kleines Beispiel anhand einer Methode:

public int divide(int numerator, int denominator) throws ArithmeticException{
    if (denominator == 0) {
        System.out.println("Cannot divide by zero");
        throw new ArithmeticException();
    } else {
        return (numerator / denominator);
    }
}

Für diese Methode würden wir folgenden Unit-Test schreiben:

@Test
public void test_divide() {
    int result = divide(4, 2);
    Assert.assertEquals(2, result);
}

Wenn wir anschließend die Coverage dieses Tests errechnen lassen, erhalten wir folgende Ergebnisse:

Hier kann man bereits sehen, wie unterschiedlich die Messungen für verschiedene Typen der Code-Coverage ausfallen können. Während die Funktionsabdeckung bei vollständigen 100% liegt, befindet sich die Abdeckung der Branches nur bei der Hälfte. Code-Coverage kann also verwendet werden, um herauszufinden, welche Teile des Codes bereits mit Tests abgedeckt worden sind. Sie kann jedoch nichts über die Qualität der Tests aussagen.

Der Test im obigen Beispiel führt die Funktion zwar aus und überprüft das Ergebnis, jedoch wird nur ein möglicher Fall abgedeckt. Was wäre zum Beispiel, wenn 0 als Teiler übergeben wird? Fügen wir noch folgenden Test für das Verhalten bei Übergabe von 0 hinzu, so erreichen wir auch 100% Line und Branch Coverage:

@Test(expected = ArithmeticException.class)
public void test_divide_zeroAsDenominator_ShouldThrowException(){
    divide(2,0);
}

Wurde diese Methode nun vollständig getestet? Die Antwort auf diese Frage lautet nein, da das Verhalten der Funktion bei Übergabewerten, die nicht zu einem runden Ergebnis führen, nicht getestet ist. Dennoch zeigte uns die Coverage hier eine hundertprozentige Abdeckung in allen Kategorien an. Hier kann man bereits sehen, dass selbst bei vollständiger Abdeckung nicht garantiert ist, dass der abgedeckte Code selbst vollständig getestet wurde.

Außerdem möchte ich an dieser Stelle noch erwähnen, dass es relativ einfach ist, eine hohe Code-Coverage zu erreichen, indem Tests geschrieben werden, welche keine assert-Anweisungen enthalten. Diese haben nur einen geringen Wert für das Projekt und sollten auch nicht geschrieben werden. Trotzdem würde ein solcher Test Laufzeitfehler im durchlaufenen Code aufdecken, was jedoch für mich keine Entschuldigung ist assert freie Tests zu schreiben.

100% Code-Coverage ein sinnvolles Ziel?

Das Thema 100% Code-Coverage wird in der Branche relativ kontrovers diskutiert. Grundsätzlich gibt es für zwei verschiedene Ansichten zu diesem Thema:

1.) 100% Code-Coverage sollte immer angestrebt werden und ist ein wichtiges Qualitätsmerkmal des Codes. Es gibt unterschiedliche Ansichten, wie die 100% erreicht werden können. So kann 100% Abdeckung erreicht werden, indem man von vorne herein darauf achtet, testbaren Code zu schreiben und triviale Funktionen, wie etwa getter/setter entweder aus der Coverage auszuschließen oder gar nicht erst zu schreiben. Hier vertreten einige auch die Meinung, dass nicht testbarer Code nicht existieren sollte. Außerdem sollten nicht hauptsächlich Unit-Tests, sondern auch Integration Tests geschrieben werden.

2.) 100% Code-Coverage sollte nicht angestrebt werden, da sie zum einen nichts über die Qualität und Vollständigkeit der Tests aussagt und das Erreichen höherer Coverage zum anderen ab einer gewissen Schwelle mit zu hohem Aufwand verbunden ist. Außerdem ist bei einer festgelegten Coverage die Versuchung groß, Tests statt zur Qualitätssicherung für die Abdeckung zu schreiben, was dem ursprünglichen Zweck von Tests widerspricht.

Grundsätzlich herrscht jedoch Konsens darüber, dass ein Programm eine hohe Testabdeckung haben sollte. Außerdem sagen auch Unterstützer der ersten Ansicht, dass Code-Coverage nichts über die Qualität der Tests aussagt und 100% Abdeckung nicht 100% fehlerfreien Code bedeutet.

Ist es nun sinnvoll 100%-Code-Coverage in einem Projekt anzustreben?

Meiner Meinung nach ist es nicht sinnvoll, sich die 100% oder auch eine beliebige andere Zahl als Ziel für die Code-Coverage zu setzen. Das soll jedoch nicht bedeuten, dass Code-Coverage eine nutzlose Metrik ist. Ich finde jedes Projekt sollte eine hohe Code-Coverage anstreben, ohne einen festen Prozentsatz festzulegen.

Code-Coverage ist eine sinnvolle Metrik, die man auf jeden Fall verwenden sollte. Durch sie kann man erkennen, welche Module noch mehr Tests vertragen könnten. Außerdem bin ich der Meinung, dass eine hohe Abdeckung dazu führt, dass weniger Bugs bis in die Produktivversion durchkommen. Dieser Eindruck wird wird durch eine Analyse von Microsoft zu ihren Testbemühungen bestätigt. Außerdem sollten nicht ausschließlich Unit-Tests verwendet werden, um eine hohe Code-Coverage zu erreichen.

Für mich spricht gegen ein Festlegen der zu erreichenden Code-Coverage die Tendenz, Tests nach maximaler Codeabdeckung zu schreiben. Selbst wenn qualitativ hochwertige Tests geschrieben werden, werden eventuell wichtigere Module nicht getestet. Insgesamt halte ich es für wichtiger, kritische Module mit Tests abzudecken und für diese Module eine hohe Abdeckung zu erreichen, als Tests für die Gesamtabdeckung zu schreiben.

Weitere Artikel aus unserem Blog

let’s dev Blog | UX Research Teil 3 – UX Methoden

Technical

UX Research Teil 3 – UX Methoden

by Elena

2020-05-28

Weiterlesen
let’s dev Blog | UX Research Teil 2 - Was ist UCD und was hat User Research damit zu tun?

Technical

UX Research Teil 2 - Was ist UCD und was hat User Research damit zu tun?

by Elena

2020-04-23

Weiterlesen
let’s dev Blog | go-digital fördert Einrichtung von Home Office Arbeitsplätzen

Corporate

go-digital fördert Einrichtung von Home Office Arbeitsplätzen

by Karl

2020-03-19

Weiterlesen
let’s dev Blog | Google Passes - Karten­verwaltung auf  Android-Geräten

Technical

Google Passes - Karten­verwaltung auf Android-Geräten

by Michelle

2020-03-12

Weiterlesen
let’s dev Blog | Swift UI - Einfache und schnelle Umsetzung von User Interfaces

Technical

Swift UI - Einfache und schnelle Umsetzung von User Interfaces

by Tobias

2020-03-02

Weiterlesen
let’s dev Blog | Im Dialog mit den Wirtschafts­junioren – Spannende Einblicke in die Unternehmens­gründung und die digitale Trans­formation

Corporate

Im Dialog mit den Wirtschafts­junioren – Spannende Einblicke in die Unternehmens­gründung und die digitale Trans­formation

by Julian

2020-02-27

Weiterlesen
let’s dev Blog | Vereinfachtes Testen von iOS Push Notifications im Simulator mit Xcode 11.4

Technical

Vereinfachtes Testen von iOS Push Notifications im Simulator mit Xcode 11.4

by Manuel

2020-02-26

Weiterlesen
let’s dev Blog | Nationales Meeting des Konsortiums des SPEAR Forschungs­projektes bei let’s dev in Karlsruhe

Corporate

Nationales Meeting des Konsortiums des SPEAR Forschungs­projektes bei let’s dev in Karlsruhe

by Karl

2020-01-27

Weiterlesen
let’s dev Blog | UX Research Teil 1 – Warum User Research so wichtig ist

Technical

UX Research Teil 1 – Warum User Research so wichtig ist

by Elena

2020-01-23

Weiterlesen
let’s dev Blog | Dark Mode

Technical

Dark Mode

by Elisa

2020-01-09

Weiterlesen
let’s dev Blog | Wir wünschen frohe Weihnachten – Und einen guten Start ins neue Jahr!

Corporate

Wir wünschen frohe Weihnachten – Und einen guten Start ins neue Jahr!

by Julian

2019-12-20

Weiterlesen
let’s dev Blog | Austausch zum Thema Digitalisierung mit dem Business Club Luxemburg in der Botschaft von Luxemburg in Berlin

Corporate

Austausch zum Thema Digitalisierung mit dem Business Club Luxemburg in der Botschaft von Luxemburg in Berlin

by Karl

2019-12-17

Weiterlesen
let’s dev Blog | DaSoMan auf der Internet+ Expo in Foshan (China)

Corporate

DaSoMan auf der Internet+ Expo in Foshan (China)

by Karl

2019-12-13

Weiterlesen
let’s dev Blog | Google Play Console: Pre-Launch Berichte

Technical

Google Play Console: Pre-Launch Berichte

by Fabian

2019-12-11

Weiterlesen
let’s dev Blog | DevFest 2019 in Hamburg

Technical

DevFest 2019 in Hamburg

by Julian

2019-12-05

Weiterlesen
let’s dev Blog | Vernissage digitale Kunst im Medientheater der Humboldt Universität Berlin

Corporate

Vernissage digitale Kunst im Medientheater der Humboldt Universität Berlin

by Karl

2019-11-21

Weiterlesen
let’s dev Blog | World Usability Day 2019 in Karlsruhe – let’s dev unterstützt als Hauptsponsor

Corporate

World Usability Day 2019 in Karlsruhe – let’s dev unterstützt als Hauptsponsor

by Aileen

2019-11-11

Weiterlesen
let’s dev Blog | Ausgeschlachtet - Tag der offenen Türen auf dem Alten Schlachthof Karlsruhe 2019

Corporate

Ausgeschlachtet - Tag der offenen Türen auf dem Alten Schlachthof Karlsruhe 2019

by Julian

2019-09-26

Weiterlesen
let’s dev Blog | Mensch und Computer 2019 - Konferenz zu User Experience und Usability in Hamburg

Corporate

Mensch und Computer 2019 - Konferenz zu User Experience und Usability in Hamburg

by Elena

2019-09-17

Weiterlesen
let’s dev Blog | Business und Enterprise App Verteilung unter iOS

Technical

Business und Enterprise App Verteilung unter iOS

by Aileen

2019-08-05

Weiterlesen
let’s dev Blog | Digital Transformation - Chances and Challenges in the Automotive Industry, Agriculture and New Technologies

Corporate

Digital Transformation - Chances and Challenges in the Automotive Industry, Agriculture and New Technologies

by Karl

2019-07-17

Weiterlesen
let’s dev Blog | let’s dev unterstützt Läuferinnen und Läufer bei der 7. KIT Meisterschaft

Corporate

let’s dev unterstützt Läuferinnen und Läufer bei der 7. KIT Meisterschaft

by Karl

2019-07-05

Weiterlesen
let’s dev Blog | Automatisiertes Testing von C++ Code mit Google Test und Google Mock – Teil 2

Technical

Automatisiertes Testing von C++ Code mit Google Test und Google Mock – Teil 2

by Arne

2019-06-13

Weiterlesen
let’s dev Blog | Apple WWDC 2019: Das sind die Highlights der Keynote

Technical

Apple WWDC 2019: Das sind die Highlights der Keynote

by Nicolas

2019-06-05

Weiterlesen
let’s dev Blog | App Builders 2019

Technical

App Builders 2019

by Nicolas

2019-05-23

Weiterlesen
let’s dev Blog | Offizielle Eröffnung des Festigungs- und Expansionszentrums (FUX)

Corporate

Offizielle Eröffnung des Festigungs- und Expansionszentrums (FUX)

by Helena

2019-04-15

Weiterlesen
let’s dev Blog | Delegation aus Nottingham zu Besuch auf dem Alten Schlachthof in Karlsruhe

Corporate

Delegation aus Nottingham zu Besuch auf dem Alten Schlachthof in Karlsruhe

by Helena

2019-04-14

Weiterlesen
let’s dev Blog | Es ist soweit: Wir ziehen um!

Corporate

Es ist soweit: Wir ziehen um!

by Helena

2019-03-26

Weiterlesen
let’s dev Blog | Automatisiertes Testing von C++ Code mit Frameworks – Teil 1

Technical

Automatisiertes Testing von C++ Code mit Frameworks – Teil 1

by Arne

2019-02-20

Weiterlesen
let’s dev Blog | Die App im Google Play Store

Technical

Die App im Google Play Store

by Elisa

2019-01-24

Weiterlesen
let’s dev Blog | „UX Day“ 2018

Corporate

„UX Day“ 2018

by Aileen

2018-12-17

Weiterlesen
let’s dev Blog | let’s dev unterstützt SG Siemens Volleyballer aus Karlsruhe

Corporate

let’s dev unterstützt SG Siemens Volleyballer aus Karlsruhe

by Helena

2018-12-04

Weiterlesen
let’s dev Blog | KMU gestalten die Digitalisierung – Mittelstandskonferenz 2018

Corporate

KMU gestalten die Digitalisierung – Mittelstandskonferenz 2018

by Helena

2018-11-12

Weiterlesen
let’s dev Blog | Apple Wallet

Technical

Apple Wallet

by Maik

2018-10-26

Weiterlesen
let’s dev Blog | „Mensch und Computer“ 2018

Corporate

„Mensch und Computer“ 2018

by Judith

2018-09-24

Weiterlesen
let’s dev Blog | State Design Pattern in Android

Technical

State Design Pattern in Android

by Thomas

2018-09-17

Weiterlesen
let’s dev Blog | let’s dev ist autorisiertes Beraterunternehmen im Förderprogramm „go-digital“

Corporate

let’s dev ist autorisiertes Beraterunternehmen im Förderprogramm „go-digital“

by Helena

2018-09-01

Weiterlesen
let’s dev Blog | App Design & Development Conference 2018

Corporate

App Design & Development Conference 2018

by Helena

2018-08-14

Weiterlesen
let’s dev Blog | iOS 12: Die Top-Neuerungen im Überblick

Technical

iOS 12: Die Top-Neuerungen im Überblick

by Nicolas

2018-07-17

Weiterlesen
let’s dev Blog | let’s dev auf der CEBIT

Corporate

let’s dev auf der CEBIT

by Karl

2018-06-11

Weiterlesen
let’s dev Blog | Einführung in User Interface (UI) Tests mit Espresso

Technical

Einführung in User Interface (UI) Tests mit Espresso

by Raphael

2018-06-07

Weiterlesen
let’s dev Blog | Die App im Apple App Store: welche Informationen werden benötigt?

Technical

Die App im Apple App Store: welche Informationen werden benötigt?

by Aileen

2018-04-27

Weiterlesen
let’s dev Blog | Smart Pointer in C++

Technical

Smart Pointer in C++

by Matthias

2018-04-01

Weiterlesen
let’s dev Blog | User Interface Design für das iPhone X: alle Neuerungen auf einen Blick

Technical

User Interface Design für das iPhone X: alle Neuerungen auf einen Blick

by Helena

2018-02-07

Weiterlesen
let’s dev Blog | WebVR – Virtual Reality Experience im Browser mit dem A-Frame Framework

Technical

WebVR – Virtual Reality Experience im Browser mit dem A-Frame Framework

by Judith

2018-01-10

Weiterlesen
let’s dev Blog | Open Data Hackathon der Deutschen Bahn

Corporate

Open Data Hackathon der Deutschen Bahn

by Karl

2015-03-31

Weiterlesen
let’s dev Blog | Blur-Effekte unter iOS 7

Technical

Blur-Effekte unter iOS 7

by Katja

2014-04-24

Weiterlesen
let’s dev Blog | Beyond App Store – Distribution von iOS-Anwendungen

Technical

Beyond App Store – Distribution von iOS-Anwendungen

by Karl

2012-08-27

Weiterlesen
let’s dev Blog | Frontend-Architektur – Model View Presenter und Message Bus

Technical

Frontend-Architektur – Model View Presenter und Message Bus

by Karl

2011-03-08

Weiterlesen