5 Python-Programme automatisch testen

5.1 Einführung in das automatische Testen

Automatisiertes Testen ist ein wichtiger Bestandteil der Softwareentwicklung. Es bedeutet, dass Tests automatisch durchgeführt werden, um die Funktionalität der Software zu überprüfen.

Durch automatisierte Tests kann die Qualität der Software sichergestellt werden, indem Fehler frühzeitig erkannt und behoben werden können. Automatisierte Tests können auch Regressionstests durchführen, um sicherzustellen, dass neue Änderungen keine unerwarteten Auswirkungen auf vorhandene Funktionalitäten haben.

Ein weiterer Vorteil von automatisierten Tests besteht darin, dass sie die Arbeit von Refactoring unterstützen. Wenn Code geändert wird, können automatisierte Tests dabei helfen, sicherzustellen, dass die Funktionalität immer noch wie erwartet ausgeführt wird.

Es gibt verschiedene Arten von automatisierten Tests, wie z.B. Unit-Tests, Integrationstests und Akzeptanztests. Unit-Tests überprüfen einzelne Module oder Funktionen der Software, Integrationstests testen die Integration von verschiedenen Komponenten, während Akzeptanztests sicherstellen, dass die Software den Anforderungen der Kunden entspricht.

Automatisiertes Testen ist eine wichtige Praxis für jeden Softwareentwickler, um die Qualität der Software zu verbessern und Fehler frühzeitig zu erkennen und zu beheben.

5.2 Unit-Tests

Unit-Tests sind eine Art von automatisierten Tests, die dazu verwendet werden, einzelne Module oder Funktionen der Software zu überprüfen. Dabei wird jede Funktion oder Methode in der Software getestet, um sicherzustellen, dass sie wie erwartet funktioniert.

Um Unit-Tests durchzuführen, schreibt man normalerweise eine Testklasse mit verschiedenen Testmethoden. Jede Testmethode überprüft eine bestimmte Funktion oder Methode und gibt einen Fehler zurück, wenn die erwarteten Ergebnisse nicht erzielt werden.

Beim Testen von Funktionen und Klassen sollten Rand- und Fehlerfälle berücksichtigt werden. Randfälle sind spezielle Eingaben, die möglicherweise unerwartete Ergebnisse erzeugen können. Fehlerfälle sind Situationen, in denen die Funktion oder Methode fehlschlägt oder eine Ausnahme auslöst.

Durch das Testen von Rand- und Fehlerfällen können Programmierfehler und unerwartete Verhaltensweisen der Software vermieden werden. Dadurch wird sichergestellt, dass die Software korrekt und zuverlässig funktioniert.

Unit-Tests sind ein wichtiger Bestandteil der agilen Softwareentwicklung und können helfen, die Qualität der Software zu verbessern und die Entwicklungszeit zu verkürzen.

5.3 Das unittest-Modul

Unit-Tests sind eine Art von automatisierten Tests, die dazu verwendet werden, einzelne Module oder Funktionen der Software zu überprüfen. Dabei wird jede Funktion oder Methode in der Software getestet, um sicherzustellen, dass sie wie erwartet funktioniert.

Um Unit-Tests durchzuführen, schreibt man normalerweise eine Testklasse mit verschiedenen Testmethoden. Jede Testmethode überprüft eine bestimmte Funktion oder Methode und gibt einen Fehler zurück, wenn die erwarteten Ergebnisse nicht erzielt werden.

Beim Testen von Funktionen und Klassen sollten Rand- und Fehlerfälle berücksichtigt werden. Randfälle sind spezielle Eingaben, die möglicherweise unerwartete Ergebnisse erzeugen können. Fehlerfälle sind Situationen, in denen die Funktion oder Methode fehlschlägt oder eine Ausnahme auslöst.

Durch das Testen von Rand- und Fehlerfällen können Programmierfehler und unerwartete Verhaltensweisen der Software vermieden werden. Dadurch wird sichergestellt, dass die Software korrekt und zuverlässig funktioniert.

Unit-Tests sind ein wichtiger Bestandteil der agilen Softwareentwicklung und können helfen, die Qualität der Software zu verbessern und die Entwicklungszeit zu verkürzen.

import unittest

def add(a, b):
    return a + b

class TestAddFunction(unittest.TestCase):
    def test_add_positive_numbers(self):
        self.assertEqual(add(1, 2), 3)
        self.assertEqual(add(5, 5), 10)
    
    def test_add_negative_numbers(self):
        self.assertEqual(add(-1, -2), -3)
        self.assertEqual(add(-5, -5), -10)
    
    def test_add_zero(self):
        self.assertEqual(add(0, 0), 0)
        self.assertEqual(add(1, -1), 0)

In diesem Beispiel wird die Funktion add getestet, die zwei Zahlen addiert. Eine TestAddFunction-Klasse wird erstellt und drei Testmethoden werden definiert, um verschiedene Eingabefälle zu testen.

Die erste Testmethode testet das Hinzufügen von positiven Zahlen, die zweite Testmethode testet das Hinzufügen von negativen Zahlen und die dritte Testmethode testet das Hinzufügen von Nullen. Für jede Testmethode werden verschiedene Eingabefälle getestet, um sicherzustellen, dass die Funktion korrekt funktioniert.

Das unittest-Modul wird verwendet, um die Tests auszuführen. Wenn alle Tests erfolgreich sind, wird keine Ausgabe erzeugt. Wenn ein Test fehlschlägt, wird eine Fehlermeldung ausgegeben, die den Grund für das Versagen des Tests angibt.

Durch das Schreiben von Unit-Tests können Entwickler sicherstellen, dass ihre Funktionen und Methoden korrekt funktionieren und unerwartete Ergebnisse vermieden werden.

5.4 Test Discovery und Test Runner

In der Softwareentwicklung ist es oft notwendig, eine große Anzahl von Tests auszuführen, um sicherzustellen, dass die Software korrekt funktioniert. Um diesen Prozess zu automatisieren, gibt es in Python Test Discovery und Test Runner.

Test Discovery ist ein Mechanismus, der automatisch Testmodule und Testmethoden in einer Software identifiziert. Dies bedeutet, dass Entwickler keine manuellen Testschritte durchführen müssen, um zu bestimmen, welche Tests durchgeführt werden müssen. Stattdessen erkennt Test Discovery automatisch alle relevanten Tests.

Der Test Runner ist ein Programm, das Tests ausführt und Berichte über die Ergebnisse erstellt. Der Test Runner liest Testmodule ein, ruft Testmethoden auf und gibt Ergebnisse aus. Der Test Runner ist sehr flexibel und kann an die spezifischen Bedürfnisse eines Projekts angepasst werden.

Es gibt mehrere Test Runner für Python, darunter das in Python integrierte unittest-Modul, das pytest-Modul und das nose-Modul. Diese Test Runner sind in der Regel sehr einfach zu verwenden und bieten umfangreiche Anpassungsmöglichkeiten für die Testausführung und Berichterstattung.

Durch die Verwendung von Test Discovery und Test Runner können Entwickler sicherstellen, dass ihre Software korrekt funktioniert und schnell auf Fehler und Probleme reagieren. Außerdem können sie die Effizienz und Genauigkeit des Testprozesses erhöhen und die Entwicklungszeit verkürzen.

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # Überprüfen, dass s.split() den erwarteten Fehler auslöst, wenn das Trennzeichen nicht vorhanden ist
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

In diesem Beispiel haben wir eine Testklasse mit drei Testmethoden definiert, um verschiedene Methoden von Strings zu testen. Wir haben dann unittest.main() verwendet, um den Test Runner auszuführen und die Tests auszuführen.

Wenn die Tests erfolgreich sind, wird die Ausgabe folgendermaßen aussehen:

----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Wenn ein Test fehlschlägt, wird die Ausgabe eine detaillierte Beschreibung des Fehlers und der erwarteten Ergebnisse enthalten.

Durch die Verwendung von Test Discovery und Test Runner können Entwickler eine Vielzahl von Tests automatisch ausführen und sicherstellen, dass ihre Software korrekt funktioniert und zuverlässig ist.

5.5 Testabdeckung und das coverage-Modul

Die Testabdeckung (auch Code Coverage genannt) ist ein Maß für die Menge des Quellcodes, die durch automatisierte Tests abgedeckt wird. Das Ziel der Testabdeckung ist es, sicherzustellen, dass alle Teile des Codes mindestens einmal getestet wurden.

Das coverage-Modul ist ein Python-Modul, das verwendet wird, um Testabdeckungsberichte zu generieren. Es kann mit pip installiert werden:

pip install coverage

Um die Testabdeckung zu generieren, führen Sie Ihre Tests mit dem coverage-Modul aus:

coverage run your_tests.py

Dies wird Ihre Tests ausführen und die Abdeckungsinformationen sammeln. Um einen Testabdeckungsbericht zu generieren, verwenden Sie das coverage report-Kommando:

coverage report -m

Dies wird einen Testabdeckungsbericht im Terminal ausgeben, der anzeigt, welche Teile des Codes durch Tests abgedeckt wurden und welche nicht. Wenn Sie einen detaillierteren Bericht wünschen, können Sie auch das coverage html-Kommando ausführen, um einen interaktiven HTML-Bericht zu generieren:

coverage html

Dies wird einen HTML-Bericht generieren, der die Testabdeckung in verschiedenen Dateien und Modulen anzeigt.

Durch die Verwendung des coverage-Moduls können Entwickler sicherstellen, dass alle Teile ihres Codes mindestens einmal getestet wurden und somit die Qualität und Zuverlässigkeit ihrer Software verbessern.

5.6 Integrationstests und Funktionstests

Integrationstests und Funktionstests sind zwei Arten von automatisierten Tests, die in der Softwareentwicklung verwendet werden, um die Interaktion zwischen verschiedenen Komponenten und Systemen zu testen.

Integrationstests werden durchgeführt, um sicherzustellen, dass verschiedene Komponenten einer Software korrekt zusammenarbeiten. Dabei werden mehrere Komponenten gleichzeitig getestet, um sicherzustellen, dass sie zusammenarbeiten und das gewünschte Verhalten zeigen. Integrationstests werden normalerweise nach der Einzelkomponententests durchgeführt, um sicherzustellen, dass die Integration der Komponenten erfolgreich ist.

Funktionstests werden durchgeführt, um sicherzustellen, dass die Software als Ganzes richtig funktioniert. Dabei wird das Verhalten der Software unter verschiedenen Bedingungen getestet, um sicherzustellen, dass sie die gewünschten Ergebnisse liefert. Funktionstests werden normalerweise am Ende des Entwicklungsprozesses durchgeführt, um sicherzustellen, dass die Software den Anforderungen entspricht.

Um Integrationstests und Funktionstests durchzuführen, müssen Test-Szenarien erstellt werden, die verschiedene Szenarien abdecken, in denen die Software verwendet werden kann. Diese Szenarien können sehr komplex sein und erfordern oft die Verwendung von speziellen Testwerkzeugen und -bibliotheken.

Durch die Durchführung von Integrationstests und Funktionstests können Entwickler sicherstellen, dass ihre Software unter allen Bedingungen korrekt funktioniert und den Anforderungen entspricht. Dies kann dazu beitragen, Fehler und Probleme in der Software zu minimieren und die Qualität und Zuverlässigkeit der Software zu verbessern.

5.6.1 Beispiel Integrationstest

Ein Beispiel für Integrationstests könnte darin bestehen, dass eine E-Commerce-Website getestet wird, indem verschiedene Komponenten wie die Benutzeroberfläche, das Warenkorb-System, das Zahlungs-Gateway und das Bestellverarbeitungssystem gleichzeitig getestet werden. Dabei könnte ein Test-Szenario erstellt werden, bei dem ein Benutzer verschiedene Produkte in den Warenkorb legt, eine Bestellung aufgibt und die Zahlung abschließt. Der Test würde sicherstellen, dass alle Komponenten richtig zusammenarbeiten und die Bestellung korrekt verarbeitet wird.

5.6.2 Beispiel Funktionstests

Ein Beispiel für Funktionstests könnte darin bestehen, dass eine Banking-App getestet wird, indem verschiedene Funktionen wie das Einloggen, Überweisen von Geld, Einrichten von Zahlungsbenachrichtigungen und Abheben von Geld getestet werden. Dabei könnte ein Test-Szenario erstellt werden, bei dem ein Benutzer sich einloggt, Geld auf ein anderes Konto überweist, eine Zahlungsbenachrichtigung einrichtet und dann Geld von einem Geldautomaten abhebt. Der Test würde sicherstellen, dass alle Funktionen der App korrekt funktionieren und die Benutzererfahrung nahtlos ist.