Première partie — .
Imaginez la situation. Vous devez développer une nouvelle fonctionnalité. Vous avez des travaux antérieurs de vos prédécesseurs. Si l'on suppose que vous n'avez aucune obligation morale, que feriez-vous ?
Le plus souvent, tous les anciens travaux tombent dans l'oubli et tout commence à zéro. Personne n'aime fouiller dans le code des autres, et s'il y a du temps, pourquoi ne pas se lancer dans la création de son propre système ? C'est une approche typique, et elle est en grande partie correcte. Mais dans notre projet, nous n'avons pas agi ainsi. Nous avons basé notre futur système de tests automatisés sur les travaux de unit-tests en utPLSQL de nos prédécesseurs, puis nous avons avancé sur plusieurs fronts en parallèle.
- Restauration des anciens unit-tests. Par restauration, nous entendons l'adaptation des tests à l'état actuel du système de fidélité et l'adaptation des tests aux normes utPLSQL.
- Résolution du problème de compréhension de ce qui est couvert par des tests automatisés, c'est-à-dire quels méthodes et processus le sont. Il faut soit garder cette information en tête, soit tirer des conclusions basées sur le code des tests automatisés. C'est pourquoi nous avons décidé de créer un catalogue. À chaque test automatisé, nous avons attribué un mnémotechnique unique, rédigé une description et noté les paramètres (par exemple, dans quelles conditions il doit être exécuté, ou ce qui doit se passer si le test échoue). En gros, nous avons rempli les métadonnées sur les tests automatisés et les avons placées dans les tables standard du schéma utPLSQL.
- Détermination de la stratégie d'expansion, c'est-à-dire le choix des fonctionnalités à vérifier avec des tests automatisés. Nous avons décidé de nous concentrer sur trois choses : les nouvelles améliorations du système, les incidents en production et les processus clés du système. De cette manière, nous nous développons parallèlement aux versions, assurant une qualité supérieure de celles-ci tout en élargissant la portée des tests de régression et en garantissant la fiabilité du système dans des endroits critiques. Le premier point critique fut le processus de distribution des remises et des bonus par facture.
- Naturellement, nous avons commencé à développer de nouveaux tests automatisés. Une des premières tâches de publication a été d'évaluer les performances des échantillons prédéfinis du système de fidélité. Dans notre projet, nous avons un bloc de requêtes SQL rigoureusement définies qui sélectionnent les clients selon des critères. Par exemple, obtenir une liste de tous les clients dont le dernier achat a été effectué dans une ville spécifique, ou une liste de clients dont le montant moyen des achats est supérieur à une certaine valeur. En écrivant des tests automatisés, nous avons vérifié ces échantillons prédéfinis et avons enregistré des paramètres de performance de référence, de plus, nous avons mis en place des tests de charge.
- Le travail avec les tests automatisés doit être pratique.. Deux actions sont effectuées le plus souvent : le lancement des tests automatisés et la création de données de test. Ainsi, deux modules auxiliaires ont été créés dans notre système : un module de lancement et un module de génération de données.
Le module de lancement se présente sous la forme d'une procédure universelle avec un unique paramètre textuel d'entrée. En tant que paramètre, on peut transmettre un code mnémotechnique de test automatisé, le nom d'un paquet, le nom d'un test, la configuration du test automatisé ou un mot-clé réservé. La procédure sélectionne et lance tous les tests automatisés répondant aux conditions.
Le module de génération de données est présenté sous la forme d'un paquet, dans lequel pour chaque objet du système à tester (table dans la BDD), une procédure spéciale a été créée pour y insérer des données. Dans cette procédure, les valeurs par défaut sont maximisées, ce qui permet de créer des objets en un clin d'œil. De plus, des modèles de données créées ont été élaborés pour plus de confort d'utilisation. Par exemple, créer un client d'un certain âge avec un numéro de téléphone de test et un achat effectué.
- Les tests automatisés doivent être lancés et fonctionner dans un délai acceptable pour votre système. C'est pourquoi un lancement quotidien nocturne a été organisé, dont les résultats sont compilés dans un rapport et envoyés à toute l'équipe de développement par e-mail d'entreprise. Après la restauration des anciens tests automatisés et la création de nouveaux, le temps total de fonctionnement était de 30 minutes. Une telle performance a satisfait tout le monde, car le lancement se faisait hors des heures de travail.
Mais nous avons dû travailler sur l'optimisation de la vitesse de fonctionnement. La mise à jour du système de fidélité en production se fait la nuit. Dans le cadre d'une des versions, nous avons dû procéder à des modifications urgentes durant la nuit. Une attente de trente minutes pour les résultats des tests automatisés à trois heures du matin n'a pas rendu heureux la personne responsable de la version (un salut chaleureux à Alexey Vasyukov !), et le lendemain matin, de nombreux éloges ont été adressés à notre système. Toutefois, un objectif de cinq minutes a été fixé pour le temps de traitement.
Pour accélérer les performances, nous avons utilisé deux méthodes : les tests automatisés sont désormais exécutés en trois flux parallèles, ce qui est très pratique grâce à l'architecture de notre système de fidélité. Et nous avons renoncé à l'approche où le test automatisé ne crée pas de données de test, mais essaie de trouver dans le système quelque chose d'adéquat. Après avoir effectué les modifications, le temps total de traitement a été réduit à 3-4 minutes.
- Le projet de tests automatisés doit pouvoir être déployé sur différents environnements. Au début, nous avons essayé d'écrire nos propres scripts batch, mais il est vite devenu évident qu'une installation automatisée maison était un véritable cauchemar, et nous nous sommes tournés vers des solutions industrielles. Étant donné qu'il y a beaucoup de code dans le projet (en priorité, nous stockons le code des tests automatisés) et très peu de données (les données principales étant les métadonnées des tests automatisés), l'intégration de Liquibase dans le projet s'est révélée très simple.
C'est une bibliothèque open source indépendante de la base de données pour le suivi, la gestion et l'application des modifications de schéma de base de données. Elle est pilotée par la ligne de commande ou des frameworks comme Apache Maven. Le principe de fonctionnement de Liquibase est assez simple. Nous avons un projet organisé d'une manière particulière, qui se compose de modifications ou de scripts à appliquer sur le serveur cible, ainsi que de fichiers de contrôle définissant l'ordre et les paramètres selon lesquels ces modifications doivent être installées.
Au niveau de la base de données, une table spéciale est créée où Liquibase stocke le journal des mises à jour. Chaque modification a un hachage calculé qui est comparé à chaque fois entre le projet et l'état dans la base. Grâce à Liquibase, nous pouvons facilement appliquer les modifications de notre système sur n'importe quel environnement. Les autotests sont maintenant exécutés dans les environnements de test et de release, ainsi que sur des conteneurs (environnements personnels des développeurs).

Alors, parlons des résultats de l'application de notre système de tests unitaires.
- Bien sûr, tout d'abord, nous sommes convaincus que nous avons commencé à développer un logiciel de meilleure qualité. Les autotests sont exécutés quotidiennement et lors de chaque release, trouvant des dizaines d'erreurs. De plus, certaines de ces erreurs sont seulement indirectement liées à la fonctionnalité que nous souhaitions réellement modifier. Il y a de grands doutes quant au fait que ces erreurs auraient été détectées par des tests manuels.
- L'équipe a gagné en confiance quant à la fonctionnalité spécifique qui fonctionne correctement… Cela concerne en premier lieu nos processus critiques. Par exemple, au cours des six derniers mois, nous n'avons eu aucun problème avec la distribution des remises et des bonus sur le reçu, malgré les changements fréquents, alors qu'au cours des périodes précédentes, des erreurs survenaient avec une certaine régularité.
- Nous avons réussi à réduire le nombre d'itérations de test. Grâce au fait que des autotests sont écrits pour la nouvelle fonctionnalité, un code de meilleure qualité parvient aux analystes et, en même temps, aux testeurs, car il a déjà été vérifié.
- Une partie des travaux de tests automatisés est utilisée par les développeurs. Par exemple, les données test sur les conteneurs sont créées à l'aide d'un module de génération d'objets.
- Il est également important de noter que nous avons eu une « acceptation » du système de tests automatisés de la part des développeurs. Il y a une compréhension que c'est important et utile. En revanche, d'après mon expérience, ce n'est vraiment pas le cas. Les autotests doivent être écrits, maintenus et développés, et les résultats doivent être analysés, alors que souvent ces investissements de temps ne valent tout simplement pas le coup. Il est beaucoup plus facile d'aller sur la production et de résoudre les problèmes là-bas. Nos développeurs se mettent désormais en file et demandent à ce que leur fonctionnalité soit couverte par des autotests.
Que faire ensuite

Parlons des plans de développement du projet de tests automatisés.
Sans aucun doute, tant que le système de fidélité de Sportmaster est vivant et continue à évoluer, on peut également pratiquement développer indéfiniment les tests automatiques. Par conséquent, la principale direction de développement est l'élargissement de la couverture.
Avec l'augmentation du nombre de tests automatiques, le temps total d'exécution augmentera inévitablement, et nous devrons de nouveau aborder la question des performances. Il est fort probable que la solution consistera à augmenter le nombre de flux parallèles.
Mais ce sont des voies de développement évidentes. Si l'on parle de quelque chose de plus non trivial, soulignons ce qui suit :
- Actuellement, la gestion des tests automatiques s'effectue au niveau de la base de données, c'est-à-dire qu'il faut des connaissances en PL/SQL pour travailler efficacement. Si nécessaire, la gestion du système (par exemple, le lancement de tests ou la création de métadonnées) peut être déléguée à une interface d'administration, en utilisant Jenkins ou quelque chose de similaire.
- Tout le monde aime les indicateurs quantitatifs et qualitatifs. Pour les tests automatisés, un indicateur universel est la couverture de code ou la métrique de couverture du code. Grâce à cet indicateur, nous pouvons déterminer quel pourcentage du code de notre système à tester est couvert par les tests automatiques. Depuis la version 12.2, Oracle offre des possibilités de calcul de cette métrique et propose d'utiliser le package standard DBMS_PLSQL_CODE_COVERAGE.
Notre système de tests automatiques a un peu plus d'un an et peut-être que c'est le moment idéal pour évaluer la couverture. Dans mon précédent projet (pas celui de Sportmaster), cela s'est avéré le cas. Un an après avoir travaillé sur les tests automatiques, la direction a demandé d'évaluer quel pourcentage de code nous couvrons. Avec une couverture de plus de 1%, la direction serait heureuse. Nous, les développeurs, nous attendions un résultat d'environ 10%. Nous avons activé la couverture de code, mesuré, et obtenu 20%. Enjoués, nous sommes partis chercher une prime, mais comment nous y sommes pris et où nous sommes allés après, c'est toute une autre histoire.
- Les tests automatiques peuvent vérifier les services Web exposés. Oracle le permet tout à fait, et nous ne rencontrerons plus un certain nombre de problèmes.
- Et bien sûr, notre système de test automatisé peut être appliqué à un autre projet. La solution que nous avons obtenue est universelle et nécessite simplement l'utilisation d'Oracle. J'ai entendu dire qu'il y a de l'intérêt pour les tests automatisés dans d'autres projets de Sportmaster et il est possible que nous nous rendions chez eux.
Conclusions
Récapitulons. Sur le projet de programme de fidélité chez Sportmaster, nous avons réussi à implémenter un système de test automatisé. La base de celui-ci est la solution utPLSQL de Steven Feuerstein. Autour de utPLSQL se trouvent le code des tests automatisés et des modules auxiliaires écrits à la main : module de lancement, module de génération de données, et d'autres. Les tests automatisés sont lancés quotidiennement et, ce qui est le plus important, ils fonctionnent et apportent des bénéfices. Nous sommes convaincus que nous avons commencé à produire des logiciels de meilleure qualité. Par ailleurs, la solution obtenue est universelle et peut être librement appliquée à tout projet nécessitant d'organiser des tests automatisés sur une base de données Oracle.
P.S. Cet article est plutôt général : il contient beaucoup de texte et quasiment pas d'exemples techniques. Si le sujet vous intéresse globalement, nous sommes prêts à le poursuivre et à revenir avec un complément, où nous expliquerons ce qui a changé au cours des six derniers mois et fournirons des exemples de code.
N'hésitez pas à laisser des commentaires s'il y a des points sur lesquels vous aimeriez que nous nous concentrions à l'avenir, ou des questions nécessitant une clarification.
Seuls les utilisateurs enregistrés peuvent participer au sondage. , s'il vous plaît.
Continuons d'en parler ?
Oui, bien sûr
Non, merci
12 utilisateurs ont voté. 4 utilisateurs se sont abstenu.
Source : habr.com
