IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Couverture de code avec Lazarus


Sujet :

Lazarus Pascal

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2023
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Couverture de code avec Lazarus
    Bonjour à tous,

    Nouveau sur ce forum, je ne sais pas si cette question a déjà été posée

    Je tente d'aider une équipe de développement afin d'améliorer leur qualité logiciel.
    Le but est de leur mettre en place une chaine d'intégration continue pour leur développement Pascal sous Lazarus.

    Pour les tests unitaires, pas de problème, j'utilise les projets de tests intégrés à l'IDE Lazarus.

    Par contre pour la couverture de code associée aux tests, cela se corse !
    J'ai bien trouvé LazCodeCoverageHelper, mais celui-ci semble vraiment trop vieux pour pouvoir s'intégré dans la dernière version 2.2.6 de Lazarus.

    Connaissez-vous d'autres outils qui peuvent répondre au besoin de couverture de code ?

    Merci pour vos retours.

  2. #2
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Salut, avec les unités FPCUnit/FPTest il n'y a pas de code coverage la seule solution c'est LazCodeCoverageHelper, même si il date, il devrait faire le job. Seul hic, y a pas de cli juste la gui.

    Sinon y a un repo pour Delphi https://github.com/MHumm/delphi-code...ge-wizard-plus a voir si c'est possible de le convertir, mais du coup ca fera du boulot en plus.

    Autre solution pour s'assurer de la qualité du code, c'est le TDD qui évitera d'écrire du code inutile. Et au final tu devrais avoir 100% de coverage avec sans soucis.

    Le seul problème est ce que les devs, sont formé dessus ?. Car quand tu commences, c'est pas évident le TDD, y a quelques méthodes a suivre pour se simplifier la vie, comme l'utilisation de SUT/Fixtures, STUB .... Et Faut savoir être pragmatique. Mais si vous faites du clean code/architecture y a pas mieux pour pouvoir faire évoluer l'app sereinement et surtout ne pas passer de longue heure de débogage pour rien.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2023
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci pour ton retour,

    Effectivement, le TDD est une très bonne pratique lorsque le code n'existe pas encore
    Mon problème est de mettre en place les test unitaires et la couverture de code sur une application existante.
    Je suis donc en train de mettre tout ça en place sur un projet existant, sur lequel l'équipe détecte de plus en plus de Bugs après livraison .

    Pour LazCodeCoverageHelper, mon problème est qu'il ne compile plus avec la version 2.2.6 de Lazarus.
    As-tu un moyen de l'intégrer dans l'IDE ?
    Même si il n'existe pas de CLI, je peux essayer de l'intégrer tout de même dans ma chaine !

    Je vais jeter un œil sur l'outil Delphi pour voir si le travail est trop important ou non.

  4. #4
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bonsoir pour LazCodeCoverageHelper, je pense qu'il n'y a pas grand chose à modifier pour le rendre compatible. Je ne code plus avec Lazarus depuis bientôt 3 ans sauf de temps a autre pour le plaisir.
    La semaine prochaine j'aurais un peu de temps libre. Je jetterai un oeil. Par contre ca va être plus compliqué de l'inclure directement dans l'ide.

    Sinon vu que tu dois reprendre du code legacy et y intégrer des tests. Tu pourrais les écrire à la manière TDD avec des SUT/Fixtures surtout si les règles métiers sont déjà établis. Le seul atelier pratique a faire serait celui de l'"example mapping" ce qui permettrait d'écrire et de définir les tests unitaires plus facilement et plus rapidement et surtout couvrir le maximum de cas possible.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2023
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Bonjour, merci pour votre retour.

    En ce qui concerne l'intégration dans l'IDE, ce n'est pas nécessaire, le but étant de mettre en place une chaine d'intégration continue dans Azure DevOps Service, donc si c'est un outil séparé, cela sera plus simple pour l'intégrer dans la chaine.
    J'avoue ne pas bien maitriser l'IDE, et le paquet LazCodeCoverage est initialement designé pour y être intégré.
    Je vais donc aussi regardé comment le compiler sous forme d'application ou autre afin de l'utiliser indépendamment de Lazarus.

    Pour les tests unitaires, je ne vais pas les coder moi-même, je n'ai pas les connaissances suffisantes pour cela, le but est de leur présenter comment les mettre en place et les coder sur des classes "basiques" de listes, fonctions mathématiques ou autres.
    Je code donc quelques tests pour expliquer la manière de tester et de s'assurer que le résultat obtenu est bien celui attendu (assert).

  6. #6
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Kcranf Voir le message
    Bonjour, merci pour votre retour.

    En ce qui concerne l'intégration dans l'IDE, ce n'est pas nécessaire, le but étant de mettre en place une chaine d'intégration continue dans Azure DevOps Service, donc si c'est un outil séparé, cela sera plus simple pour l'intégrer dans la chaine.
    J'avoue ne pas bien maitriser l'IDE, et le paquet LazCodeCoverage est initialement designé pour y être intégré.
    Je vais donc aussi regardé comment le compiler sous forme d'application ou autre afin de l'utiliser indépendamment de Lazarus.
    Je jetterai un oeil dans la semaine prochaine, pour voir si je peux t'aider la-dessus

    Citation Envoyé par Kcranf Voir le message
    Pour les tests unitaires, je ne vais pas les coder moi-même, je n'ai pas les connaissances suffisantes pour cela, le but est de leur présenter comment les mettre en place et les coder sur des classes "basiques" de listes, fonctions mathématiques ou autres.
    Je code donc quelques tests pour expliquer la manière de tester et de s'assurer que le résultat obtenu est bien celui attendu (assert).
    Oui c'est ce que j'avais compris. C'est pour cela que je parlais de l'importance d'avoir un atelier "d'example mapping" (qui fait partie des méthodes en BDD) Idem pour les SUT/Fixtures ce te permet d'écrire des tests conscits et comprhéensible en un clin d'oeil car il n'y a aucun détails d'implémentation. Ca permet de suivre la structure Arrange/Act/Assert (Given/When/Then)


    Exemple vite fait (excuses moi si il y a des erreurs de syntaxe), il faudra bien sur dispatcher en plusieurs fichiers :
    Ce model permet de tester des grosses feature comme de simple méthode comme par exemple une function qui renverrait la différence entre 2 date (eg : "maintenant", "Il y a 15 secondes", "il y 3 minutes" Il y a 1 semaine" etc...) Sont avantage, c'est que les tests sont totalement indépendant de l'implémentation, ce qui fait que même si vous changez de lib externe, réfactorisez, ces tests eux ne bougeront plus.
    De plus ils sont facile à lire. Un dev qui ne connait pas le code va beaucoup plus vite le comprendre car cette structure sert également de documentation.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    //----------------------------------------------------------------------------
    Type
     
      PostMessageCommand = record
        author: string;
        text: string;
      end;
     
      function BuildPostMessageCommand(author, text: string) : PostMessageCommand;
     
    Type
      TMessage = class(TPersistent)
      private
         FID: String;
         FAuthor: String;
         FMessageText : String;
         FPublishedAt: TDateTime;
     
         procedure SetID(id: String);
         procedure SetAuthor(author: String);
         procedure SetMessageText(messgeText: String);
         procedure SetPublishedAt(publishedAt: TDateTime);
     
       protected
       public
          constructor Create(id, messageText, author : String; publishedAt: TDateTime);
     
          property ID: String read FID write SetID;      
          property Author: String read FAuthor write SetAuthor;
          property MessageText: String read FMessageTex write SetMessageText;
          property PublishedAt: TDateTime read FPublishedAt write SetPubliedAt;
      end;
     
     
     
    //----------------------------------------------------------------------------
    Type
       IDateProvider = interface
         function getNow(): DateTime;
      end;
     
      TAbstractDateProvider = Abstract Class(TInterfacedObject, IDateProvider)
      public
           function getNow(): DateTime; abstract;
      end;
     
     
     
    //----------------------------------------------------------------------------
    //----------------------------------------------------------------------------
     
    Type
      TStubDateProvider = class(TAbstractDateProvider)
      private
        FNow: DateTime;   
      public
        constructor Create(now: TDateTime);
     
        function getNow(): DateTime;    
      end;
     
    //----------------------------------------------------------------------------
     
      TMessageBuilder = class
      private
      public
         function WithId(Id: string): TMessageBuilder;
         function AuthoredBy(author: string): TMessageBuilder;
         function WithText(text: string): TMessageBuilder;
         function PublishedAt(publishedAt: TDateTime): TMessageBuilder;
     
         function Build: TMessage;
      end;
     
    //----------------------------------------------------------------------------
     
    Type
      MessagingFixture = class(TObject)
        private
          FDep1 : IDep;
          FDep2 : IDep2;
     
        protected
        public
          constructor (dependance1 : IDep1; dependance2:IDep2, dateProvider: IDateProvider)
     
          procedure givenDateIs(dateStr: string);
          procedure whenUserPostAMessage(message: PostMessageCommand);
          procedure thenMessageShouldBe(expectedMessage : TMessage);
     
      end;
     
    //===============================================
     
     
    uses fpcunit;
     
    interface
     
    type
      TFeatureMessagingBaseTestCase = class(TTestCase)
        protected
          FFixture : TMessagingFixuture;
          procedure Setup; override;
        public
         // ..
      end;
     
    type
      TRule1_TestCase_1 = class(TFeatureMessagingBaseTestCase)
      protected   
        procedure RunTest; override;
      end;
     
    //...
     
    implementation
     
    procedure TRule1_TestCase_1.RunTest;
    var messageBuilder : TMessageBuilder;
    begin
      messageBuilder = TMessageBuilder.create();
      //Arrange (GIVEN)
      FFixture.givenDateIs(StrToDateTime("2023 06 21 22:28"));
     
      // Act (WHEN)
      FFixture.whenUserPostAMessage(BuildPostMessageCommand("Alice", "lorem picsum..."));
     
      // Assert (THEN)
      FFixture.thenMessageShouldBe(messageBuilder
         .WithId("msg-1")
         .AuthoredBy("Alice")
         .WithText("lorem picsum...")
         .PublishedAt(StrToDateTime("2023 06 21 22:28"))
         .Build()
      );
     
    end;
     
    //....
     
    initialization
      const cFeatureTestCase =  "Feature_Messaging.";
     
      const cRule_1 = "RULE_A_message_can_contain_a_maximum_of_280_characters.";
      const cRule_1_Test_1 = "Alice_can_post_a_message_on_her timeline";
      const cRule_1_Test_2 = "Alice_cannot_post_a_message_with_more_than_280_characters";
     
      const cRule_2 = "RULE_A_message_cannot_be_empty.";
      const cRule_2_Test_1 = "Alice_cannot_post_an_empty_message";
      const cRule_2_Test_2 = "Alice_cannot_pos_a_message_with_only whitespaces";
     
      RegisterTest(cFeatureTestCase + cRule_1 , TRule1_TestCase_1.CreateWithName(cRule_1_Test_1);
      RegisterTest(cFeatureTestCase + cRule_1 , TRule1_TestCase_1.CreateWithName(cRule_1_Test_2);
     
      RegisterTest(cFeatureTestCase + cRule_2 , TRule2_TestCase_1.CreateWithName(cRule_2_Test_1);
      RegisterTest(cFeatureTestCase + cRule_2 , TRule2_TestCase_2.CreateWithName(cRule_2_Test_2);
     
    end.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

Discussions similaires

  1. Présentation de la couverture de code en Python avec coverage
    Par deusyss dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 11h16
  2. couverture de code avec test JUnit sur tomcat distant
    Par Hurricae dans le forum Tomcat et TomEE
    Réponses: 1
    Dernier message: 31/08/2010, 23h01
  3. [Tests] La Couverture de code avec Xdebug
    Par bilred dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 24/09/2009, 14h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo