Tests unitaires dans SGBD - comment nous le faisons dans Sportmaster, deuxième partie

La première partie est ici .



Imaginez la situation. Vous êtes confronté à la tâche de développer de nouvelles fonctionnalités. Vous avez des développements de vos prédécesseurs. En supposant que vous n'ayez aucune obligation morale, que feriez-vous?

Le plus souvent, toutes les anciennes réalisations sont oubliées et tout recommence. Personne n'aime fouiller dans le code de quelqu'un d'autre, et si vous avez le temps, pourquoi ne pas commencer à créer votre propre système? Il s'agit d'une approche typique, et elle est largement correcte. Mais dans notre projet, nous nous sommes trompés. Nous avons jeté les bases du futur système de test automatisé basé sur des tests unitaires sur utPLSQL de nos prédécesseurs, puis nous sommes allés travailler dans plusieurs directions parallèles.

  1. Restaurer les anciens tests unitaires. La récupération fait référence à l'adaptation des tests à l'état actuel du système de fidélité et à l'adaptation des tests aux normes utPLSQL.
  2. La solution au problème de la compréhension, et de quoi exactement, quelles méthodes et processus, nous sommes couverts par les autotests. Vous devez garder ces informations à l'esprit ou tirer des conclusions sur la base du code d'autotest lui-même. Nous avons donc décidé de créer un catalogue. Nous avons attribué un code mnémonique unique à chaque autotest, formé une description et fixé les paramètres (par exemple, dans quelles conditions il devrait démarrer, ou ce qui devrait se produire si le test échoue). Essentiellement, nous avons rempli les métadonnées sur les autotests et placé ces métadonnées dans les tables de schéma utPLSQL standard.
  3. Définir une stratégie d'expansion, c'est-à-dire sélection des fonctionnalités à vérifier par les autotests. Nous avons décidé de prêter attention à trois choses: les améliorations du nouveau système, les incidents de production et les processus clés du système. Ainsi, nous développons en parallèle avec la version, en fournissant sa qualité supérieure, en augmentant simultanément le volume de régression et en garantissant la fiabilité du système dans les endroits critiques. Le premier goulot d'étranglement a été le processus de distribution de remises et de bonus sur un chèque.
  4. Naturellement, nous avons commencé à développer de nouveaux autotests. L'une des premières tâches de publication a été d'évaluer les performances d'échantillons prédéfinis du système de fidélité. Dans notre projet, il existe un bloc de requêtes SQL fixes de manière rigide qui sélectionne les clients en fonction des conditions. Par exemple, obtenez une liste de tous les clients dont le dernier achat a été effectué dans une ville particulière ou une liste de clients dont le montant d'achat moyen est supérieur à une certaine valeur. Après avoir écrit des autotests, nous avons vérifié les échantillons prédéfinis, fixé les paramètres de performance de référence et, en plus, nous avons eu des tests de charge.
  5. Le travail avec les autotests devrait être pratique . Le plus souvent, deux actions sont effectuées: exécuter des autotests et créer des données de test. Ainsi, dans notre système, deux modules auxiliaires sont apparus: le module de lancement et le module de génération de données.

    Le lanceur est présenté comme une procédure universelle unique avec un paramètre de texte d'entrée. En tant que paramètre, vous pouvez transmettre le code mnémonique d'autotest, le nom du package, le nom du test, le paramètre d'autotest ou un mot clé réservé. La procédure sélectionne et exécute tous les autotests qui satisfont aux conditions.

    Le module de génération de données se présente sous la forme d'un package dans lequel pour chaque objet du système testé (table dans la base de données), une procédure spéciale est créée qui y insère des données. Dans cette procédure, les valeurs par défaut sont remplies autant que possible, ce qui garantit la création d'objets en un clic de doigt. Et pour la facilité d'utilisation, des modèles pour les données générées ont été créés. Par exemple, créez un client d'un certain âge avec un téléphone test et un achat parfait.
  6. Les autotests doivent s'exécuter et s'exécuter à une heure acceptable pour votre système. Par conséquent, un lancement quotidien a été organisé tous les soirs, dont les résultats génèrent un rapport sur les résultats et l'envoient à toute l'équipe de développement par courrier électronique. Après avoir restauré les anciens autotests et en avoir créé de nouveaux, la durée totale de fonctionnement était de 30 minutes. Une telle performance convenait à tout le monde, puisque le lancement avait lieu après les heures.

    Mais j'ai dû travailler sur l'optimisation de la vitesse de travail. La mise à jour du système de fidélité en production se fait de nuit. Dans le cadre d'une des sorties, j'ai dû faire des changements urgents la nuit. La demi-heure d'attente pour les résultats des autotests à trois heures du matin n'a pas rendu la personne responsable de la libération heureuse (salutations ardentes à Alexei Vasyukov!), Et le lendemain matin, beaucoup de mots aimables ont été prononcés à l'égard de notre système. Mais sur la base des résultats, une norme de travail de 5 minutes a été établie.

    Pour accélérer les performances, nous avons utilisé deux méthodes: les autotests ont commencé à s'exécuter dans trois threads parallèles, ce qui est très pratique en raison de l'architecture de notre système de fidélité. Et nous avons abandonné l'approche lorsque l'autotest ne crée pas de données de test pour lui-même, mais essaie de trouver quelque chose de convenable dans le système. Après avoir effectué les modifications, la durée totale de fonctionnement a été réduite à 3-4 minutes.
  7. Le projet avec auto-tests devrait pouvoir être déployé sur différents stands. Au début du voyage, il y a eu des tentatives d'écriture de vos propres fichiers batch, mais il est devenu clair qu'une installation automatisée auto-écrite était une horreur totale, et nous nous sommes tournés vers des solutions industrielles. Étant donné que le projet a beaucoup de code direct (tout d'abord, nous stockons le code pour les autotests) et très peu de données (les données principales sont des métadonnées sur les autotests), il s'est avéré très simple d'introduire Liquibase dans le projet.

    Il s'agit d'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. Géré via 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 certaine manière, qui consiste en des modifications ou des scripts qui doivent être transférés sur le serveur cible, et des fichiers de contrôle qui déterminent dans quelle séquence et avec quels paramètres ces modifications doivent être installées.

    Au niveau du SGBD, une table spéciale est créée dans laquelle Liquibase stocke le journal d'exécution. Chaque modification a un hachage calculé, qui est comparé à chaque fois entre le projet et l'état dans la base de données. Grâce à Liquibase, nous pouvons facilement appliquer nos modifications de système à n'importe quel circuit. Les autotests s'exécutent désormais sur les boucles de test et de libération, ainsi que sur les conteneurs (boucles personnelles des développeurs).




Parlons donc des résultats de l'application de notre système de tests unitaires.

  1. Bien sûr, tout d'abord, nous sommes convaincus que nous avons commencé à développer de meilleurs logiciels. Les tests automatiques s'exécutent quotidiennement et détectent des dizaines d'erreurs chaque année. De plus, certaines de ces erreurs ne sont qu'indirectement liées aux fonctionnalités que nous voulions vraiment changer. Il y a de grands doutes que ces erreurs ont été trouvées par des tests manuels.
  2. L'équipe a acquis la certitude que la fonctionnalité spécifique fonctionne correctement ... Tout d'abord, elle concerne 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 chèque, malgré les changements dans les versions, bien que dans les périodes précédentes des erreurs se soient produites à certains intervalles
  3. Nous avons pu réduire le nombre d'itérations de test. Étant donné que les autotests sont écrits pour de nouvelles fonctionnalités, les analyses et les testeurs à temps partiel obtiennent un code de meilleure qualité, car Cela a déjà été vérifié.
  4. Une partie des développements des tests automatisés est utilisée par les développeurs. Par exemple, les données de test sur les conteneurs sont créées à l'aide du module de génération d'objets.
  5. Il est important que nous ayons développé «l'adoption» d'un système de tests automatisés par les développeurs. Il est entendu que cela est important et utile. Et d'après ma propre expérience, je peux dire que c'est loin d'être le cas. Les autotests doivent être écrits, ils doivent être maintenus et développés, les résultats analysés, et souvent ces coûts en temps n'en valent tout simplement pas la peine. C’est beaucoup plus facile d’aller en production et de régler les problèmes là-bas. Chez nous, les développeurs font la queue et demandent à couvrir leurs fonctionnalités avec des tests automatiques.


Et ensuite




Parlons des plans de développement du projet de test automatisé.

Bien sûr, alors que le système de fidélité de Sportmaster est toujours en vie et continue de se développer, il est également possible de développer des tests automatiques presque à l'infini. Par conséquent, la principale direction du développement est l'expansion de la zone de couverture.

À mesure que le nombre d'autotests augmente, la durée totale de leur travail augmentera régulièrement et nous devrons à nouveau revenir sur la question de la productivité. Très probablement, la solution sera d'augmenter le nombre de threads parallèles.

Mais ce sont des voies de développement évidentes. Si nous parlons de quelque chose de plus banal, nous mettons en évidence ce qui suit:

  1. Actuellement, les autotests sont gérés au niveau du SGBD, c'est-à-dire vous avez besoin de connaissances PL / SQL pour réussir. Si nécessaire, contrôlez le système (par exemple, lancez ou créez des métadonnées), vous pouvez créer une sorte de panneau d'administration à l'aide de Jenkins ou quelque chose de similaire.
  2. Tout le monde aime les indicateurs quantitatifs et qualitatifs. Pour les tests automatisés, une telle mesure universelle est la couverture de code ou les mesures de couverture de code. En utilisant cet indicateur, nous pouvons déterminer quel pourcentage du code de notre système de test est couvert par les autotests. À partir de la version 12.2, Oracle offre la possibilité de calculer cette métrique et suggère d'utiliser le package standard DBMS_PLSQL_CODE_COVERAGE.

    Notre système d'autotest a un peu plus d'un an et c'est peut-être le moment d'évaluer la couverture. Dans mon projet précédent (un projet qui n'était pas celui de Sportmaster), cela s'est produit. Un an après avoir travaillé sur les autotests, la direction s'est fixé pour objectif d'évaluer le pourcentage du code que nous couvrons. Avec une couverture de plus de 1%, la direction serait ravie. Nous, les développeurs, attendions un résultat d'environ 10%. La couverture du code vissé, mesurée, a reçu 20%. Pour célébrer, nous sommes allés chercher un prix, mais comment nous l'avons fait et où nous sommes allés plus tard est une histoire complètement différente.
  3. Les tests automatiques peuvent vérifier les services Web exposés. Oracle vous permet de le faire et nous ne rencontrerons plus un certain nombre de problèmes.
  4. Et, bien sûr, notre système de test automatisé peut être appliqué à un autre projet. Notre solution est universelle et ne nécessite que l'utilisation d'Oracle. J'ai entendu dire que sur d'autres projets de Sportmaster, il y avait un intérêt pour les tests automatiques et, peut-être, nous irons à eux.

Conclusions


Résumons. Sur le projet, le système de fidélité de Sportmaster, nous avons réussi à mettre en place un système de test automatisé. Sa base est la solution utPLSQL de Stephen Feuerstein. Autour d'utPLSQL se trouve le code d'autotest et les modules auxiliaires auto-écrits: module de lancement, module de génération de données et autres. Les tests automatiques s'exécutent quotidiennement et, surtout, fonctionnent et apportent des avantages. Nous sommes convaincus que nous avons commencé à publier des logiciels de meilleure qualité. Dans le même temps, la solution résultante est universelle et peut être librement appliquée sur tout projet où il est nécessaire d'organiser des tests automatisés sur Oracle DBMS.

PS Cet article n'est pas très précis: il y a beaucoup de texte et presque pas d'exemples techniques. Si le sujet est globalement intéressant, nous sommes prêts à le poursuivre et à revenir avec une suite, où nous vous dirons ce qui a changé au cours des six derniers mois et donnerons des exemples de code.

Écrivez des commentaires s'il y a des points sur lesquels il vaut la peine de se concentrer à l'avenir, ou des questions nécessitant une divulgation.

Source: https://habr.com/ru/post/fr465047/


All Articles