Hallo Sekitaka.
Heute zeige ich Ihnen, wie Sie eine Funktion testen, die "datetime.now ()" verwendet.
Angenommen, Sie möchten eine Funktion erstellen, die am nächsten Tag nach dem Ausführen eines Programms die Zeichenfolge "JJJJMMTT" zurückgibt, und diese Funktion testen.
def get_tomorrow():
now_datetime = datetime.now()
tomorrow_datetime = now_datetime + timedelta(days=+1)
tomorrow = tomorrow_datetime.strftime("%Y%m%d")
return tomorrow
Zuerst habe ich kurz den folgenden Testcode geschrieben. Wie Sie sehen, ist dies jedoch nur erfolgreich, wenn Sie den Test am 22. Juni 2017 ausführen. Dies führt zu einem Fehler beim täglichen Testen mit CI.
class Test(TestCase):
def test_get_tomorrow(self):
self.assertEqual("20170623", get_tomorrow())
Die nächste Idee war, den erwarteten Wert dynamisch zu generieren. Dies besteht den Test immer dann, wenn Sie ihn testen. Tatsächlich habe ich jedoch den gleichen Code wie get_tomorrow geschrieben und ich habe das Gefühl, dass er nicht getestet wurde.
class Test(TestCase):
def test_get_tomorrow(self):
expect_tomorrow = (datetime.now() + timedelta(days=+1)).strftime("%Y%m%d")
self.assertEqual(expect_tomorrow, get_tomorrow())
Daher dachte ich, dass es besser wäre, "datetime.now ()" zu verspotten und "get_tomorrow" in einem Zustand auszuführen, in dem eine beliebige datetime zurückgegeben wird. Und ich habe den folgenden Code geschrieben.
from mock import Mock
class Test(TestCase):
def test_get_tomorrow(self):
datetime.now = Mock(return_value=datetime(year=2017, month=1, day=1))
self.assertEqual("20170102", get_tomorrow())
Wenn ich es mit Erwartung ausgeführt habe, konnte ich es nicht ausführen, da ich das Attribut anscheinend nicht auf die integrierte Datums- / Uhrzeitangabe festlegen konnte.
TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
Als ich in Schwierigkeiten war, fand ich eine Bibliothek namens freezegun, die das datetime-Modul verspottete.
from freezegun import freeze_time
class Test(TestCase):
@freeze_time("2017-01-01")
def test_get_tomorrow_4(self):
self.assertEqual("20170102", get_tomorrow())
Der Strom wird durch die Beschreibung von "@freeze_time (" 2017-01-01 ")" auf 2017/1/1 festgelegt. "Get_tomorrow ()" gibt also immer "20170102" zurück und ist erfolgreich, wenn Sie den Test ausführen. Wenn Sie das Datum freeze_time ändern, ist dies praktisch, da Sie überprüfen können, ob das Programm über die Jahre oder im Quelljahr normal funktioniert.
Was haben Sie gedacht. Ich habe vorgestellt, wie man eine Funktion testet, die von Pythons datetime.now ()
abhängt.
Es ist erforderlich, einen Testfall zu erstellen, damit der Komponententest einmal ausgeführt und nicht abgeschlossen werden kann, aber jederzeit ausgeführt werden kann, wenn das CI gedreht wird.
Ich möchte weiter über Testmethoden lernen.
Recommended Posts