Wenn der Zeittest manuell durchgeführt wird, kann es ärgerlich sein, das "Sysdate" zu ändern, und es ist wahrscheinlich, dass Fehler eingemischt werden. Also habe ich den Test codiert und einfacher ausgeführt, um festzustellen, ob er die Qualität verbessern kann.
Die Ausführungsumgebung ist wie folgt
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88
$ python --version
Python 3.7.4
Versuchen Sie auch, ein Paket mit dem Namen freezegun zu verwenden, um es jederzeit problemlos zu testen. Sie können dieses Paket namens "freezegun" verwenden, um die aktuelle Zeit von "datetime" in der Standardbibliothek von "Python" durch die angegebene zu ersetzen.
Wenn ich die Verarbeitung rund um die Uhr teste, möchte ich natürlich zu verschiedenen Zeiten testen. Es ist jedoch ärgerlich, den Test auszuführen, während die Systemzeit nur dafür geändert wird. Wenn Sie also "freezegun" verwenden, müssen Sie das nicht tun. Installieren Sie das Paket über den Befehl pip.
$ pip install freezegun
In "freezegun" kann "freezegun.freeze_time ()" ersetzt werden, so dass die Funktion des "datetime" -Moduls eine bestimmte Zeit zurückgibt.
Der Beispielcode betrachtet den Inhalt von datetime.now ()
.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
def main():
#Ersetzen und zeigen Sie die aktuelle Uhrzeit mit Freezegun an
freezer = freezegun.freeze_time('2015-10-21')
freezer.start()
try:
print("freezegun:" + str(datetime.now()))
finally:
freezer.stop()
#Aktuelle Uhrzeit anzeigen
print("nowtime:" + str(datetime.now()))
if __name__ == '__main__':
main()
Mach das oben.
$ python app_freezegun.py
freezegun:2015-10-21 00:00:00
nowtime:2019-12-14 10:16:49.847317
Sie können sehen, dass die aktuelle Zeit während der Verwendung der Freezegun ersetzt wurde.
Als nächstes ein Muster, das die API als Dekorateur verwendet. Die Zeit wird nur innerhalb der vom Dekorateur geänderten Funktion ersetzt.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
#Ersetzen und zeigen Sie die aktuelle Uhrzeit mit Freezegun an
@freezegun.freeze_time('2015-10-21')
def main():
print("freezegun:" + str(datetime.now()))
#Aktuelle Uhrzeit anzeigen
def main_2():
print("nowtime:" + str(datetime.now()))
if __name__ == '__main__':
main()
main_2()
Mach das oben.
$ python app_freezegun.py
freezegun:2015-10-21 00:00:00
nowtime:2019-12-14 10:16:49.847317
Sie können sehen, dass die aktuelle Zeit in der vom Dekorateur qualifizierten Funktion ersetzt wurde. Natürlich können Sie auch die Uhrzeit angeben.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
#Ersetzen Sie die aktuelle Zeit mit freezegun
@freezegun.freeze_time('2015-10-21 12:34:56')
def main():
print("freezegun:" + str(datetime.now()))
if __name__ == '__main__':
main()
Das Ergebnis ist wie folgt.
$ python app_freezegun.py
freezegun:2015-10-21 12:34:56
Früher habe ich die Zeit mit einem Dekorateur angegeben. Dieselbe API kann auch als Kontextmanager verwendet werden. Das folgende Muster wird als Kontextmanager verwendet. In diesem Fall wird die Zeit nur innerhalb des Kontextmanagerblocks ersetzt.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
def main():
#Ersetzen und zeigen Sie die aktuelle Uhrzeit mit Freezegun an
with freezegun.freeze_time('2015-10-21'):
print("freezegun:" + str(datetime.now()))
#Aktuelle Uhrzeit anzeigen
print("nowtime:" + str(datetime.now()))
if __name__ == '__main__':
main()
Das Ergebnis ist das gleiche wie [4.], daher wird es weggelassen.
Ich denke, wenn Sie einen Test durchführen, müssen Sie einmal die Standardzeit einstellen und dann die Zeit verschieben, nachdem Sie einen bestimmten Prozess durchgeführt haben. Versuchen Sie es mit freezegun
.
Im folgenden Beispielcode wird "tick ()" verwendet, um die Zeit um das "timedelta" -Objekt zu verschieben, und "move_to ()" wird verwendet, um die Zeit umzuschalten.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
from datetime import timedelta
def main():
with freezegun.freeze_time('2015-10-21 00:00:00') as freeze_datetime:
print(datetime.now())
#Vorlaufzeit um 1 Sekunde
freeze_datetime.tick()
print(datetime.now())
#Stellen Sie die Zeit um 1 Minute vor
freeze_datetime.tick(delta=timedelta(minutes=1))
print(datetime.now())
#Wechseln Sie zu einer bestimmten Zeit
freeze_datetime.move_to('2019-01-01 00:00:00')
print(datetime.now())
if __name__ == '__main__':
main()
Mach das oben.
$ python app_freezegun.py
2015-10-21 00:00:00
2015-10-21 00:00:01
2015-10-21 00:01:01
2019-01-01 00:00:00
Ich habe verschiedene Dinge überprüft, aber hier ist die tatsächliche Produktion. Verwenden Sie "freezegun" mit "unittest". Ich möchte testen, was automatisch mit "datetime" erstellt wird, also verspotten Sie AWS EC2. Bereiten Sie zuerst die App vor. Holen Sie sich das erstellte EC2, holen Sie das ältere, das älter als das Ausführungsdatum und die Ausführungszeit der Anwendung ist, und geben Sie den Instanznamen zurück.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import boto3
from datetime import datetime, timedelta, timezone
def main():
#Holen Sie sich die aktuelle Zeit
now = datetime.now(timezone.utc)
#Initialisieren Sie den Instanznamen mit dem Array
instace_names = []
client = boto3.client('ec2')
#Holen Sie sich alle Instanzinformationen.
instances = client.describe_instances()
#Holen Sie sich Instanzen, die vor dem Ausführungsdatum erstellt wurden.
for instance_list in instances.get('Reservations'):
for instance in instance_list.get('Instances'):
if now > instance.get('LaunchTime'):
#Extrahieren Sie den Instanznamen.
instace_names.append(instance.get('KeyName'))
return instace_names
Als nächstes kommt der Testcode.
Verwenden Sie freezegun
, um 4 EC2s mit unterschiedlichen Erstellungsdaten zu verspotten.
test_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import unittest
import boto3
from moto import mock_ec2
import freezegun
from datetime import datetime, timedelta
from app import app_freezegun as app
class MyTestCase(unittest.TestCase):
@mock_ec2
def test_case_1(self):
with freezegun.freeze_time('2017-01-01 00:00:00') as freeze_datetime:
#Erstellungsdatum 2017-01-Erstellen Sie EC2 mit 01
self.__common('test_ec2_name_1')
freeze_datetime.move_to('2018-01-01 00:00:00')
#Erstellungsdatum 2018-01-Erstellen Sie EC2 mit 01
self.__common('test_ec2_name_2')
freeze_datetime.move_to('2019-01-01 00:00:00')
#Erstellungsdatum 2019-01-Erstellen Sie EC2 mit 01
self.__common('test_ec2_name_3')
freeze_datetime.move_to('2020-01-01 00:00:00')
#Erstellungsdatum 2020-01-Erstellen Sie EC2 mit 01
self.__common('test_ec2_name_4')
#Führen Sie die App aus
instance_names = app.main()
#Überprüfen Sie das Ergebnis
self.assertEqual(instance_names, ['test_ec2_name_1', 'test_ec2_name_2', 'test_ec2_name_3'])
def __common(self, name):
client = boto3.client('ec2')
#Legen Sie die Bedingungen für die Erstellung von EC2 fest
ec2objects = [
{'KeyName': name}
]
#Erstellen Sie EC2
for o in ec2objects:
client.run_instances(
ImageId='ami-03cf127a',
MinCount=1,
MaxCount=1,
KeyName=o.get('KeyName'))
if __name__ == '__main__':
unittest.main()
Versuchen Sie es auszuführen.
$ python -m unittest tests.test_freezegun -v
test_case_1 (tests.test_freezegun.MyTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.387s
OK
Ich hab es gut gemacht.
Recommended Posts