Serveur ESP32 : tests automatisés
(2ème partie)
Ceci est la suite et fin des six articles précédents :
Serveur ESP32 : implémentation
Serveur ESP32 : implémentation (2ème partie)
Serveur ESP32 : implémentation (3eme-partie)
Serveur ESP32 : implémentation (4eme-partie)
Serveur ESP32 : implémentation (5eme-partie)
Serveur ESP32 : tests automatisés
Le but de cette dernière évolution est :
- ajouter la délivrance d'un service aux abonnés
- améliorer le serveur
- tester certains cas nominaux ou non nominaux
- tests particuliers
- tests interactifs
Pour un ESP8266 il faudra forcément utiliser une SD.
1. Evolutions
1.1. Service aux abonnés
- un bouton-poussoir
- une LED (la LED de la carte ESP32)
Si l'abonné n'est pas enregistré la LED clignote 1 fois.
Si l'abonné est désactivé la LED clignote 3 fois.
Si l'abonné a un crédit nul la LED clignote 6 fois.
S'il a du crédit la LED s'allume 10 secondes et son crédit est décompté.
On pourrait imaginer beaucoup de solutions hardware :
- écran LCD alphanumérique
- écran tactile
- gâche électrique
- vanne de distribution de boisson
- distributeur de barres vitaminées
- imprimante de tickets
- etc.
1.2. Historique
L'historique fonctionne maintenant à l'envers. Il est plus pratique d'avoir les dernières opérations affichées en premier.L'affichage de l'historique est maintenant limité à 20 lignes et un lien "More history ..." permet de visualiser le fichier complet.
Une nouvelle ligne a été ajoutée : la date d'enregistrement de l'abonné.
1.3. Les détails
Le changement d'heureComme le changement d'heure est intervenu cette nuit (29 mars), le serveur est en retard d'une heure.
L'heure était configurée comme ceci :
configTime(3600, 0, ntpServer);
Aujourd'hui il faudrait la configurer avec une heure de plus :
configTime(7200, 0, ntpServer);
Mais il y a moyen de faire cela automatiquement, avec une "timezone string" :
configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);
Le changement d'heure sera donc automatique le dernier dimanche de mars et octobre.
Les explications ici : https://www.di-mgt.com.au/wclock/tz.html
Les image et logos
Les deux pages HTML affichent maintenant un petit logo (un cadenas) et l'icône favori (favicon.ico) a également été ajouté :
Ceci pour démontrer qu'il ne suffit pas d'écrire <img src="/lock.jpg"> dans une page pour que l'image s'affiche.
Cela n'est pas forcément une évidence lorsque l'on a l'habitude de travailler sur un serveur Apache, mais avec un ESP32 et la librairie AsyncWebServer, il faut servir cette image.
Mémoire libre
Une URL supplémentaire a été ajoutée afin de pouvoir afficher la mémoire dynamique libre :
/freeram.html
La quantité de mémoire RAM libre est également affichée dans la boîte de dialogue "About ...".
2. Tests
2.1. Cas nominaux et non nominaux
Quelques tests nominaux ont été ajoutés :- recherche par nom
- recherche par UID
Dans tout développement sérieux il ne suffit pas de tester quelques cas nominaux. Il faut aussi tester les cas d'erreurs :
- carte non lue
- abonné inexistant
- abonné désactivé
- crédit nul
Tant que l'on n'a pas testé le plus de cas possible rien ne permet d'affirmer que le logiciel fonctionne correctement.
Ces tests paraissent simples. Vérifier que le serveur affiche bien "Subscriber NOT FOUND !!!" si l'abonné n'existe pas ne devrait poser aucune difficulté.
Pour rappel cette suite de test s'exécute comme ceci :
$ python3 test.py AutomatedTest
2.2. Cas particuliers
Partition pleineUn test en particulier est absolument indispensable : le test de remplissage de la partition FAT.Pour tester ce cas, il va être difficile de créer un abonné ou plusieurs et de réaliser un grand nombre d'actions (ajout de crédit par exemple) jusqu'à remplir la partition de 1.44 méga-octets. Chaque ligne d'historique faisant environ 30 octets. Cela nous obligerait à réaliser 48059 actions.
Faire ce test en automatique sera long également. Même si chaque opération ne dure que 500ms, il nous faudrait tout de même 24000 secondes soit plus de 6 heures !
Une astuce consiste à remplir artificiellement la partition de fichiers de taille assez importante.
La serveur se voit donc ajouter une nouvelle URL /create.html permettant de créer un fichier X de taille donnée. La durée du test sera nettement raccourcie.
Une deuxième URL /freebytes.html est ajoutée afin que le logiciel de test puisse récupérer l'espace disponible.
Le logiciel de test va donc demander au serveur de créer N fichiers de 100Ko jusqu'à ce que l'espace soit presque plein.On ne peut pas simplement diviser l'espace disponible au départ par 100Ko et créer N fichiers. L'allocation des secteurs par le système de fichiers n'est pas prédictible.
La taille restante sera d'environ 4096 octets, la taille d'un secteur de la FLASH.
En dessous de cette valeur la méthode FFat.freeBytes() utilisée pour déterminer l'espace disponible retourne ZÉRO, ce qui ne nous arrange pas car on ne saurait quand s'arrêter.
Il ne nous restera plus qu'à effectuer une centaine d'opérations pour remplir le dernier secteur.
Test intensif
Ce test enchaîne 5000 ajouts de crédit.
Cela m'a permis de m'apercevoir qu'après l'ajout de 5000 lignes dans le fichier historique, lorsque l'on utilise la fonction explorer, la lecture du fichier historique échoue. L'ESP32 n'a plus assez de mémoire.
Donc les fichiers sont affichés par page de 200 lignes avec un lien "More ...".
Les lignes sont maintenant numérotées.
Cette suite de test s'exécute comme ceci :
$ python3 test.py SpecialTest
2.3. Tests interactifs
Deux tests interactifs ont été également ajoutés :- ajout d'un abonné
- débit
Le test de débit nécessite la présentation de la carte et l'appui sur le bouton-poussoir.
Il est à noter que chacun de ces test, s'il est effectué un peu avant le passage à la minute suivante, échouerait, d'où une petite attente, afin de laisser au testeur le temps de réaliser les opérations manuellement :
def wait_minute_00(self) :
dt = datetime.now()
if dt.second < 30:
return
print("wait %s seconds please" % (60 - dt.second))
time.sleep(60 - dt.second)
Cette suite de test interactifs s'exécute comme ceci :
$ python3 test.py InteractiveTest
3. La suite de test
Celle-ci est disponible ici :https://bitbucket.org/henri_bachetti/webserver-form/src/v2.3/esp32-subscriber/test/test.py
On voit donc de nouveaux tests apparaître :
- remise à ZÉRO du crédit
- désactivation de l'abonné
- réactivation de l'abonné
- test de remplissage de la partition
- setUp() et tearDown() : voir article précédent
- nettoyage du serveur
- remplissage de la partition
- récuparation de l'heure
Le PC peut en effet demander au serveur d'effectuer une opération qu'il effectuera à 10:44:59, et il est probable que le logiciel de test récupère ensuite une heure légèrement différente : 10:45:00. La comparaison échouerait.
L'heure du PC et de l'ESP32 ne sont pas parfaitement synchronisées à la seconde près. C'est pour cette raison que l'on évite généralement de contrôler des heures à la seconde près.
Le test de remplissage de la partition est situé dans une classe à part SpecialTest afin de permettre son exécution séparément des autre tests, car son exécution prend pas mal de temps : 2 minutes.
$ python3 test.py SpecialTest
.
----------------------------------------------------------------------
Ran 1 test in 122.269s
OK
L'exécution des tests nominaux est plus courte : 10 secondes.
$ python3 test.py AutomatedTest
......
----------------------------------------------------------------------
Ran 7 tests in 10.686s
OK
4. Téléchargement
Cette version est disponible ici :https://bitbucket.org/henri_bachetti/webserver-form/src/v2.3/esp32-subscriber/
5. Liens utiles
La suite :Serveur ESP32 : implémentation (6eme-partie)
6. Conclusion
Une fois de plus le test automatisé permet de fiabiliser le logiciel. Sans test automatisé il m'aurait été impossible de m'apercevoir de ce que j'ai observé en test intensif (voir 2.2).On voit également que souvent le code à tester évolue au fur et à mesure que les tests sont écrits, ce qui est parfaitement normal dans une démarche de test automatisé.
Il existe même une méthode dite "Test-driven development" (Développement piloté par les tests) qui préconise l'écriture des tests avant l'écriture du code.
Bien entendu la suite de tests n'est pas totalement terminée, mais cela ne justifie pas un article de plus.Les suppléments seront ajoutés dans celui-ci.
Pour conclure, je dirais que le test automatisé nécessite une investissement non négligeable, certes, mais cet investissement est largement compensé par le temps gagné par rapport à des tests effectués manuellement, surtout si on les répète souvent.
En fait on s'aperçoit très vite que l'on a tendance à lancer les tests après chaque journée ou semaine de travail, avant le commit (partage de son travail). Lorsque l'on travaille en équipe cela permet de ne pas perturber le travail des autres membres de l'équipe.
J'ai tellement pris goût à ces méthodes que même quand je travaillais seul, je continuais à faire de même.
J'espère que cette suite d'articles vous aura éclairé quant à la manière de concevoir un serveur ESP32, et surtout de le tester.
Cordialement
Henri
7. Mises à jour
27/03/2020 : ajout de testscorrections
29/03/2020 : 1.3. Les détails / le changement d'heure
Aucun commentaire:
Enregistrer un commentaire