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

C++ Discussion :

C++ et les tests unitaires, d'assemblage/intégration, robot IHM (pour Qt, par exemple), robot web


Sujet :

C++

  1. #1
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut C++ et les tests unitaires, d'assemblage/intégration, robot IHM (pour Qt, par exemple), robot web
    Bonjour,

    Je ne cache pas que j'ouvre ce post sous le coup de la colère contre la communauté C++, dont j'ai fait partie dans les années 90 (jusqu'au C++ 98).
    Depuis quelques mois, le très connu logiciel de gestion de couches géographiques QGis se dégrade à une vitesse hallucinante.

    Dans la liste d'issues ouvertes, j'y ai introduit la mienne : un gel complet de l'application lors de l'authentification à un serveur WMS. En cause : un refactoring échoué dans un code déjà plombé par des mutex.lock() en pagaille, dans toutes les méthodes.
    Pas de commentaires dans les sources, ce qui explique 40% du déclin de l'application, et pas de tests. À ce rythme-là, les derniers sacrements c'est pour bientôt : elle part dans le fossé.

    Alors je me suis posé cette question-là : quelles sont les pratiques de tests en C++ ? J'ai la nette impression que les tests automatisés sont négligés, par rapport aux pratiques que l'on voit en d'autres langages, quand j'observe des projets C++.


    tests unitaires = ceux qui s'exécutent en mémoire, sans ressources physiques (bases de données ou autre) requise, et durent tous 0 secondes au maximum.
    Existe t-il des standardisés, courants, rendus obligatoires dans certains projets ?

    tests d'assemblage / d'intégration = ceux qui engagent des ressources et bases de données ou autres pour prouver la correction d'un code, et peuvent durer le temps qu'ils veulent.

    tests d'automatisation de type robots = pour des IHM comme Qt ou pour des sites web, le cas échéant ?

    Qu'en est-il ?


    Je vous remercie pour vos éclairages.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 29
    Par défaut
    Je ne vois pas le rapport avec le langage.

    Ce projet, si je comprends bien, est juste un bel exemple d'un développement qui a été mené sans tests, sans documentation et avec une dette technique croissante. Ce genre de développement arrive malheureusement trop souvent est indépendant du langage.

    En C++, comme dans tous les autres langages répandus, il existe des frameworks de tests unitaires, de tests d'intégration, d'analyse statique/dynamique de code, d'analyse mémoire, etc... je pense qu'il faut juste se donner les moyens de le faire au début du projet. Le problème c'est qu'au début d'un projet on y voit pas forcément l'intérêt, mais avec le recule on se rend bien compte de l'importance de ces éléments.

    Pour ma part, je conseille fortement la mise en place de tests automatisé avec une vérification de couverture : c'est un minimum.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 634
    Par défaut
    Salut,

    En théorie, la politique de tests est strictement la même que dans n'importe quel langage, et, bien que tu les appelles "tests d'intégration", il se peut parfaitement que certains "tests unitaires" aient besoin de ressources externes.

    Et la théorie, c'est -- bien sur -- que chaque fonction sera testée séparément, et qu'aucune modification ne sera acceptée si les tests correspondants ne se déroulent pas / plus correctement.

    Cependant, quel que soit le langage envisagé, tu sais sans doute aussi bien que moi qu'il y a, parfois, un gouffre entre la théorie et la pratique et que ce n'est généralement pas tant le fait du langage (même si C++ fait clairement partie des langages les plus complexes que l'on puisse trouver), que le fait de l'équipe de développement.

    Par contre, pour ce qui est de l'absence de commentaires, la pratique de plus en plus courante (et que l'on tend à promouvoir de plus en plus, quel que soit le langage envisagé) est de considérer que le meilleur commentaire -- à l'exception d'un éventuel cartouche -- sera le commentaire que l'on n'aura pas écrit: les identifiants (de variable ou de paramètre, de types de données et de fonctions) devant -- a priori -- être suffisamment précis que pour permettre au lecteur du code de déterminer exactement quel est l'objectif visé du fait de l'usage de la fonctionnalité en question.

    Je ne connais absolument pas le projet dont tu parle, et je n'ai donc absolument aucune idée de la manière dont il est géré par l'équipe de dev. Je ne peux donc que comprendre parfaitement ton point de vue et ton ras-le-bol d'après ce que tu en dis.

    Mais, comme d'habitude, ce ne sont a priori les pratiques "générales", telles qu'elles devraient être appliquées qui sont en cause, mais bien la manière dont elles sont appliquées par l'équipe de dev. En dehors d'une oreille compatissante, je crains fort que la communauté de manière générale ne pourra pas faire grand chose si tu ne t'adresse pas directement à l'équipe de dev

    Le plus souvent, les situations que tu décris sont le résultat "d'un éclatement" de l'équipe "d'origine" du projet, et surviennent parce que "quelques développeurs" ont du reprendre "au pied levé" un projet qu'ils ne maîtrisaient pas complètement à la base pour éviter qu'il ne tombe dans l'oubli.

    Généralement, après des "débuts" un peu chaotiques, les choses ont tendance à s'améliorer, et tout ce que l'on peut te conseiller c'est ... d'avoir un peu de patience.

    Maintenant, il se peut aussi que les problèmes actuels n'aient absolument aucun rapport avec un quelconque éclatement de l'équipe d'origine; que la re factorisation ait été absolument nécessaire, mais que l'équipe ait commis la boulette de faire passer en production quelque que chose qui était encore loin d'être au point.

    C'est regrettable, bien sur, et cela nuit grandement à la réputation d'un projet, mais tu sais aussi bien que moi que cela arrive malheureusement très souvent ... Encore une fois, la patience est sans doute la seule possibilité que tu aies à ta portée, à moins que tu ne décide de t'investir dans le projet
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Merci pour vos première réponses.
    Mais pourriez-vous m'éclairer sur les manières de tests unitaires les plus en vigueur aujourd'hui dans le monde C++ ?
    Etant en Java, ces temps-ci, je m'attends à trouver un répertoire de tests avec des fichiers sources basés sur une classe de test de base, venue probablement d'un .lib reconnu.
    Puis celles plus avancées pour les environnements à préconfigurer (de manière automatisée peut-être également) avant ?

    Qu'en est-il au quotidien, qu'utilisez-vous ?

    Pour ce qui est des tests unitaires sans ressources (si possible) et à zéro secondes de durée, c'est que je me suis rendu compte que si les T.U. duraient sur l'ensemble de la compilation projet plus de trente secondes, alors les développeurs progressivement commençaient à compiler en les ignorant, ceci porteur de problèmes à échéance.

    Le problème des commentaires non mis, c'est que si le code est justement pas assez lisible ou les variables mal nommées, le temps de parcours des fichiers et de l'interprétation des lignes de code est très long (il faut que l'on remplace, de tête, le compilateur).
    Et ce n'est pas très commode pour faire venir de nouveaux venus sur un projet opensource (ou non). T'as 300 000 lignes dans le projet, c'est long à appréhender. Si tu as 80 000 commentaires dedans, c'est 5 fois plus rapide.
    Là, on a un sac à bugs, aucun moyen de le tester, et aucun moyen de le comprendre rapidement.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    les développeurs progressivement commençaient à compiler en les ignorant, ceci porteur de problèmes à échéance.
    Ton problème c'est pas le test, c'est la politique de check-in qui est foireuse.
    Si le check-in était interdit sans rouler les tests, si un test échoue, si la compilation échoue, ... alors le logiciel ne partirait pas en sucette.
    Si des petits malins trouvent un moyen de contrer ceci et que personne ne le voit et n'intervient, alors l'organisation de la team est bancale.
    Et ça n'a rien à voir avec le C++, c'est juste le contexte de l'équipe/compagnie qui joue là.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 29
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Mais pourriez-vous m'éclairer sur les manières de tests unitaires les plus en vigueur aujourd'hui dans le monde C++ ?
    Hum, à ma connaissance, ce n'est pas normalisé comme dans le monde Java.

    Citation Envoyé par grunt2000 Voir le message
    Qu'en est-il au quotidien, qu'utilisez-vous ?
    Personnellement, pour un projet donné aujourd'hui, j'utilise:
    • CMake pour générer le projet selon l'IDE préféré du développeur, contient la liste des sources et des tests unitaires à passer
    • Conan pour gérer les dépendances du projet, il fournit la liste des includes et librairies à CMake
    • Catch et HippoMocks pour les tests unitaires
    • C++Tests/Sonar pour l'analyse statique
    • Valgrind pour l'analyse mémoire
    • Ctc/Sonar pour la couverture de code
    • Doxygen pour générer la doc


    D'un point de vue hiérarchie des dossiers ce sera un truc comme ça :
    • docs : contient des .h qui peuvent générer des pages de docs expliquant la conception mise en place par exemple
    • src : contient les sources à compiler
    • include : contient les includes publiques dans le cas d'une librairie qui sera partagée
    • src-test : contient les sources des tests unitaires
    • CMakeLists.txt : fichier projet CMake, en fonction de la taille du projet, il peut être décliné dans des sous-dossiers
    • conanfile.py : fichier projet Conan


    Et pour faire marcher tout ce beau monde, un petit serveur Jenkins avec un pipeline qui s'exécute à chaque remonté de code dans le gestionnaire de versions.

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 634
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Merci pour vos première réponses.
    Mais pourriez-vous m'éclairer sur les manières de tests unitaires les plus en vigueur aujourd'hui dans le monde C++ ?
    Etant en Java, ces temps-ci, je m'attends à trouver un répertoire de tests avec des fichiers sources basés sur une classe de test de base, venue probablement d'un .lib reconnu.
    Puis celles plus avancées pour les environnements à préconfigurer (de manière automatisée peut-être également) avant ?
    Il en va, a priori, exactement de la même manière en C++

    La seule différence, c'est que tu n'as pas forcément (en fonction du framework de tests utilisé) une classe de test "de base" dont dérivent toutes les autres
    Qu'en est-il au quotidien, qu'utilisez-vous ?
    Au quotidien, il y a un tas de frameworks, parmi lesquels on peut citer:
    • QTest, fourni par Qt "him self" (et qui permet même, sauf erreur de ma part, de "scripter" des actions sur l'IHM)
    • boost::unit_test
    • Catch2
    • Gtest (fourni par google)
    • et sans doute bien d'autres encore

    la plupart de ceux dont je viens de parler sont en outre assez simples à intégrer dans un environnement build et de test automatisé, comme jenkins

    Pour ce qui est des tests unitaires sans ressources (si possible) et à zéro secondes de durée, c'est que je me suis rendu compte que si les T.U. duraient sur l'ensemble de la compilation projet plus de trente secondes, alors les développeurs progressivement commençaient à compiler en les ignorant, ceci porteur de problèmes à échéance.
    Je te comprends...

    C'est sans doute pour cela qu'un environnement d'intégration continue disposant d'un "build serveur" configuré de manière à effectuer l'ensemble des tache (compilation complète + ensemble des tests) à chaque commit semble particulièrement utile

    J'ai travaillé sur un projet dont rien que la compilation (complète) prenait minimum une demi heure en mettant à profit la compilation partagée entre sept ordinateurs, et dont l'ensemble des tests nécessitaient une bonne demi heure de plus.

    Par chance, l'ensemble du projet était subdivisé en sept modules différents et chaque module venait avec sa propre batterie de tests, si bien que l'on pouvait "se contenter" de ne faire tourner que les tests unitaires associés au module sur lequel on travaillait, mais qui devaient passer avant même que l'on ne commite les modifications sur le serveur de dev.

    Dans de rares cas, une modification fonctionnait au niveau du module, mais plantait au niveau du programme, mais nous en étions tenus au courant au pire dans les deux heures qui suivaient le commit foireux
    Le problème des commentaires non mis, c'est que si le code est justement pas assez lisible ou les variables mal nommées, le temps de parcours des fichiers et de l'interprétation des lignes de code est très long (il faut que l'on remplace, de tête, le compilateur).
    Je te comprends, et j'aurais du mal à te contredire sur ce coup là...

    Mais le problème des commentaires, c'est qu'ils représentent une source d'information qui n'est absolument pas prise en compte par le compilateur / l'interpréteur, et qui se trouve régulièrement désynchronisée par rapport à ce que fait réellement le code.

    Dans de telles conditions, cela augmente la charge cognitive de celui qui doit lire le code, l'obligeant à parcourir d'avantage de code s'il décide de ne pas tenir compte des commentaires.

    Et, s'il décide d'en tenir compte, le risque est énorme qu'il ne s'intéresse qu'aux commentaires et qu'il laisse le code (celui qui sera manipulé par le compilateur / l'interpréteur) de coté. Avant qu'il ne se rende compte que le code ne fait absolument pas ce que le commentaire prétend, il peut partir sur des hypothèses vachement erronées.

    Mieux vaut encore prendre le risque d'une variable mal nommée sur ce coup. D'autant plus que, dans l'idéal, la revue par les pairs devrait limiter assez facilement le risque de voir "une fonctionnalité quelconque" porter un nom incongru
    Et ce n'est pas très commode pour faire venir de nouveaux venus sur un projet opensource (ou non).
    Ce n'est pas plus mal commode que pour accueillir le petit dernier dans l'équipe de dev non open sources
    T'as 300 000 lignes dans le projet, c'est long à appréhender. Si tu as 80 000 commentaires dedans, c'est 5 fois plus rapide.
    et tu as, surtout, cinq fois plus de chances pour que le "petit dernier" parte sur des hypothèses incorrectes à cause de commentaires dé synchronisés.

    Quand j'ai débarqué sur le projet dont je viens de parler, c'était un projet dont le développement durait déjà depuis plus de cinq ans, composé de plusieurs millions de lignes de code, réparti sur plusieurs milliers de fichiers.

    On m'a donné mes identifiants SVN, et on m'a dit, en gros:
    Récupère le projet, compile le, joue un peu avec le programme, et regarde le code

    Le plus facile est sans doute de partir des tests unitaires pour voir par où ils passent et ce que cela produit
    J'ai fait joujou une petite semaine avant de demander à réellement entrer dans l'équipe

    Et il n'y avait -- au mieux -- que les cartouche pour une partie du projet

    Mais cela ne m'a pas empêcher de rentrer dans le bain
    Là, on a un sac à bugs, aucun moyen de le tester, et aucun moyen de le comprendre rapidement.
    Encore une fois, je comprends ton point de vue...

    Mais le problème est encore une fois du à l'équipe de dev, et non au "règles générales" qu'elle aurait du appliquer (ce qu'elle n'a visiblement pas fait).

    On y trouve -- d'ailleurs -- un dossier tests qui semble contenir plusieurs angles d'attaques et qui devrait -- a priori -- encore tous passer correctement.

    Je n'ai pas essayé de compiler le projet, donc je suis -- bien sur -- limité à des suppositions ici .

    Si ce n'est pas le cas et que ces tests ne passent plus, ou pire, si ces tests là passent encore très bien mais qu'il manque tout un pan à la politique de tests, c'est suite à un problème au niveau de l'équipe de dev. Et ca, malheureusement, on ne peut pas faire grand chose d'autre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 287
    Par défaut
    Il y a plein de possibilités, de frameworks, etc.

    Je rejoins mes petits camarades pour dire que c'est au niveau du process global de maintenance du logiciel qu'il y aura un soucis. Sur d'autres projets libres que je fréquente, nous avons une batterie de VMs de test, et avant qu'une merge request soit validée, il faut passer audit du code, compilation sans warning avec diverses combinaisons (compilos/versions, OS/versions), plus des tests de non régression, d'autres unitaires, et avec/sans sanitizations, etc.
    Bref, le fait que le projet soit en C++ ou non ne change strictement rien.

    PS: mutex.lock() est un terrible code smell. C'est le même qu'en Java quand le unlock() n'est pas dans un finally ou un try-with-ressources. En C++, il n'y a que ténèbres dans un monde sans RAII -- sauf à court termes où il y a plus de maintenance à vendre, mais à long terme cela finit en abandon car trop instable et inmaintenable. C'est typiquement le genre de chose qui ne devrait pas passer une revue de code.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Strategies pour les tests unitaires
    Par xxiemeciel dans le forum Test
    Réponses: 6
    Dernier message: 17/04/2008, 11h59
  2. Les Tests Unitaires en PHP
    Par Ashgenesis dans le forum Langage
    Réponses: 2
    Dernier message: 31/12/2007, 16h15
  3. LookupDispatchAction et les tests unitaires
    Par fk04 dans le forum Struts 1
    Réponses: 3
    Dernier message: 21/10/2007, 14h36
  4. [VS 2005] Les Tests Unitaires
    Par loverdose dans le forum Visual Studio
    Réponses: 3
    Dernier message: 07/05/2007, 19h25

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