Code-Qualitätssicherung mit PDB und anderen Tools Debugging von Python-Programmen

Von Thomas Joos

Debugging und Qualitätssicherung spielen beim Programmieren eine wichtige Rolle. In Python ist die Fehlersuche mit verschiedenen Modulen und dem PDB-Tool möglich. Wir zeigen diese und weitere Möglichkeiten in diesem Beitrag.

Starten des Debugging-Vorgans in der JetBrains-Entwicklungsumgebung PyCharm.
Starten des Debugging-Vorgans in der JetBrains-Entwicklungsumgebung PyCharm.
(Bild: Joos / JetBrains)

Das Debugging kann in Python auf verschiedenen Wegen durchgeführt werden. Neben Bordmitteln lassen sich auch externe Debugger anbinden. Ebenso ist in der Python IDLE (Integrated Development and Learning Environment) ein Debugger enthalten.

Die Lernumgebung steht auf dem Rechner zur Verfügung, auf dem auch Python installiert wurde, der Debugger lässt sich über den Menüpunkt „Debug“ in der grafischen Oberfläche starten. Natürlich bieten auch IDEs eigene Debugger in Visual Studio 2022 und auch im Editor Visual Studio Code sind Debugger genauso enthalten, wie in PyCharm.

Der interne Python-Debugger PDB

Python bietet einen integrierten Debugger.
Python bietet einen integrierten Debugger.
(Bild: Joos / Python.org)

Eines der bekannteren Tools zum Debugging von Python ist der integrierte Debugger PDB. Allerdings bietet dieser keine gute Übersicht und erfordert auch etwas Einarbeitung. Das Modul des Debuggers lässt sich generell zum Debugging nutzen, ist aber in der Realität zu kompliziert und schlecht zu bedienen. Dafür gehört er zum Lieferumfang von Python.

Mit dem Debugger lassen sich Haltepunkte setzen, so wie bei anderen Debuggern auch. Mit „import pdb“ lässt er sich in das Konsolenfenster integrieren. Der Debugger wird in der Python-Dokumentation umfassend beschrieben. Um das Debugging zu starten, ist zum Beispiel mindestens folgender Code notwendig:

>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')

Es ist auch mit PDB möglich, direkt eine Python-Datei zu debuggen. Der Befehl dazu lautet:

python3 -m pdb myscript.py

Sollen Abbrüche in den Debugger integriert werden, kann mit „pdb.set_trace()“ gearbeitet werden. Im Debugger kann auch direkt mit Python-Code gearbeitet werden. Damit das funktioniert, muss der Code mit „!“ begonnen werden. Der interne Editor bietet alle Funktionen, die auch externe Debugger von externen IDEs zur Verfügung stellen.

Wir zeigen im nächsten Abschnitt verschiedene Befehle, mit denen sich der Debugger recht effektiv nutzen lässt. Arbeiten Entwickler mit einer IDE wie Visual Studio, kommt normalerweise der Editor der IDE zum Einsatz.

So funktioniert der interne Debugger PDB

Nach dem Aufrufen des Debuggers kann mit „help“ eine Hilfe angezeigt werden. Mit „step“ führt der Debugger die nächsten Code-Zeilen aus, bis zum nächsten Haltepunkt, zum Beispiel der nächsten Funktion. Der Befehl „list“ zeigt den Code an, bei dem sich der Debugger aktuell befindet.

Mit „break“ visualisiert der Debugger die aktuellen Haltepunkte und deren Nummer. Mit Eingabe von „break <Nummer>“ lässt sich wiederum ein Haltepunkt an der aktuellen Stelle des Codes setzen; und durch Eingabe von „break <Name der aktuellen Funktion>“ setzt PDB einen Haltepunkt an der Stelle im Code, an dem sich die aktuelle Funktion befindet.

Nach der Eingabe von „continue“ fährt der Debugger bis zum nächsten Haltepunkt fort. Um an den Beginn des Codes zu springen und das Programm von Anfang an nochmal zu starten, kann „run“ verwendet werden.

Externe Debugger nutzen: Visual Studio, Visual Studio Code und PyCharm

Auch in PyCharm ist ein Debugger dabei.
Auch in PyCharm ist ein Debugger dabei.
(Bild: Joos / JetBrains)

Integrierte Entwicklungsumgebungen (IDEs) und Editoren für Python haben ebenfalls Debugger mit an Bord. Beispiele dafür sind Visual Studio oder PyCharm. Auch in den kostenlosen Versionen lässt sich Debugging für Python nutzen, also auch in Visual Studio Code, der PyCharm Community Edition und der Visual Studio 2022 Community Edition.

In Visual Studio und Visual Studio Code lässt sich der Debugger am einfachsten mit der Taste F5 starten. Das Einfügen von Haltepunkten erfolgt in der grafischen Oberfläche über das Kontextmenü an der entsprechenden Stelle im Code. Über „Haltepunkt“ und „Haltepunkt einfügen“ bindet zum Beispiel Visual Studio 2022 einen Haltepunkt ein.

Starten des Debugging-Vorgans in der JetBrains-Entwicklungsumgebung PyCharm.
Starten des Debugging-Vorgans in der JetBrains-Entwicklungsumgebung PyCharm.
(Bild: Joos / JetBrains)

In PyCharm steht für das Debugging ebenfalls ein eigener Menüpunkt zur Verfügung. Ausführlichere Informationen finden sich auf der JetBrains-Webseite „Debugging with PyCharm“ zu finden. Über das kleine, grüne Dreieck in PyCharm kann beim Ausführen eines Python-Programmes auch der Debugger gestartet werden.

Mit Logdateien in Python arbeiten: Modul „logging“ in der Praxis

Beim Debugging und zur Optimierung von Quellcode kann auch das Python-Modul „logging“ zum Einsatz kommen. Informationen zu diesem Modul sind auch in der Online-Hilfe von Python zu finden. Bei der Verwendung lassen sich Anweisungen innerhalb des Programmcodes hinterlegen, die Ausgaben und auch Fehler des Programmes in eine Logdatei schreiben. Damit das funktioniert, gilt es zunächst einmal mit „import logging“ das Modul zu laden.

Jetzt Newsletter abonnieren

Täglich die wichtigsten Infos zu Softwareentwicklung und DevOps

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

Die Aktivierung des Logging kann mit folgenden Anweisungen gestartet werden, auch in einer interaktiven Sitzung der Python-Shell:

logging.basicConfig(level=logging.INFO)

Eine weitere Möglichkeit ist:

logging.basicConfig(level=logging.DEBUG)

Soll die Ausgabe direkt in einer Datei erfolgen, lässt sich diese auch direkt im Programmcode erstellen:

import logging
logging.basicConfig( level=logging.DEBUG, filename='meinlog.log')
Data pretty printer (pprint)

Das Modul „pprint“ bietet sich ebenfalls für das Debuggen an. Grundsätzlich funktioniert das Modul wie „print“, gibt aber zusätzliche Informationen am Zeilenende aus. Diese Informationen unterstützen auch beim Debuggen. Das Laden des entsprechenden Moduls erfolgt mit „import pprint“.

Testen mit doctest

Am Beginn von Funktionsblöcken ist es sinnvoll, eine Beschreibung der Funktion als String zu integrieren, damit der Aufbau der Funktion und das erwartete Ergebnis verständlich beschrieben werden. Solche Strings lassen sich als Docstrings speichern, die spezielle Formatierungsvorgaben einhalten müssen. Ein Docstring beginnt mit drei Anführungszeichen. Hier tragen viele Entwickler auch ein einfaches Codebeispiel ein, das erklärt, wie die Funktion arbeitet und welches Ergebnis erwartet wird.

Mit der Zeichenfolge ">>>" wird verdeutlicht, dass die folgenden Zeilen im Python-Interpreter eingegeben werden. Diese Vorgehensweise macht Programmcode sehr viel leichter nachvollziehbar. Um Doctests zu nutzen, kommt am Anfang des Codes der Befehl „import doctest“ zum Einsatz. Die Online-Dokumentation von Python zeigt neben der grundlegenden Vorgehensweise einige Beispiele.

Automatisiertes Testen mit unittest

Mit dem Paket „unittest“ lassen sich im Rahmen des Debuggens und der Verbesserung der Codequalität auch automatisierte Tests durchführen. Bei einem solchen Unit Test wird für jedes Modul ein Testmodul erstellt. Damit ist es möglich, alle Funktionen des jeweiligen Moduls automatisiert zu testen. Für die Verwendung wird auch hier das Paket zunächst importiert: „import unittest“. Ein Beispiel sieht folgendermaßen aus:

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'])
    # check that s.split fails when the separator is not a string
    with self.assertRaises(TypeError):
      s.split(2)
if __name__ == '__main__':
  unittest.main()

Fazit

Es gibt zahlreiche Möglichkeiten, um den Code in Python zu debuggen oder Tests durchzuführen. Die dazu notwendigen Funktionen sind in den meisten Fällen in Python integriert und auch externe Tools und Editoren bieten solche Funktionen. In IDEs wie PyCharm oder Visual Studio 2022 lassen sich die internen Funktionen zum Debuggen von Python genauso nutzen, wie die eigenen Funktionen der jeweiligen IDE.

(ID:48119780)