Si le test de temps est effectué manuellement, il peut être ennuyeux de changer le sysdate
, et des bogues sont susceptibles d'être mélangés.
J'ai donc codé le test et l'ai exécuté plus facilement pour voir s'il pouvait améliorer la qualité.
L'environnement d'exécution est le suivant
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88
$ python --version
Python 3.7.4
Essayez également d'utiliser un package appelé freezegun pour tester facilement à tout moment.
Vous pouvez utiliser ce paquet appelé freezegun
pour remplacer l'heure actuelle obtenue à partir de datetime
dans la bibliothèque standard de Python
par celle spécifiée.
Lorsque je teste le traitement dans le temps, bien sûr, je veux tester à plusieurs reprises. Cependant, exécuter le test tout en modifiant l'heure du système juste pour cela est ennuyeux.
Donc, si vous utilisez freezegun
, vous n'aurez pas à faire cela.
Installez le package à partir de la commande pip.
$ pip install freezegun
Dans freezegun
,freezegun.freeze_time ()
peut être remplacé pour que la fonction du module datetime
renvoie une heure spécifique.
L'exemple de code examine le contenu de datetime.now ()
.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
def main():
#Remplacez et affichez l'heure actuelle à l'aide du freezegun
freezer = freezegun.freeze_time('2015-10-21')
freezer.start()
try:
print("freezegun:" + str(datetime.now()))
finally:
freezer.stop()
#Afficher l'heure actuelle
print("nowtime:" + str(datetime.now()))
if __name__ == '__main__':
main()
Faites ce qui précède.
$ python app_freezegun.py
freezegun:2015-10-21 00:00:00
nowtime:2019-12-14 10:16:49.847317
Vous pouvez voir que l'heure actuelle a été remplacée lors de l'utilisation du freezegun.
Ensuite, un modèle qui utilise l'API comme décorateur. L'heure n'est remplacée que dans la fonction modifiée par le décorateur.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
#Remplacez et affichez l'heure actuelle à l'aide du freezegun
@freezegun.freeze_time('2015-10-21')
def main():
print("freezegun:" + str(datetime.now()))
#Afficher l'heure actuelle
def main_2():
print("nowtime:" + str(datetime.now()))
if __name__ == '__main__':
main()
main_2()
Faites ce qui précède.
$ python app_freezegun.py
freezegun:2015-10-21 00:00:00
nowtime:2019-12-14 10:16:49.847317
Vous pouvez voir que l'heure actuelle dans la fonction qualifiée de décorateur a été remplacée. Bien sûr, vous pouvez également spécifier l'heure.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
#Remplacer l'heure actuelle à l'aide de Freeze
@freezegun.freeze_time('2015-10-21 12:34:56')
def main():
print("freezegun:" + str(datetime.now()))
if __name__ == '__main__':
main()
Le résultat est le suivant.
$ python app_freezegun.py
freezegun:2015-10-21 12:34:56
Plus tôt, j'ai spécifié l'heure à l'aide d'un décorateur. La même API peut également être utilisée comme gestionnaire de contexte. Voici le modèle utilisé comme gestionnaire de contexte. Dans ce cas, l'heure n'est remplacée que dans le bloc du gestionnaire de contexte.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import freezegun
from datetime import datetime
def main():
#Remplacez et affichez l'heure actuelle à l'aide du freezegun
with freezegun.freeze_time('2015-10-21'):
print("freezegun:" + str(datetime.now()))
#Afficher l'heure actuelle
print("nowtime:" + str(datetime.now()))
if __name__ == '__main__':
main()
Le résultat est le même que [4.], il est donc omis.
Lors d'un test, je pense qu'il est nécessaire de définir une fois l'heure standard, puis de décaler l'heure après avoir effectué un processus spécifique. Essayez d'utiliser freezegun
.
Dans l'exemple de code suivant, tick ()
est utilisé pour décaler l'heure par l'objet timedelta
etmove_to ()
est utilisé pour changer l'heure.
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())
#Avancez le temps de 1 seconde
freeze_datetime.tick()
print(datetime.now())
#Avancez l'heure de 1 minute
freeze_datetime.tick(delta=timedelta(minutes=1))
print(datetime.now())
#Passer à une heure précise
freeze_datetime.move_to('2019-01-01 00:00:00')
print(datetime.now())
if __name__ == '__main__':
main()
Faites ce qui précède.
$ 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
J'ai vérifié diverses choses, mais voici la production réelle.
Utilisez freezegun
dans ʻunit test. Je veux tester ce qui est créé automatiquement à l'aide de
datetime`, alors moquez-vous d'AWS EC2.
Tout d'abord, préparez l'application.
Obtenez l'EC2 créé, récupérez celui qui est plus ancien que la date et l'heure d'exécution de l'application et renvoyez le nom de l'instance.
app_freezegun.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import boto3
from datetime import datetime, timedelta, timezone
def main():
#Obtenez l'heure actuelle
now = datetime.now(timezone.utc)
#Initialiser le nom de l'instance avec le tableau
instace_names = []
client = boto3.client('ec2')
#Obtenez toutes les informations sur l'instance.
instances = client.describe_instances()
#Obtenez les instances créées avant la date d'exécution.
for instance_list in instances.get('Reservations'):
for instance in instance_list.get('Instances'):
if now > instance.get('LaunchTime'):
#Extrayez le nom de l'instance.
instace_names.append(instance.get('KeyName'))
return instace_names
Vient ensuite le code de test.
Utilisez freezegun
pour simuler 4 EC2 avec des dates de création différentes.
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:
#Date de création 2017-01-Créer EC2 avec 01
self.__common('test_ec2_name_1')
freeze_datetime.move_to('2018-01-01 00:00:00')
#Date de création 2018-01-Créer EC2 avec 01
self.__common('test_ec2_name_2')
freeze_datetime.move_to('2019-01-01 00:00:00')
#Date de création 2019-01-Créer EC2 avec 01
self.__common('test_ec2_name_3')
freeze_datetime.move_to('2020-01-01 00:00:00')
#Date de création 2020-01-Créer EC2 avec 01
self.__common('test_ec2_name_4')
#Exécutez l'application
instance_names = app.main()
#Vérifiez le résultat
self.assertEqual(instance_names, ['test_ec2_name_1', 'test_ec2_name_2', 'test_ec2_name_3'])
def __common(self, name):
client = boto3.client('ec2')
#Définir les conditions de création d'EC2
ec2objects = [
{'KeyName': name}
]
#Créer EC2
for o in ec2objects:
client.run_instances(
ImageId='ami-03cf127a',
MinCount=1,
MaxCount=1,
KeyName=o.get('KeyName'))
if __name__ == '__main__':
unittest.main()
Essayez de l'exécuter.
$ python -m unittest tests.test_freezegun -v
test_case_1 (tests.test_freezegun.MyTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.387s
OK
J'ai bien fait.
Recommended Posts