Python: Unittest-Tricks

2013-01-31 22:05

Gelegentlich muss man beim Testen in die Trickkiste greifen. Zuerst will ich allen unentschlossenen das mock-Package zur Erstellung von Fakes für Tests und zum sicheren Monkey Patching nahelegen. Ab Python 3.3 ist es sogar builtin - als unittest.mock :)

Module importieren, ohne dass sie existieren

Es gibt Fälle, bei denen im Test Module nicht importiert werden können, weil sie in der isolierten Testumgebung nicht verfügbar sind. Um das zu machen, kann man sys.modules um dieses Modul bereichern.

Im folgenden Beispiel konnte module_to_test nicht importiert werden, weil es missing_module importiert, der Versuch aber mit einem ImportError fehlschlägt. Also wird vor dem Import das Modul durch einen Fake ersetzt:

import mock

import sys



sys.modules['missing_module'] = mock.Mock()



import module_to_test

Funktionen mit mehreren, unterschiedlichen Rückgabewerten

Gelegentlich liefert ein Aufruf innerhalb einer Funktion mehrere Werte zurück. Das gewünschte Verhalten kann man relativ aufwändig per Hand nachbauen, oder aber man nutzt den folgenden Trick, der vom mock-Autor selbst gezeigt wurde.

foo = Mock()

returns = [3, 7]

foo.add.side_effect = lambda *args: returns.pop(0)



perform_action_using_foo()



foo.add.assert_called_with(3, 4)

pop_last_call(foo.add)

foo.add.assert_called_once_with(1, 2)

Und hier noch die Variante für den Fall, dass man weiss, welche Übergabewerte man erwartet (und der bei falschem Übergabewert einen Fehler werfen wird):

foo = Mock()

results = {(1, 2): 3, (3, 4): 7}

foo.add.side_effect = lambda *args: results[args]