Unittests für die Kommandozeile

Letzte Änderung am 11. Januar 2020 by Christoph Jüngling

Unsere Kaffeemaschine wird zwangsläufig über die Kommandozeile aufgerufen. Das wäre selbst dann noch der Fall, wenn wir eine graphische Oberfläche hätten und der Benutzer zum Start auf ein Icon doppelt geklickt hätte. Unter der Haube werkelt halt immer noch die gute alte Konsole. Da ist es nur logisch, auch diesen Aufruf einigen Unittests zu unterziehen.

Die Rechtschreibkorrektur schlug als Alternative für das ihr unbekannte “Unittests” übrigens “Unsitte” vor :-) Weit gefehlt! Es wäre eher eine Unsitte, Unittests nicht durchzuführen.

Das Dumme an unserer bisher so eleganten Lösung für die Kommandozeilen-Parameter ist, dass wir so recht gar nicht wissen, wie die Parameter eigentlich in unser Programm gelangen. Da scheint etwas Magie im Hintergrund zu werkeln! Und in der Tat, genau so ist es.

Der “Schuldige” ist unser “ArgumentParser” und darin die hilfreiche Methode “parse_args”. Diese holt sich im Hintergrund die Parameter aus der Liste “argv”, welche über die Bibliothek “sys” zu finden ist. Diese Liste enthält in der Reihenfolge der Eingabe alle Argumente der Kommandozeile, mit der das Programm aufgerufen wurde. Dabei ist das erste Element (mit dem Index 0) der Name des Programms selbst.

Vorbereitungen

Und genau diese Liste können wir, um das erste Element erleichtert, an “parse_args” übergeben. Dazu müssen wir sie allerdings erstmal in unser Programm bekommen. Wie wir seit bf84cb wissen, lautet unser Aufruf im Hauptprogramm (abgesehen von der später erfolgten Umbenennung der Funktion):

def main():
    args = parse_command_line()
    ...

An dieser Stelle holen wir uns einfach vorab schonmal die Argumente aus der oben erwähnten Liste und übergeben sie an unsere Funktion, die sich dann letztlich des ArgumentParsers bedient. Das erste Element wird dabei abgeschnitten. Natürlich muss diese Routine dann diese Argumente übernehmen und an parse_args durchreichen. Alles andere bleibt unverändert.

def main():
    args = parse_command_line(sys.argv[1:])
    ...

def parse_command_line(arguments):
    ...
    args = parser.parse_args(arguments)
    return args

Unittests

Nun sind wir bereit für die Unittests. Wir legen am besten in dem Ordner “tests” ein weiteres Modul an, das ich analog zu dem schon existierenden “TestKaffeemaschine.py” genannt habe. Als Template kommt wieder das für die Unittests zum Einsatz.

import unittest

from kaffeemaschine import parse_command_line


class Test(unittest.TestCase):

    def test_argument_noparam(self):
        '''
        Test default parameter settings
        '''
        parser = parse_command_line([])
        self.assertEqual(parser.menge, 1, 'Menge falsch')
        self.assertEqual(parser.sorte, 'Arabica', 'Sorte falsch')
        self.assertEqual(parser.verbose, 0, 'Verbose-Level falsch')

Die Grundstruktur ist ja bereits bekannt. Zusätzlich holen wir uns per Import in Zeile 3 die Funktion “parse_command_line” aus dem Modul “kaffeemaschine”. Wichtig ist nun, dass wir dieser Funktion jeweils eine Liste mit den zu testenden Kommandozeilenparametern zu übergeben haben (siehe Zeile 12), wobei die einzelnen Elemente dieser Liste Strings zu sein haben. Nun können wir auf die Attribute von “parser” wie gewohnt zugreifen.

Siehe Changeset d78772.

Ähnliche Artikel:

Schreibe einen Kommentar

Deine Email-Adresse wird nicht veröffentlicht.

neunzehn + sechs =