Immer wieder liest oder hört man im Bereich der Software- und natürlich auch Webentwicklung von „testbarem Code“. Doch was genau ist damit eigentlich gemeint? Was macht Code testbar, und was nicht? Sollten wir uns alle vielleicht ein Stück weit damit beschäftigen? Und: was hat das Ganze mit Unit-Testing zu tun?

Testing

Um der Sache auf den Grund zu gehen, schauen wir uns zunächst einmal an, was sich formal hinter dem Begriff „Testing“ verbirgt.

Definition: Testing

Nach dem ISTQB® (International Software Testing Qualifications Board) umfasst Testing sämtliche Aktivitäten, dynamische wie statische, die sich mit der Planung, Aufbereitung und Evaluierung von Software befassen. Das eigentliche Ziel ist es, festzustellen, ob die getestete Software allen Anforderungen entspricht, sowie potentielle Fehler (engl. defects, oder auch bugs) aufzudecken.

The process consisting of all lifecycle activities, both static and dynamic, concerned with planning, preparation and evaluation of software products and related work products to determine that they satisfy specified requirements, to demonstrate that they are fit for purpose and to detect defects.
(Quelle: ISTQB Glossary)

Dies ist ein Test

Mit etwas Abstand (und ein Wenig Humor) betrachtet, kann man das nachfolgende Suchbild also als eine Art Test verstehen:

Abbildung_-_Suchbild

Suchbild als visueller Vergleich für einen Test. (Quelle: Mopf-der Blog, www.blog.mopf.net/)

Wir haben hier zwei Dinge, die wir miteinander vergleichen, um herauszufinden, ob sie einander entsprechen. Hierbei ist es völlig egal, welche Seite die Anforderung ist und welche die Implementierung, also das Ergebnis. Ist es möglich, einen oder mehrere Unterschiede festzustellen, sind die zwei Dinge nicht gleich, und der Test ist fehlgeschlagen (bzw. er war erfolgreich darin, den oder die Fehler aufzuzeigen).

Wen es interessiert: es gibt in unserem Beispiel insgesamt fünf Unterschiede zu entdecken.

Warum testen?

Gute Gründe dafür, Software ordnungsgemäß zu testen, gibt es zuhauf. Allem voran die ernüchternde Tatsache, dass Software Fehler enthält. Immer. Diese Fehler im Programmcode können zum Fehlverhalten der Software führen. Und dieses Fehlverhalten wiederum kann einerseits Geld kosten, oder, je nach Einsatzort oder -zweck, auch Menschenleben!

Tests sind lebendige Dokumentationen. Sie vermitteln eine Aussage über die Qualität der Software und schaffen so Vertrauen in selbe. Außerdem kann Testing, nachdem die zu erwartenden anfänglichen Schwierigkeiten erst einmal überwunden sind, tatsächlich auch die Softwareentwicklung merklich beschleunigen.

Hätte man beispielsweise die Software der wohl bekanntesten Ariane 5 vollständig getestet, wäre sie vermutlich länger als die knapp 40 Sekunden in der Luft geblieben…

Testbarer Code

Kommen wir also nun zurück zu unserem testbaren Code. Wenn wir das zuvor Erwähnte einmal Revue passieren lassen, könnten wir recht schnell zu folgendem Schluss kommen: jedes Stück Software ist testbar. Und das ist auch völlig richtig.

Code kann immer getestet werden

Man kann zum Beispiel die Rückgabewerte einer bestimmten Funktion oder Methode testen. Oder den Output, wenn man beispielsweise an PHP oder aber auch React denkt, wo letzten Endes eine Ausgabe in Form von HTML-Code erzeugt wird. Ebenfalls testbar ist, ob eine bestimmte Aktion Seiteneffekte erzeugt. Der simpelste aller Tests ist oft das bloße Ausführen eines Programms, um sicherzustellen, dass es nicht abstürzt.

Nicht jeder Code ist testbarer Code

Obwohl jede Software grundsätzlich testbar ist, wäre es nicht ganz richtig, zu sagen, dass sie daher durchweg testbaren Code besitzt. Das stimmt aus folgenden zwei Gründen nicht:

  1. Fast immer, wenn jemand von testbarem Code spricht, passiert dies im Kontext des Unit-Testings.
  2. Es gibt eine ganze Reihe von Dingen, die das Unit-Testing von Software, in Teilen oder im Ganzen, äußerst schwer gestaltet, oder gar unmöglich macht.

Folglich ist mit testbarem Code eigentlich unit-testbarer Code gemeint.

Unit-Testing

Nachdem wir das Software-Testing allgemein kurz und knapp definiert und zudem gute Gründe für dessen Durchführung genannt haben, kommen wir nun zum eigentlichen Thema dieses Beitrags: dem Unit-Testing.

Wo ist Unit-Testing?

Bevor wir uns jedoch um das Was des Unit-Testings kümmern, wollen wir zunächst einmal das Wo klären. Besonders hilfreich ist hierbei das gute alte V-Modell, welches in der folgenden Grafik dargestellt ist.

Abbildung - v-model mit einer Darstellung der unterschiedlichen Phasen des Softwareentwicklungsprozesses

V-Modell mit Darstellung der unterschiedlichen Phasen des Softwareentwicklungsprozesses.

Aber keine Sorge! Hier geht es nicht darum, tatsächlich nach dem (bzw. einem) V-Modell Software zu entwickeln. Ich selbst habe das noch nie getan und werde das daher auch nicht lehren. Zudem halte ich dieses Vorgehensmodell für völlig antiquiert.

Das V-Modell eignet sich jedoch sehr gut dazu, einen Überblick über die unterschiedlichen Phasen in der Softwareentwicklung zu gewinnen. Zum einen haben wir auf der linken Seite die Entwicklungs- bzw. Definitionsphasen, die schließlich im Software-Entwurf (engl. implementation) enden. Diesen gegenübergestellt sind die unterschiedlichen Teststufen, beginnend mit dem Unit-Testing. Unabhängig vom tatsächlich eingesetzten Softwareentwicklungsprozess wird man sämtliche Phasen in der Regel irgendwo durchlaufen: manchmal (geplant) einmalig, manchmal (geplant) mehrfach.

Ebenfalls sehr gut zu erkennen sind die Beziehungen zwischen den einzelnen Phasen innerhalb einer Seite, sowie seitenübergreifend, also von einer der Teststufen zu einer der Definitionsphasen. Die durchgezogenen grauen Pfeile geben die Reihenfolge der einzelnen Phasen an. Dies bedeutet jedoch nicht, dass man, wenn eine bestimmte Phase einmal erreicht ist, nie wieder zurück geht. Die Reihenfolge sagt vielmehr aus, dass man eine bestimmte Phase nicht beginnen kann bzw. sollte, bevor die entsprechende andere Phase nicht zumindest vorläufig abgeschlossen ist. Die gestrichelten Pfeile von einer Entwicklungsphase zurück zur vorherigen repräsentieren statische Tests, wobei die gepunkteten Pfeile von rechts nach links für die unterschiedlichen Arten von dynamischen Tests stehen. Hierbei wird stets der geschriebene Code getestet, und zwar anhand von Testdefinitionen, die in der jeweils entsprechenden Entwicklungsphase erarbeitet wurden.

In puncto Unit-Testing können wir also sehen, dass der Softwareentwurf gegen das Modul- bzw. Algorithmusdesign getestet wird, und dass Unit-Testing als erste aller Teststufen die Basis für potentielle Integrationstests bildet.

Terminologie

Namen sind Schall und Rauch, geht es doch oftmals mehr um die Konzepte dahinter. In fast keinem anderen Bereich der Softwareentwicklung gibt es jedoch derart viele Probleme und Missverständnisse im Zusammenhang mit Namensgebung oder Kategorisierung, wie es beim Testing der Fall ist. Wenn dann auch noch Englisch als zweite (Fach-)Sprache hinzukommt, steht man vor allem als unerfahrener Neuling wie der Ochs vorm Berg. Aus diesem Grund klären wir daher erst einmal eine Reihe unterschiedlicher Begrifflichkeiten, die uns früher oder später unterkommen könnten.

Beim Unit-Testing geht es, wer hätte das gedacht, um Unit-Tests. Doch je nach Kontext, das heißt zum Beispiel Programmiersprache, Lernmaterial oder auch einfach nur Vorliebe, wird anstelle von „Unit“ der Begriff „Modul“ benutzt. Wikipedia beispielsweise verwendet „Modultest“ als kanonischen Namen, was auch durch die Weiterleitung von „Unit-Test“ auf die erstgenannte Seite ersichtlich ist. Ein weiterer, ebenfalls weit verbreiteter Name ist „Komponententest„.

Was ist Unit-Testing

Ob Unit-Test, Modultest oder gar Komponententest: das eigentliche Prinzip ist stets das Gleiche. Es geht darum, Software nicht im Ganzen zu testen, sondern sämtliche Tests jeweils auf genau eine funktionale Einheit der zu testenden Software auszurichten.

Unit-Testing ist dynamisches Testen einzelner Einheiten in Isolation.

Eigentlich ist mit dem vorigen Satz bereits alles gesagt, wenn es um das Grundverständnis beim Unit-Testing geht. Aber natürlich hilft einem dies nicht besonders, wenn einem Dinge wie dynamisches Testen, die Definition einer Einheit oder das Testen in Isolation ebenfalls unklar sind. In den folgenden Abschnitten wollen wir uns daher diesen drei Konzepten im Detail widmen.

Unit-Testing ist dynamisches Testen

Beim dynamischen Testen geht es immer darum, dass der zu testende Code ausgeführt wird. Anders als beim statischen Testen, welches ein bloßes Lesen bzw. Analysieren des Codes umfasst, können durch das Ausführen der Software potentielle Fehler im Code in Form von Fehlverhalten entdeckt werden. Wird solch ein Fehlverhalten beobachtet, geht es im nächsten Schritt ans Debugging. Das bedeutet, dass die für das Fehlverhalten verantwortlichen Bugs gesucht und anschließend natürlich auch gefixt werden.

Testing und Softwarequalität

Unit-Testing allein ist, wie Testing ganz allgemein, kein qualitätssteigernder Prozess, denn es sagt lediglich etwas über die aktuelle Qualität der Software aus. Der komplette Ablauf von Testing, Debugging und Bugfixing hingegen gipfelt, wenn erfolgreich, tatsächlich in einer Steigerung der Softwarequalität. Somit ist Unit-Testing ein erster, wichtiger Schritt hin zu besserer Software.

Validierung

Die primäre Aufgabe des dynamischen Testens und damit auch des Unit-Testings, ist die Validierung. Dabei geht es darum, sicherzustellen, dass die entwickelte Software tatsächlich auch sämtliche Anforderungen und damit ihren eigentlichen Zweck erfüllt.

The process of evaluating a system or component during or at the end of the development process to determine whether it satisfies specified requirements.
(Quelle: IEEE 610.12-1990 – IEEE Standard Glossary of Software Engineering Terminology)

Der Validierung gegenüber steht die Verifikation, welche hauptsächlich beim statischen Testen erfolgt. Als wichtige Bestandteile des Software-Testings werden Validierung und Verifikation jedoch oft verwechselt oder gar vermischt. Barry W. Boehm hat Validierung aus diesem Grund durch folgende, einfache Frage definiert: „Are we building the right product?„. Eine mögliche freie Übersetzung ist „Machen wir das Richtige?“. Verifikation hingegen fragt „Are we building the product right?“ bzw. „Machen wir das richtig?“.

Definition einer Einheit

Beim Unit-Testing geht es darum, einzelne Einheiten zu testen. So weit, so gut. Aber was genau ist eine Einheit?

Auf diese Frage gibt es, zugegebenermaßen, keine einfache und zugleich definitive Antwort. Im Bereich der Webentwicklung jedoch, wo wir beispielsweise mit PHP und JavaScript zu tun haben, wird eine Einheit nahezu ausnahmslos als eine einzelne Funktion (oder auch Methode) definiert.

Doch gehen wir einfach einmal gemeinsam potentielle Einheiten durch, und überlegen, warum sie in Frage kommen, oder eben nicht.

Von Zeichen zu Klassen

Wenn wir von Einheiten im Programmcode sprechen, stellen Zeichen wohl das Atomar-Level dar. Sicher, es gibt auch Multibyte-Zeichen, also könnten wir ein Zeichen auch noch in einzelne Bytes unterteilen. Und dann sind da natürlich auch noch Bits! Aber für uns als Webentwickler ist das alles nicht wirklich greifbar, und es begegnet uns auch nicht bei der täglichen Arbeit in unserer IDE. Bleiben wir also bei Zeichen.

Aus mehreren Zeichen können wir Wörter formen. Diese können Werte sein, oder Schlüsselworte in der jeweiligen Programmiersprache, bzw. Namen von Variablen, Funktionen und dergleichen. Mehrere Wörter wiederum ergeben einen Satz, und wenn wir die Syntaxregeln beachten, gelangen wir somit zu Ausdrücken (engl. expression, oder statement).

Durch das Kombinieren von Wörtern und Ausdrücken – manche davon Schlüsselworte, andere Werte, und dann noch einen Operator hier und da – erhalten wir schließlich Logik, zum Beispiel mathematische Logik oder auch Konditionallogik. Hierbei ist Folgendes besonders interessant: Programmlogik ist die erste Klassifizierung einer Einheit, bei der Testen sowohl möglich ist, als auch Sinn macht.

Bleiben wir für einen Moment bei PHP und JavaScript, also Programmiersprachen, die sowohl prozeduralen Code, als auch objektorientierte Programmierung erlauben. Hier sind die nächsten beiden Stufen in unserer Hierarchie der möglichen Einheiten Funktionen (oder Methoden) und Klassen (oder Module).

Sinnvolle Einheiten

Zwar gibt es über Klassen noch weitere Ebenen, wie beispielsweise Namensräume oder Pakete, doch haben wir ja mit Logik bereits eine Form der Einheit gefunden, die auch testbar ist. Folglich sind Funktionen, welche Logik abstrahieren, und auch Klassen, welche wiederum Funktionen kapseln (und vielleicht auch einen inneren Zustand besitzen), ebenfalls testbar.

Wenn wir noch einmal etwas genauer über Logik nachdenken, könnte uns auffallen, dass Logik, obwohl testbar an sich, nicht zwangsläufig als Einheit in Isolation getestet werden kann. Was das nun genau bedeuten, wird im nächsten Abschnitt erläutert. Anhand der folgenden, recht einfachen Funktion sehen wir jedoch, dass Logik keine sonderlich geeignete Einheit im Kontext des Unit-Testings ist.

function doubleOrHalf( number ) {
    if ( number > 0 ) {
        return number * 2;
    }

    return number / 2;
}

Der obige Code beinhaltet drei unterschiedliche Stücke Logik: eine Bedingung (number > 0) und zwei Rechenoperationen (number * 2 und number / 2). Schnell leuchtet ein, dass in jedem Fall die Bedingung ausgewertet wird, egal welchen Wert wir der Funktion beim Aufruf auch mitgeben. Das bedeutet also, dass keine der mathematischen Anweisungen ohne die Bedingung getestet werden kann. Zudem kann aber auch die Bedingung nicht alleine getestet werden, denn entweder ist sie wahr, was in der ersten Rückgabe und somit Berechnung endet, oder aber die Bedingung ist falsch, wodurch die zweite Berechnung ausgewertet wird.

Demnach kommen als sinnvolle Einheiten nur Funktionen oder Klassen in Frage. Im Großteil der Fälle gewinnt Erstere. Das bedeutet also, eine Einheit beim Unit-Testing entspricht in der Regel einer einzelnen Funktion.

Testen in Isolation

Einer der wichtigsten Aspekte des Unit-Testings ist merkwürdigerweise auch der, der am häufigsten vergessen wird: jede zu testende Einheit muss in Isolation getestet werden, also ohne ein Zutun anderer Einheiten. Auf die Software bezogen heißt das, dass wir nur den Code dieser einen Einheit ausführen wollen, und nichts anderes.

Warum in Isolation testen?

Der Grund dafür ist recht simpel. Angenommen wir führen einen umfangreichen Test aus und involvieren dabei eine Reihe von PHP-Klassen und auch Funktionen. Wenn dieser Test nun fehlschlägt, haben wir erst einmal keine Ahnung, warum. Wir beginnen mit einem einzigen Funktions- oder Methodenaufruf, der dann wiederum andere Funktionen anstößt, die wiederum zwei oder drei neue Objekte erzeugen und Methoden darauf ausführen und … ehe wir uns versehen, haben wir sowohl die Kontrolle, als auch den Überblick über das, was gerade geschieht, verloren.

Ist der einzige echte Code jedoch der, der unsere zu testende Einheit definiert (wobei hier bei der objektorientierten Programmierung auch private Methoden derselben Klasse zulässig sind), dann wissen wir mit Bestimmtheit: der Grund für einen fehlgeschlagenen Unit-Test liegt in der zu testende Methode selbst. Na ja, oder dem Test-Code. 😉

Abhängigkeiten kontrollieren durch Mocking

Alles klar! Aber wie stellen wir nun sicher, dass wir eine einzelne Einheit tatsächlich auch in Isolation testen (können)? Die Antwort auf diese Frage liest sich recht einfach, ist jedoch nicht immer einfach umzusetzen: durch die Definition von Dummy-Funktionen, über die wir volle Kontrolle haben.

Je nachdem, welche Werkzeuge und Bibliotheken man verwendet, oder welche Bücher und Online-Artikel man kürzlich gelesen haben mag, kommen einem eine ganze Reihe merkwürdiger Dinge unter: Mocks, Stubs, Spies, Fake– oder Dummy-Funktionen, Test-Doubles und noch einiges mehr.

Obwohl es zwischen diesen Begrifflichkeiten ein paar (teils bedeutende) Unterschiede gibt, sorgen sie doch alle für die folgenden zwei Dinge:

  1. Wenn wir die zu testende Einheit ausführen, gibt es keine Fehler.
  2. Sämtliche anderen Einheiten, die in irgendeiner Art am Programmablauf beteiligt sind, sind unecht und besitzen keine echte Logik, wenn überhaupt.

In manchen Programmiersprachen ist es möglich, definierte Symbole (z.B. eine Funktion oder auch eine Klasse) einfach neu zu definieren, also so gesehen, die alte Definition zu überschreiben. JavaScript ist eine solche Sprache, zumindest wenn man an ECMAScript 5 und die althergebrachten Definitionsweisen von Funktionen und Variablen mit function bzw. var denkt. In PHP beispielsweise ist es nicht einfach möglich, eine Funktion, Methode oder Klasse neu zu definieren, wenn sie bereits irgendwo für den aktuellen Prozess definiert worden ist. Das bedeutet folglich, dass wir das (automatische oder manuelle) Definieren sämtlicher Einheiten verhindern müssen – abgesehen von unserer zu testenden Einheit natürlich. Zudem müssen wir anstelle der echten Definitionen aber auch etwas anderes, was auf die gleiche Art wie das Original benutzt werden kann, bereitstellen – sogenannte Mocks. Tun wir dies nicht, sind Fehler vorprogrammiert, denn unser Code bezieht sich auf Dinge, die nirgends definiert sind.

Für die meisten Unit-Tests reicht es jedoch nicht aus, einfach nur sicherzustellen, dass Dinge existieren. Oft müssen wir diesen Mocks auch ein bestimmtes Verhalten aufzwingen, also zum Beispiel festlegen, dass sie gewisse Ausgaben erzeugen oder Werte zurückgeben, die für den jeweiligen Test Sinn ergeben oder zumindest den Anforderungen entsprechen.

Unit-Testing erfordert Wissen um Programminterna

Beim dynamischen Testen gibt es unterschiedliche Test-Methoden. Eine davon nennt sich White-Box-Testing, und im Gegensatz zum Black-Box-Testing, welches den zu testenden Code bzw. die ganze zu testende Software an sich als eine Art Blackbox ansieht, setzt White-Box-Testing Detailkenntnisse des Programmcodes zwingend voraus. Daher wird diese Art des Testens hin und wieder auch Glass-Box-Testing genannt, weil man in die Software hineinsehen kann bzw. können muss.

Beim Unit-Testing werden nahezu ausschließlich Techniken des White-Box-Testings eingesetzt, was also Wissen um Interna erfordert. In anderen Worten: für die Entwicklung von Unit-Tests wird der tatsächliche Programmcode benötigt. Aus diesem Grund werden Unit-Tests in der Regel auch von Entwicklern geschrieben, nicht selten von denjenigen, die auch die eigentliche Software entwickeln.

Ein kleines Code-Beispiel dazu:

function answer() {
    return '42';
}

Wir sehen hier eine einzelne einfache Funktion (ganz gleich, ob PHP, JavaScript oder Pseudocode), die nicht sonderlich viel tut. Wenn man die Funktion ausführt, gibt sie den die Zeichenkette „42“ zurück.

Wollen wir nun testen, ob diese Funktion, also unsere Einheit, sich den Anforderungen entsprechend verhält, müssen wir natürlich wissen, was diese Anforderungen denn sind. Anhand des Codes allein sehen wir, dass die Funktion keine Ausgabe erzeugt, dass sie keine Eingaben erwartet bzw. verwendet, sondern immer einen konstanten Wert vom Type String liefert. In diesem einfachen Fall ist das erwartete Verhalten also, dass die Funktion, wenn ausgeführt, den String „42“ zurückgibt.

Was macht gute Unit-Tests aus?

Angenommen wir haben das Prinzip Unit-Test verstanden, und auch, warum Unit-Testing eine gute Sache ist. Woher wissen wir nun aber, wie ein guter Unit-Test aussieht? Genau zu dieser Frage hat Eric Elliott einen hervorragenden Beitrag geschrieben, den ich in diesem Abschnitt daher kurz zusammenfassen möchte.

Jeder Unit-Test muss fünf Fragen beantworten

Es gibt eine Unzahl wichtiger Dinge, die man beim Schreiben guter Unit-Tests beachten kann. Das Beantworten der folgenden fünf Fragen ist jedoch bereits ein riesiger Schritt in die richtige Richtung:

  1. Was will ich testen?
  2. Was soll es tun?
  3. Was ist das erwartete Ergebnis (z.B. Ausgabe oder Rückgabewert)?
  4. Was ist das tatsächliche Ergebnis?
  5. Wie kann ich den Test wiederholen?

Die jeweilige Antwort für die ersten vier Fragen finden wir in der Regel in den Bezeichnungen von Variablen, Funktionen, Klassen und Methoden, sowie in den durch Funktionsaufrufe erzeugten Inhalten von Variablen. Die Antwort auf die letzte Frage liefert die Zeile, in der wir das tatsächliche Ergebnis definieren und alles, was dafür benötigt wird.

Unit-Test-Vorlagen

Für ein besseres Verständnis folgen in diesem Abschnitt zwei einfache Unit-Test-Vorlagen: eine für PHP und eine für JavaScript.

Für PHP und die Verwendung von PHPUnit könnte eine solche Vorlage wie folgt aussehen:

class WhatClassTest extends \PHPUnit\Framework\TestCase {

    public function testWhatMethodShouldDoWhat() {

        $expected = 'What is the expected result?';

        $actual = 'What is the actual result?';

        static::assertSame( $expected, $actual, 'What should it do? (optional)' );
    }
}

Und hier eine mögliche JavaScript-Vorlage, zum Beispiel für Jest:

describe( 'What are you testing?', () => {
    test( 'What should it do?', () => {
        const expected = 'What is the expected result?';
        const actual = 'What is the actual result?';

        expect( actual ).toBe( expected );
    } );
} );

Was ist Unit-Testing nicht?

Unit-Testing ist nicht das Allheilmittel! Wie wir im V-Modell gesehen haben, ist Unit-Testing nur eine von mehreren Teststufen. Und alle sind sinnvoll und wichtig.

Es sollte aber auch nicht das Ziel sein, bei jedem Projekt immer und überall 100% Testabdeckung allein durch Unit-Tests zu erzielen. Das ist schlichtweg nicht möglich, zumindest wenn man Unit-Tests schreiben will, die auch tatsächlich Sinn machen.

Wer einmal nach „2 unit tests, 0 integration tests“ sucht, wird schnell über das eine oder andere lustige Video oder Bild stolpern. Unit-Testing ist überaus wichtig, da wir es bei Unit-Tests immer nur mit einer Wahrheit zu tun haben. Mit guten und ausreichenden Unit-Tests können wir daher sagen, dass eine Funktion oder Methode richtig ist, sich also den an sie gestellten Anforderungen entsprechend verhält. Testen wir jedoch nicht auch das Zusammenspiel mehrerer Einheiten, verlassen wir uns auf Wahrheiten in falschen Situationen. Zumindest Integrations- und/oder Abnahmetests sollten wir noch in Betracht ziehen. Oft werden auch Funktionstests (engl. functional test) durchgeführt, was wiederum eine teststufenübergreifende Klassifizierung von Tests ist, bei der einzelne funktionale Anforderungen abgetestet werden. Doch das ist ein Thema für einen anderen Beitrag…

Zusammenfassung

Puh, das war eine ganze Menge. Versuchen wir also, das Wichtigste noch einmal kurz zusammenzufassen.

Unit-Testing…

  • …will Fehler im Code finden.
  • …führt Software tatsächlich aus.
  • …bedeutet, dass einzelne Einheiten in Isolation getestet werden.
  • …erfordert Wissen um Programminterna.
  • …ermittelt, ob Software den Anforderungen entspricht.

Bildnachweis: Pixabay free pictures

Thorsten Frommen

Große Auswahl an günstigen Domain-Endungen – schon ab 0,08 € /Monat
Jetzt Domain-Check starten