• [^] # Re: Pas de révision d'historique

    Posté par . En réponse au journal Chiselapp ferme ses portes. Évalué à 0.

    je te conseille de regarder ce qu'est le Test Driven Development

    J'ai déjà jeté un oeil (donc, je n'ai pas creusé énormément) du côté du TDD, justement.
    Le principe me semble réellement intéressant, mais la quantité de code de tests à écrire au début de l'application me semble quand même vachement excessive, puisque, selon les documents que j'ai lus à ce sujet il faudrait aller jusqu'a effectuer des tests pour tout, strictement tout…

    Sachant que la moyenne de mes méthodes ne dépasse pas les 15 lignes (mes "algorithmes" se situent en fait plus dans le diagramme de classes, chacun s'occupant uniquement de ses affaires. Ca n'évite pas les bugs, mes le code est plus lisible pour moi, et 20 fois plus simple à réutiliser), j'imagine que tu peux comprendre qu'écrire 4 fois plus de code de test par classe que de code réel me semble trop lourd.

    Alors que par contrat, j'imagine qu'il faut tester que ton résultat contient tous tes éléments de départ, et uniquement ceux-là, et vérifier qu'ils sont correctement ordonnés. Ça me semble plus pénible à écrire.

    En gros, avec la programmation par contrat (de ce que j'en ai lu, je n'ai pas assez d'expérience avec pour me proclamer dev par contrat…) tu indiques au dev ce qu'il doit fournir à ta méthode -préconditions- (les langages à typage fort comme C++ permettent donc une vérification basique des contrats à la compilation, si les prototypes sont bien écrits), les invariants et les post-conditions. Si le contrat n'est pas respecté par l'appelante (mauvaises pré-conditions donc) le comportement est indéfini.

    Du coup, il est simple de produire les tests, et si tu utilises pimpl (si je me lourde pas sur le nom), tu peux instrumenter très simplement le code, par exemple:

    int foo::bar(std::string const& input, double &output)
    {
     #ifndef NDEBUG
     if( false == input.empty() )
     throw std::logic_error(...);
     int ret=fooimpl(input, output);
     if( output < 1.0 )
     throw std::logic_error(...);
     return ret;
     #else
     return fooimpl(input, output);
    }
    
    

    Personnellement, je préfère garder les vérifications de contrat en dehors de la version de débogage: ça consomme peut-être un peu de ressources, mais tu as la possibilité de faire des messages d'erreur clairs, que l'utilisateur peut te copier/coller (voire ton application t'envoie directement le rapport d'erreur par mail ou sur bugtracker, pourquoi pas, il suffirait d'implémenter un gros try{…}catch(std::exception &e){…} dans le main après tout) et qui t'indiquent quel bloc de code pose problème.

    Du coup, pour détecter une merde dans le déploiement c'est assez pratique, je dois l'avouer, alors qu'il ne me semble pas que le TDD permette de vérifier que le problème vienne de l'installation de ton application, puisque les tests ne sont pas inclus dans le binaire (je ne crache pas sur TDD, au contraire, je ne fais que demander ce que tu en penses).
    Ca, ça m'a déjà économisé pas mal de temps (et donc plus ça va, et plus j'utilise cette histoire de contrats) quand je balance mon boulot d'une de mes machines à une autre.

    Et vu que ton contrat est clair, je me dis que si jamais à un moment… bon, ok, quand tu as une merde, il est simple d'ajouter un test de non régression, qui vérifie uniquement cette merde. Du coup, moins de "perte de temps" (note les guillemets) à écrire et maintenir des tests qui ne serviront potentiellement jamais, mais tu conserves la possibilité d'éviter une régression ou le retour d'un bug.

    Je ne sais pas si je suis très clair, mais, je le répète: je ne suis expert ni dans le TDD, ni dans le CDD (en encore moins dans les CDI XD bon ok je sors)