Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

Hé Habr !

Je m'appelle Maxim Ponomarenko et je suis développeur chez Sportmaster. J'ai 10 ans d'expérience dans le domaine informatique. Il a débuté sa carrière dans les tests manuels, puis s'est tourné vers le développement de bases de données. Depuis 4 ans, accumulant les connaissances acquises en tests et développement, j'automatise les tests au niveau du SGBD.

Je fais partie de l'équipe Sportmaster depuis un peu plus d'un an et je développe des tests automatisés sur l'un des projets majeurs. En avril, les gars de Sportmaster Lab et moi avons parlé lors d'une conférence à Krasnodar, mon rapport s'intitulait « Tests unitaires dans un SGBD », et maintenant je veux le partager avec vous. Il y aura beaucoup de texte, j'ai donc décidé de diviser le rapport en deux articles. Dans le premier, nous parlerons des autotests et des tests en général, et dans le second, je m'attarderai plus en détail sur notre système de tests unitaires et les résultats de son application.

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

Tout d’abord, une petite théorie ennuyeuse. Qu’est-ce que les tests automatisés ? Il s'agit de tests effectués à l'aide de logiciels et, dans l'informatique moderne, ils sont de plus en plus utilisés dans le développement de logiciels. Cela est dû au fait que les entreprises se développent, leurs systèmes d'information se développent et, par conséquent, le nombre de fonctionnalités à tester augmente. Réaliser des tests manuels devient de plus en plus coûteux.

J'ai travaillé pour une grande entreprise dont les sorties sortent tous les deux mois. Parallèlement, un mois entier a été consacré à la vérification manuelle des fonctionnalités par une douzaine de testeurs. Grâce à la mise en place de l'automatisation par une petite équipe de développeurs, nous avons pu réduire le temps de test à 2 semaines en un an et demi. Nous avons non seulement augmenté la vitesse des tests, mais également amélioré leur qualité. Des tests automatisés sont lancés régulièrement et effectuent toujours l'ensemble des contrôles qu'ils contiennent, c'est-à-dire que nous excluons le facteur humain.

L'informatique moderne se caractérise par le fait qu'un développeur peut être amené non seulement à écrire du code produit, mais également à écrire des tests unitaires qui vérifient ce code.

Mais que se passe-t-il si votre système repose principalement sur une logique de serveur ? Il n’existe pas de solution universelle ni de bonnes pratiques sur le marché. En règle générale, les entreprises résolvent ce problème en créant leur propre système de tests auto-écrits. Il s'agit de notre propre système de tests automatisés auto-écrit qui a été créé sur notre projet et j'en parlerai dans mon rapport.

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

Tester la fidélité

Parlons d’abord du projet dans lequel nous avons déployé un système de tests automatisés. Notre projet est le système de fidélité Sportmaster (d'ailleurs, nous en avons déjà parlé dans ce post).

Si votre entreprise est suffisamment grande, alors votre système de fidélisation aura trois propriétés standards :

  • Votre système sera très chargé
  • Votre système contiendra des processus informatiques complexes
  • Votre système sera activement amélioré.

Allons-y dans l'ordre... Au total, si l'on considère toutes les marques Sportmaster, nous avons plus de 1000 magasins en Russie, Ukraine, Chine, Kazakhstan et Biélorussie. Environ 300 000 achats sont effectués chaque jour dans ces magasins. Autrement dit, 3 à 4 chèques sur deux entrent dans notre système. Naturellement, notre système de fidélité est très chargé. Et comme il est activement utilisé, nous devons garantir les normes de qualité les plus élevées, car toute erreur dans le logiciel entraîne d'importantes pertes monétaires, de réputation et autres.

Parallèlement, Sportmaster propose plus d'une centaine de promotions différentes. Il existe une variété de promotions : il y a les promotions de produits, il y a celles dédiées au jour de la semaine, il y a celles liées à un magasin spécifique, il y a les promotions pour le montant du ticket de caisse, il y a celles pour le nombre de marchandises. En général, pas mal. Les clients disposent de bonus et de codes promotionnels qui sont utilisés lors de leurs achats. Tout cela conduit au fait que calculer n'importe quelle commande est une tâche très non triviale.

L'algorithme qui implémente le traitement des commandes est vraiment terrible et compliqué. Et toute modification de cet algorithme est assez risquée. Il semblait que les changements les plus insignifiants pouvaient avoir des effets tout à fait imprévisibles. Mais ce sont précisément ces processus informatiques complexes, en particulier ceux qui mettent en œuvre des fonctionnalités critiques, qui sont les meilleurs candidats à l’automatisation. Vérifier manuellement des dizaines de cas similaires prend beaucoup de temps. Et comme le point d'entrée dans le processus reste inchangé, après l'avoir décrit une fois, vous pouvez créer rapidement des tests automatiques et être sûr que la fonctionnalité fonctionnera.

Étant donné que notre système est activement utilisé, l'entreprise voudra quelque chose de nouveau de votre part, vivra avec son temps et sera orientée client. Dans notre système de fidélité, les sorties sortent tous les deux mois. Cela signifie que tous les deux mois, nous devons procéder à une régression complète de l’ensemble du système. Dans le même temps, bien entendu, comme dans toute informatique moderne, le développement ne passe pas immédiatement du développeur à la production. Il naît sur le circuit du développeur, passe successivement par le banc de test, la release, l’acceptation, pour enfin aboutir en production. Au minimum, sur les circuits de test et de release, il faut procéder à une régression complète de l'ensemble du système.

Les propriétés décrites sont standard pour presque tous les systèmes de fidélité. Parlons des caractéristiques de notre projet.

Technologiquement, 90 % de la logique de notre système de fidélité est basée sur serveur et implémentée sur Oracle. Il existe un client exposé dans Delphi, qui remplit la fonction d'administrateur de lieu de travail automatisé. Il existe des services Web exposés pour des applications externes (par exemple un site Web). Il est donc très logique que si nous déployons un système de tests automatisés, nous le ferons sur Oracle.

Le système de fidélité de Sportmaster existe depuis plus de 7 ans et a été créé par des développeurs uniques... Le nombre moyen de développeurs sur notre projet au cours de ces 7 années était de 3 à 4 personnes. Mais au cours de la dernière année, notre équipe s’est considérablement agrandie et nous comptons désormais 10 personnes travaillant sur le projet. Autrement dit, les personnes qui viennent au projet ne sont pas familiarisées avec les tâches, les processus et l'architecture typiques. Et le risque de rater des erreurs est accru.

Le projet se caractérise par l'absence de testeurs dédiés en tant qu'unités de personnel. Il y a bien sûr des tests, mais les tests sont effectués par des analystes, en plus de leurs autres responsabilités principales : communiquer avec les clients professionnels, les utilisateurs, développer les exigences du système, etc. etc... Malgré le fait que les tests soient effectués de très haute qualité (cela est particulièrement approprié de le mentionner, car certains analystes peuvent attirer l'attention de ce rapport), l'efficacité de la spécialisation et de la concentration sur une chose n'a pas été annulée .

Compte tenu de tout ce qui précède, pour améliorer la qualité du produit livré et réduire le temps de développement, l’idée d’automatiser les tests sur un projet semble très logique. Et à différentes étapes de l’existence du système de fidélité, les développeurs individuels se sont efforcés de couvrir leur code avec des tests unitaires. Dans l’ensemble, ce fut un processus assez décousu, chacun utilisant sa propre architecture et ses propres méthodes. Les résultats finaux étaient communs aux tests unitaires : les tests ont été développés, utilisés pendant un certain temps, stockés dans un stockage de fichiers versionnés, mais à un moment donné, ils ont arrêté de fonctionner et ont été oubliés. Tout d'abord, cela était dû au fait que les tests étaient davantage liés à un interprète spécifique qu'au projet.

utPLSQL vient à la rescousse

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

Savez-vous quelque chose sur Stephen Feuerstein ?

C'est un gars intelligent qui a consacré une longue partie de sa carrière à travailler avec Oracle et PL/SQL et a écrit un assez grand nombre d'ouvrages sur ce sujet. L'un de ses livres célèbres s'intitule : « Oracle PL/SQL. Pour les professionnels." C'est Stephen qui a développé la solution utPLSQL ou, comme son nom l'indique, le framework de tests unitaires pour Oracle PL/SQL. La solution utPLSQL a été créée en 2016, mais elle continue de travailler activement et de nouvelles versions sont publiées. Au moment de la rédaction du rapport, la dernière version remonte au 24 mars 2019.
Qu'est-ce que c'est. Il s'agit d'un projet open source distinct. Il pèse quelques mégaoctets, exemples et documentation compris. Physiquement, il s'agit d'un schéma distinct dans la base de données ORACLE avec un ensemble de packages et de tables pour organiser les tests unitaires. L'installation prend quelques secondes. Une caractéristique distinctive d’utPLSQL est sa facilité d’utilisation.
Globalement, utPLSQL est un mécanisme d'exécution de tests unitaires, où un test unitaire s'entend comme des procédures batch Oracle ordinaires, dont l'organisation suit certaines règles. En plus du lancement, utPLSQL stocke un journal de toutes vos exécutions de tests et dispose également d'un système de reporting interne.

Regardons un exemple de ce à quoi ressemble le code de test unitaire, implémenté à l'aide de cette technique.

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

Ainsi, l'écran affiche le code d'une spécification de package typique avec des tests unitaires. Quelles sont les exigences obligatoires ? Le paquet doit être préfixé par "utp_". Toutes les procédures avec tests doivent avoir exactement le même préfixe. Le package doit contenir deux procédures standards : « utp_setup » et « utp_teardown ». La première procédure est appelée en redémarrant chaque test unitaire, la seconde après le lancement.

« utp_setup », en règle générale, prépare notre système à exécuter un test unitaire, par exemple en créant des données de test. "utp_teardown" - au contraire, tout revient aux paramètres d'origine et réinitialise les résultats du lancement.

Voici un exemple du test unitaire le plus simple qui vérifie la normalisation du numéro de téléphone client saisi au formulaire standard de notre système de fidélité. Il n'existe pas de normes obligatoires sur la manière d'écrire des procédures avec des tests unitaires. En règle générale, un appel est effectué à une méthode du système testé et le résultat renvoyé par cette méthode est comparé à celui de référence. Il est important que la comparaison du résultat de référence et de celui obtenu se fasse via les méthodes utPLSQL standard.

Un test unitaire peut comporter n’importe quel nombre de vérifications. Comme le montre l'exemple, nous effectuons quatre appels consécutifs à la méthode testée pour normaliser le numéro de téléphone et évaluer le résultat après chaque appel. Lors du développement d'un test unitaire, vous devez tenir compte du fait qu'il existe des vérifications qui n'affectent en aucune façon le système et qu'après certaines, vous devez revenir à l'état d'origine du système.
Par exemple, dans le test unitaire présenté, nous formatons simplement le numéro de téléphone saisi, ce qui n'affecte en rien le système de fidélité.

Et si nous écrivons des tests unitaires en utilisant la méthode de création d'un nouveau client, alors après chaque test, un nouveau client sera créé dans le système, ce qui peut affecter le lancement ultérieur du test.

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

C'est ainsi que les tests unitaires sont exécutés. Il existe deux options de lancement possibles : exécuter tous les tests unitaires à partir d'un package spécifique ou exécuter un test unitaire spécifique dans un package spécifique.

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

Voici à quoi ressemble un exemple de système de reporting interne. Sur la base des résultats du test unitaire, utPLSQL crée un petit rapport. Nous y voyons le résultat de chaque contrôle spécifique et le résultat global du test unitaire.

6 règles d'autotests

Avant de commencer à créer un nouveau système de tests automatisés du système de fidélité, nous avons déterminé, en collaboration avec la direction, les principes auxquels devraient se conformer nos futurs tests automatisés.

Tests unitaires dans un SGBD - comment nous le faisons dans Sportmaster, première partie

  1. Les autotests doivent être efficaces et utiles. Nous avons des développeurs formidables, qu'il faut absolument mentionner, car certains d'entre eux verront probablement ce rapport et écrivent un code merveilleux. Mais même leur merveilleux code n’est pas parfait et contient, contient et continuera de contenir des erreurs. Des autotests sont nécessaires pour trouver ces erreurs. Si ce n'est pas le cas, soit nous écrivons de mauvais autotests, soit nous sommes arrivés à une zone morte qui, en principe, n'est pas développée. Dans les deux cas, nous faisons quelque chose de mal et notre approche n’a tout simplement pas de sens.
  2. Des autotests doivent être utilisés. Cela n'a aucun sens de consacrer beaucoup de temps et d'efforts à l'écriture d'un produit logiciel, de le placer dans un référentiel et de l'oublier. Les tests doivent être exécutés et exécutés aussi régulièrement que possible.
  3. Les autotests devraient fonctionner de manière stable. Quels que soient l’heure de la journée, le stand de lancement et les autres paramètres du système, les tests devraient conduire au même résultat. En règle générale, cela est assuré par le fait que les autotests fonctionnent avec des données de test spéciales avec des paramètres système fixes.
  4. Les autotests doivent fonctionner à une vitesse acceptable pour votre projet. Ce temps est déterminé individuellement pour chaque système. Certaines personnes peuvent se permettre de travailler toute la journée, tandis que d’autres trouvent essentiel de le faire en quelques secondes. Je vous dirai un peu plus tard quelles normes de vitesse nous avons atteintes dans notre projet.
  5. Le développement des autotests doit être flexible. Il n'est pas conseillé de refuser de tester une fonctionnalité simplement parce que nous ne l'avons pas fait auparavant ou pour une autre raison. utPLSQL n'impose aucune restriction sur le développement et Oracle, en principe, vous permet d'implémenter diverses choses. La plupart des problèmes ont une solution, ce n’est qu’une question de temps et d’efforts.
  6. Déployabilité. Nous disposons de plusieurs stands où nous devons effectuer des tests. Sur chaque stand, un dump de données peut être mis à jour à tout moment. Il est nécessaire de réaliser un projet avec des tests automatiques de manière à pouvoir réaliser sans douleur son installation complète ou partielle.

Et dans le deuxième post, dans quelques jours, je vous dirai ce que nous avons fait et quels résultats nous avons obtenus.

Source: habr.com

Ajouter un commentaire