CSC4102 : Conception detaill ee et pr eparation des tests unitaires - Denis Conan, avec Chantal Taconet, Christian Bac et Paul Gibson

La page est créée Lucie Nicolas
 
CONTINUER À LIRE
CSC4102 : Conception detaill ee et pr eparation des tests unitaires - Denis Conan, avec Chantal Taconet, Christian Bac et Paul Gibson
CSC4102 : Conception
detaillée et préparation des
tests unitaires
Revision : 4362

Denis Conan, avec Chantal Taconet,
Christian Bac et Paul Gibson
Janvier 2020
CSC4102 : Conception detaill ee et pr eparation des tests unitaires - Denis Conan, avec Chantal Taconet, Christian Bac et Paul Gibson
Sommaire

       1. Objet de la séance
       2. Motivations et objectifs
       3. Conception détaillée
       4. Préparation des tests unitaires
       5. Mise en pratique en TP (2h) + HP (3h)

2/38    01/2020            Denis Conan       CSC4102 : Conception detaillée et préparation des tests unitaires
1 Objet de la séance

        Attributs, opérations (certains algorithmes en pseudo-code)

        Cycle de vie et invariant des objets des classes les plus importantes

        Préparation des tests unitaires des opérations les plus importantes

                       Cahier des charges                                                                                                    Logiciel
                                                                                        Objet de la séance
        S’accorder sur les                                                                                                                          Le système est−il
           fonctionnalités   Expression des besoins                                                                                   Recette       conforme au
              du système                                                                                                                            cahier des
                                                            Préparation...          des tests           ...Exécution                                charges ?

                       Comprendre les                                                                                                           Le système est−il
                     besoins, décrire le    Spécification                                                              Tests de validation      conforme à la
                      QUOI du système                                                                                                           spécification ?

                                                                                                                                       Les différentes parties
              S’accorder sur le COMMENT                                                                      Tests d’intégration       du logiciel
              de construction du système        Conception préliminaire                                                                fonctionnent−elles
                                                                                                                                       correctement ensemble ?

                               Détailler le COMMENT                                                                       Pour un objet, chaque opération
                                  pour un langage de        Conception détaillée                    Tests unitaires
                                                                                                                          fonctionne−t−elle correctement ?
                               programmation donné
                                                                                    Codage
                                                                                 fonctionnalités
                                                                                    et tests

3/38     01/2020                       Denis Conan                        CSC4102 : Conception detaillée et préparation des tests unitaires
2 Motivations et objectifs

       2.1 Pourquoi la conception détaillée avant le codage ?
       2.2 Pourquoi des tests unitaires ?
       2.3 Quels sont les objectifs de la séance ?

4/38    01/2020          Denis Conan       CSC4102 : Conception detaillée et préparation des tests unitaires
2.1 Pourquoi la conception détaillée avant le co-
                   dage ?
        Permettre une « ingénierie vers l’avant »
          (en anglais, forward engineering)
        •    Raffinement, c.-à-d. ajout de contraintes pour simplifier la solution
             • P.ex., telle association ; peut-on « la traverser » dans les deux sens ?
        •    Modèle assez précis pour générer une partie du code
        Prendre les dernières décisions indépendantes du langage de programmation

        • Si c’est une autre équipe qui code
         − Limiter les choix et les interprétations en rassemblant dans une fiche tout ce
                   qui concerne une classe
                    • P.ex., tel attribut dérivé ; est-ce une information redondante ou calculée
                      à la demande ?

        Choisir des canevas logiciels (bibliothèques) techniques1

        1. Ces aspects ne sont pas abordés dans ce module, mais lors des VAP comme ASR,
       DSI ou JIN
5/38     01/2020               Denis Conan         CSC4102 : Conception detaillée et préparation des tests unitaires
2.2 Pourquoi des tests unitaires ?
       Enquête sur le développement logiciel dans les startups            [Giardino et al., 2016]

        The highest priority = a functioning but faulty product to quickly market

        Startups will likely increase their user-base, product size, and number of
          developers.
          This will require [...] to eventually pay the accumulated technical debt.

        Technical debt    [Fowler, 2003, Cunningham, 2009]

        •    Developers accept compromises in a system in one aspect (e.g. modularity) to
             meet an urgent demand in some other aspects (e.g. a deadline) ; such
             compromises incur a “debt” on which “interest” has to be paid
        •    Some of the five dimensions of technical debts : design, testing, code

        Pour évaluer la dette, il faut avoir un jour pratiqué « idéalement », ou proche
          de l’idéal : conception avec assez de détails pour préparer des tests unitaires
          = Rôle de ce module, et plus particulièrement de cette séance

6/38     01/2020            Denis Conan           CSC4102 : Conception detaillée et préparation des tests unitaires
2.3 Quels sont les objectifs de la séance ?
        Conception détaillée
        •    Raffinement (ajout de contraintes) du diagramme de classes pour faciliter la
             programmation
        •    La vie des objets d’une classe dans le système
         −     Modéliser le cycle de vie des objets des classes principales dans des
               diagrammes de machine à états
        •    Le détail des classes dans une fiche par classe
         −         Tous les attributs entièrement définis
         −         Liste de toutes les opérations (trouvées), les + importantes avec l’algorithme
        Préparation des tests unitaires sur les classes principales
        •    Déduire les invariants des classes principales à partir de leur diagramme de
             machine à états et de leur fiche
        •    Construire les tables de décision des opérations principales de ces classes
         −         D’abord, pour les constructeurs
         −         Puis, pour les opérations qui font changer l’état de l’objet

7/38     01/2020               Denis Conan          CSC4102 : Conception detaillée et préparation des tests unitaires
3 Conception détaillée

       3.1 Raffinement du diagramme de classes
       3.2 Diagramme de machine à états
       3.3 Conception d’une fiche par classe

8/38    01/2020          Denis Conan    CSC4102 : Conception detaillée et préparation des tests unitaires
3.1 Raffinement du diagramme de classes

       3.1.1 Rappel, diagramme de classes préliminaire
       3.1.2 Navigabilité
       3.1.3 Composition = agrégation forte

         . Dans cette seconde étude du diagramme de classes, sont laissés pour la
       programmation les éléments de modélisation suivants : interface et classe paramétrée
9/38    01/2020             Denis Conan          CSC4102 : Conception detaillée et préparation des tests unitaires
3.1.1 Rappel, diagramme de classes préliminaire
        Classe, attribut (dérivé), opération, association, multiplicité, agrégation, généralisation
        spécialisation, agrégation, attribut/opération de classe, classe abstraite, classe
        d’association
                                                                                                           Médiathèque
                                                      Localisation                                    nom:string
                                               salle:string
                                               rayon:string                        *

                           *
                                                          est rangé

                              Genre
                     nom:string
                     nbEmprunts:integer=0                                                                            *
                                                                                                                   FicheEmprunt
                                                                                                            dateEmprunt:Date
                                                              *
                                  posséder

                                                                                                            dateLimite:Date
                                                                                                            dateRappel:Date
                                                                      Document
                                                                                                            /dépassé:booléen
                                                                                                                                                                                *
                                                    code:string                                              /tarif:double                                     CategorieClient
                                                    titre:string
                                                    auteur:string                        *                                                               nomCat: string
                                                *   année:string                                                                                         nbEmpruntsMax:integer
                                                    empruntable:booléen=F
                                                    /emprunté:booléen=F                                                                                  cotisation:double
                                                    nbEmprunt:integer=0                  *                                                               coefTarif:double
                                                                                                                                                         coefDurée:double
                                                                                                                                                         codeReductionActif:boolean

                               Audio                                                   Vidéo
                    classification:string

                                                                                                                                                                   appartenir
                                                                                                                                  0..1
                    nbEmpruntsTotal:string=0
                                                                         duréeFilm:integer
                                                                         mentionLégale:string
                                                                                                                                                  *
                    DURÉE:integer=4*7                                                                                                    Client
                                                                         nbEmpruntsTotal:string=0
                    TARIF:double=1.0                                     DURÉE:integer=2*7
                                                                                                                         nom:string
                                                                                                                         prenom:string
                                                                         TARIF:double=1.5                                adresse:string
                                                                                                                         dateInscription:Date             *
                                                         Livre                                                           dateRenouvellement:Date
                                             nombrePage: integer {readOnly}                                              nbEmpruntsEffectues:integer=0
                                             dimension:Dimension                               Dimension                 nbEmpruntsDepasses:integer=0
                                               =Dimension.A5                                                             nbEmpruntsEncours:integer=0
                                                                                             A4
                                             nbEmpruntsTotal:string=0
                                                                                             A5
                                                                                                                         codeRéduction:integer
                                             DURÉE:integer=6*7                               LETTER
                                             TARIF:double=0.5

10/38     01/2020                                    Denis Conan                                           CSC4102 : Conception detaillée et préparation des tests unitaires
3.1.2 Navigabilité

     Par défaut, une association est bidirectionnelle

     Il est possible de la rendre unidirectionnelle

        • Il en résulte une simplification de la solution
         − Pas besoin du maintien de la cohérence des références croisées
                   • « Ajouter un document =⇒ ajouter la connaissance du genre »
                     est plus facile à gérer que
                   • « Ajouter un document =⇒ ajouter la connaissance du genre + ajouter
                     la connaissance du document par le genre »

                                           Genre                                                                  *      Document
                                                                           posséder
        Navigabilité
        Croix optionnelle

                                           Genre                                                                  *      Document
                                                                           posséder

11/38    01/2020             Denis Conan           CSC4102 : Conception detaillée et préparation des tests unitaires
3.1.3 Composition = agrégation forte

     Composition = agrégation forte liant les cycles de vie du composé
        (ensemble) avec les composants (éléments)               [OMG, 2013]

        •   A part object is included in at most one composite object at a time
        •   All of the part instances that are objects are deleted with it
        •   A part object may be removed before the composite object
        •   The order and way in which composed objects are created is intentionally not
            defined
                                         4
              Voiture                           Roue

                                                                                           2..5
                                             Carrosserie                                                  Porte

                                               Moteur                                                  Habitacle

12/38   01/2020            Denis Conan        CSC4102 : Conception detaillée et préparation des tests unitaires
3.2 Diagramme de machine à états

        3.2.1       Pourquoi modéliser les états d’un objet ?
        3.2.2       Types d’états, événement et transition
        3.2.3       Transition : événement, condition, action
        3.2.4       Transition implicite et actions liées à un état

           . Les éléments suivants de la spécification UML ne sont pas étudiées : état composite,
        région, sous-machine, et pseudo-état
13/38     01/2020               Denis Conan         CSC4102 : Conception detaillée et préparation des tests unitaires
3.2.1 Pourquoi modéliser les états d’un objet ?

     Certaines classes sont plus complexes, et surtout,
        influent de manière importante sur le comportement global du système
     Il est important de décrire les événements provoquant les changements
        d’états des objets de ces classes
     Les changements d’états sont décrits dans des machines à états

     Exemples de questions pour lesquelles les diagrammes de machine à états
        sont une aide dans la médiathèque :
        •   Un document est-il empruntable ? est-il emprunté ?
        •   Un emprunt est-il « en retard » ?
        •   Un client peut-il emprunter ?
    =⇒ Diagramme de machine à état pour Document, FicheEmprunt et Client

14/38   01/2020           Denis Conan           CSC4102 : Conception detaillée et préparation des tests unitaires
3.2.2 Types d’états, événement et transition
                                                                                                                                         Document
     Regardez les attributs significatifs, p.ex. les booléens                                                                 code:string
                                                                                                                                titre:string
                                                                                                                                auteur:string
                                                                                                                                année:string
                                                                                                                                empruntable:booléen=F
                                                                                                                                /emprunté:booléen=F
                                                                                                                                nbEmprunts:integer=0

                                                          Événement                                       Action

                                                                                      mise en prêt
                                                                                   /metEmpruntable()
                                  EnCréation               Consultable                                     Empruntable
                             entry:constructeur()
                                                                                 mise en consultation
                                                                                  /metConsultable()                     emprunt
                  État initial                      retrait du rayon                                                    /emprunter()
                                                                                     retrait du rayon
                                      État                                                              restitution
                                                                                                        /restituer()

                     État final                           EnDestruction                                       Emprunté
                                                          entry:destructeur()      Transition

     Nous mettons toujours les états EnConstruction et EnDestruction

     En plus des états initial, final, EnConstruction et EnDestruction, ne
        conservez que les états significatifs, c.-à-d. dans lesquels l’objet reste
        pendant un certain temps et qui influent sur le comportement du système

15/38   01/2020                     Denis Conan                    CSC4102 : Conception detaillée et préparation des tests unitaires
3.2.3 Transition : événement, condition, action

     Syntaxe complète d’une transition : événement[condition]/action

        • La transition est déclenchée par un événement
        • La transition est effectivement franchie si la condition est valide
         − Condition (uniquement) sur l’état de l’objet
        • Le franchissement déclenche l’exécution de l’action de la transition
         − L’exécution de l’action est considérée comme atomique2
     P.ex. « résiliation du client [pas d’emprunt] / résilier() »

     Si plusieurs transitions sont franchissables, alors la transition effectivement
          franchie est choisie aléatoirement

         2. Qui s’exécute comme un tout, sans pouvoir être interrompue ; on modélise l’état du
        système avant ou après l’action, pas au milieu.
16/38     01/2020            Denis Conan         CSC4102 : Conception detaillée et préparation des tests unitaires
3.2.4 Transition implicite et actions liées à un état

     Transition implicite =6 ∃ événement ∧ 6 ∃ condition
        Donc, le franchissement est possible
     Actions exécutées à l’entrée et à la sortie d’un état (entry et exit)

     Action exécutée pendant toute la durée de présence dans l’état (do)

     Action interne déclenchée par un événement (p.ex. événement1)

                              événement[condition]/action

           Transition                                               État n                                            Transition
           réflexive :                                                                                                implicite
           do interrompu,                            entry: action en entrée de l’état
           puis exit,action,entry,do                 do: activité pendant l’état
                                                     événement1[condition1]: action1              action
                                                     événement2[condition2]: action2
                                                     ...
                                                     exit: action en sortie d’état

17/38   01/2020                        Denis Conan                CSC4102 : Conception detaillée et préparation des tests unitaires
3.3 Conception d’une fiche par classe

        3.3.1      Une fiche par classe
        3.3.2      Traduction des associations en attributs
        3.3.3      Traduction des agrégations/compositions
        3.3.4      Encapsulation et visibilité
        3.3.5      Exemple des opérations protégées redéfinies
        3.3.6      Traduction des attributs dérivés
        3.3.7      Rappels : « Façade » et classe d’association
        3.3.8      Traduction des diagrammes de séquence en algorithmes
        3.3.9      Traduction des diagrammes de machine à états

18/38    01/2020             Denis Conan      CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.1 Une fiche par classe

                                        Collecte et définition des attributs
                                        Collecte et définition des opérations
                                        Décisions de conception
                Modèle structurel            − traduction des associations en attributs
                                             − visibilité des attributs
             Diagrammes de classes           − traduction des attributs dérivés

                                                                                                       1 fiche par classe

              Modèle dynamique
        Diagrammes de machine à états
        Diagrammes de communications
           Diagrammes de séquence

19/38   01/2020           Denis Conan     CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.2 Traduction des associations en attributs
     Référence = À partir d’un Document, « aller vers » un objet Genre

                                                              Localisation
                   Genre                               salle:string                                      Médiathèque
                                                       rayon:string
                                                                                                 nom:string
                                                                                                                                               FicheEmprunt
        nom:string
        nbEmprunts:integer=0                est rangé                                                                                  dateEmprunt:Date
                                                                                                                                       dateLimite:Date
                                                                      Document                                                         dateRappel:Date
                                                         *   code:string
                                                                                                                                       /dépassé:booléen
                                                                                                                                       /tarif:double
                               posséder
                                                         *   titre:string

               Nouveaux attributs
                                                             auteur:string
                                                             année:string                  *                                                  0..1
                                                             empruntable:booléen=F                            concerner
                   genre: Genre                              /emprunté:booléen=F
                   localisation: Localisation                nbEmprunts:integer=0

     Association unidirectionnelle = pas d’attribut du « côté de la flèche »

     Association binaire = 1 attribut ; association n-aire = n − 1 attributs

     Nom de l’attribut = nom du rôle ou forme nominale du nom de l’association

     Multiplicité « 1 » traduit par « Classe »

     Multiplicités « 0..N » et « ∗ » traduit par « Collection Classe »3
        3. Choix du type de collection par le programmeur (liste [ordonnée] ou dictionnaire)
20/38    01/2020                         Denis Conan                    CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.3 Traduction des agrégations/compositions
     Agrégation = association, avec les mêmes règles de traduction en attributs
                                                               4
                                Voiture                                   Roue

                                                                                                        2..5
                                                                       Carrosserie                               Porte

                                                                         Moteur                                 Habitacle

                     attributs ajoutés :                                          attributs ajoutés :
                         roues : Tableau[4] de @Roue                                  portes : Collection de @Porte
                         carosserie : @Carosserie                                     habitacle : @Habitacle
                         moteur : @ Moteur                                            voiture : @Voiture

     Composition = ajouter le contrôle du cycle de vie des composants par le
        composé
                                                                   4
                                  Voiture                                  Roue

                                                                                                         2..5
                                                                        Carrosserie                               Porte

                                                                          Moteur                                 Habitacle
                    constructeur() {         // possiblement
                     création objets Roue
                     création objet Carroserie                                     constructeur() {          // possiblement
                     création objet Moteur}                                         création objets Porte
                    destructeur() {       // obligatoirement                        création objet Habitacle}
                     destruction objets Roue                                       destructeur() {        // obligatoirement
                     destruction objet Carosserie                                   destruction objets Porte
                     destruction objet Moteur}                                      destruction objet Habitacle}

21/38   01/2020                 Denis Conan                        CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.4 Encapsulation et visibilité
     Doit-on voir / accéder à tous les attributs et à toutes les opérations d’un
           objet ? Non, c’est le principe de l’encapsulation
     Visibilité privé, notation UML « − » : uniquement l’intérieur de la classe
     Visibilité protégé, notation UML « # » : privé + les classes enfants
     Visibilité public, notation UML « + » : toutes les classes

                    Document                                  Visibilité « privé »                                    Document
        code: String                                          pour les attributs                           − code: String
        titre: String                                         par défaut                                   − titre: String
        auteur: String                                                                                     − auteur: String
        année: String                                                                                      − année: String
        empruntable: Booléen = F                                                                           − empruntable: Booléen = F
        /emprunté: Booléen = F                                                                             − /emprunté: Booléen = F
        nbEmprunts: Integer = 0                               Classe abstraite =>                          − nbEmprunts: Integer = 0
        genre: Genre                                          constructeur uniquement                      − genre: Genre
        localisation: Localisation                            pour les classes enfants                     − localisation: Localisation
        constructeur(String code...)                                                                       # constructeur(String code...)
        getCode(): String                                                                                  + getCode(): String
        getTitre(): String                                    Attributs privés =>                          + getTitre(): String
        getAuteur(): String                                   si besoin, ajoutez                           + getAuteur(): String
        metEmpruntable()                                      des opérations get et/ou set                 + metEmpruntable()
        metConsultable()                                                                                   + metConsultable()
        estEmpruntable() : Booléen                                                                         + estEmpruntable() : Booléen
        estEmprunté() : Booléen                                                                            + estEmprunté() : Booléen
        emprunter() : Booléen                                 Visibilité « public »                        + emprunter() : Booléen
        restituer()                                           pour les opérations                          + restituer()
        afficherStastitique()                                 la plupart du temps                          + afficherStastitique()

22/38     01/2020                      Denis Conan   CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.5 Exemple des opérations protégées redéfinies

                                                 Document
                                   − code: String
                                   − titre: String                                              protected constructeur(String code...) {
                                   − auteur: String                                               this.code = code;
                                                                                                  this.titre = titre;
                                   # constructeur(String code...)                                 this.auteur = auteur;
                                                                                                  ...
                                                                                                }

                     Audio                                            Vidéo
        − classification: String                      − duréeFilm: Integer
        + constructeur(String code...)                + constructeur(String code...)

                                                                                           public constructeur(String code...) {
                                            Livre                                            // appel au constructeur de Document
                              − nombrePage: Integer                                          super(code...);
                                                                                             this.nombrePage = nombrePage;
                              + constructeur(String code...)                               }

23/38    01/2020                   Denis Conan                 CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.6 Traduction des attributs dérivés

     Opération ou attribut selon qu’il est ou non recalculé à chaque fois que sa
           valeur est lue (p.ex. dans un accesseur)

                    Document                                                                                                                    Document
        − code: String                                                                                                               − code: String
        − titre: String                                                                                                              − titre: String
        − auteur: String                                                                                                             − auteur: String
        − année: String                      Solution avec attribut                               Solution sans attribut             − année: String
        − empruntable: Booléen = F           estEmprunté et mise à                                mais référence vers                − empruntable: Booléen = F
        − emprunté: Booléen = F              jour dans emprunter()                                une fiche d’emprunt                − nbEmprunts: Integer = 0
        − nbEmprunts: Integer = 0                                                                                                    − ficheEmprunt: FicheEmprunt
        − genre: Genre                                                                                                               − genre: Genre
        − localisation: Localisation                                                                                                 − localisation: Localisation
        # constructeur(String code...)                                                                                               # constructeur(String code...)
        + getCode(): String                                                                                                          + getCode(): String
        + getTitre(): String                 Booléen estEmprunté() {                             Booléen estEmprunté() {             + getTitre(): String
        + getAuteur(): String                  return emprunté;                                    return ficheEmprunt!=null;        + getAuteur(): String
        + metEmpruntable()                   }                                                   }                                   + metEmpruntable()
        + metConsultable()                                                                                                           + metConsultable()
        + estEmpruntable() : Booléen                                                                                                 + estEmpruntable() : Booléen
        + estEmprunté() : Booléen            Booléen emprunter() {                      Booléen emprunter() {                        + estEmprunté() : Booléen
        + emprunter() : Booléen                if (empruntale et non emprunté) {          if (empruntale et non estEmprunté()) {     + emprunter() : Booléen
        + restituer()                              emprunte = true;                           genre.emprunter();                     + restituer()
        + afficherStastitique()                    genre.emprunter();                         nbEmprunts++;                          + afficherStastitique()
                                                   nbEmprunts++;                              return true;
                                                   return true;                           } return false;}
                                               } return false;}

24/38     01/2020                        Denis Conan                     CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.7 Rappels : « Façade » et classe d’association
     Façade :
        •   Constructeur et destructeur : cf. traduction des agrégation et composition
        •   Une opération publique par cas d’utilisation

     Classe d’association :                                                                   Note
                                                                                          contenu

        •   Concept n’existant pas en langage
                                                                                          date

            de programmation
                                                              Écrivain                                             Paragraphe
            =⇒ Traduction en deux
            associations lors de la conception
            détaillée                                                         Traduction des multiplicités :
                                                                                  1−−−1 devient 1−−−1 et 1−−−1
                                                                                  *−−−* devient 1−−−* et *−−−1
                                                                                  1−−−* devient 1−−−* et 1−−−1
                                                                                  *−−−1 devient 1−−−1 et *−−−1

                                                              Écrivain                                             Paragraphe
                                                                                               Note
                                                                                          contenu
                                                                                          date

25/38   01/2020           Denis Conan        CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.8 Traduction des diagrammes de séquence en
                      algorithmes
                                     
                                                                f:FicheEmprunt                     :CatégorieClient                          g:Genre

                                                                                         c:Client                    d:Document
        constructeur(c,d) {
             client = c; document = d;
             dateEmprunt = « date du jour »;
             Integer dn = d.duréeEmprunt(); // 1                          dn=dureeEmprunt():int
             dateLimite = c.dateRetour(dateEmprunt, dn); // 2
             d.emprunter(); // 3
             c.emprunter(this); // 4                                      dateLimite=
             nbEmpruntsTotal++;                                           dateRetour(
             Double tn = d.tarifEmprunt(); // 5                           dateEmprunt,dn):date
             tarif = client.sommeDue(tn); // 6                                              cD=getCoefDuree():double
        }                                                                 bd=emprunter(f)                         bg=emprunter()
                                                                             :booléen                                :booléen
                                                                          bc=emprunter():booléen
                                                                          tn=
                                                                          tarifEmprunt():double

                                                                          tarif=
                                                                          sommeDue(tn):double
                                                                                          cT=getCoefTarif():double

26/38       01/2020                       Denis Conan                  CSC4102 : Conception detaillée et préparation des tests unitaires
3.3.9 Traduction des diagrammes de machine à
                  états
     Certaines méthodes apparaissent en tant qu’action dans les diagrammes de
        machine à états
                                                                                                                              Booléen vérifier() {
                            EnCréation                                                          EnCours                         if (dépassé) return false;
                                                                                                                                else
                       entry: constructeur()                                             nouveau jour: vérifier()                  if (dateLimite < « date du jour »)
                                                                                                                                       return true;
                                                                                                                                return false;
                                                                                                                              }

                                                                                                      [dateJour>dateLimite]
                                                                                        ()
                                                                                   er
                                                                                  itu
                                                                              st
           restituer() {
                                                                            /re
             client.restituer();                                          nt
                                                                         ie
                                                                     cl

             document.restituer();}
                                                                                                                              premierRappel() {
                                                                     e

           }
                                                                   rl

                                                                                                                                if (non dépassé) {
                                                                pa
                                                               n

                                                                                                                                    client.marquer();
                                                          tio
                                                         itu

                                                                                                                                    dateRappel = « date du jour »;
                                                     st

                                                                                                                                }
                                                    re

                                                                                                                              }

                                                restitution par le client                                                     relancer() {
                           EnDestruction               /restituer()                            EnRetard                          if (« date du jour » > dateRappel + 7)
                                                                                                                                     dateRappel = « date du jour »;}
                       entry:destructeur()                                               entry: premierRappel()               }
                                                                                         nouvelle semaine:
                                                                                                relancer()

27/38   01/2020                       Denis Conan                                  CSC4102 : Conception detaillée et préparation des tests unitaires
4 Préparation des tests unitaires

        4.1 Invariant de classe
        4.2 Précondition, postcondition, et algorithme d’une opération
        4.3 Table de décision des opérations

28/38    01/2020          Denis Conan       CSC4102 : Conception detaillée et préparation des tests unitaires
4.1 Invariant de classe

     Invariant = Propriété vraie pendant tout le cycle de vie                          [Lamport, 2003]

        • Exprimé en fonction des attributs modifiables
         − Principe : étant donné un objet correctement construit, l’invariant reste vrai
     Méthodologie :

        • Calculez l’invariant
         − À partir du diagramme de machine à états et de la liste des attributs
                   modifiables
         − Avec les contraintes de valeurs des attributs non modifiables
        • Ajoutez l’opération publique « invariant(): Booléen »
        • Utilisez cette opération pour vérifier le bon fonctionnement des opérations qui
             modifient l’état

29/38    01/2020                 Denis Conan   CSC4102 : Conception detaillée et préparation des tests unitaires
4.1.1 Exemple : invariant de la classe Document I
     Première étape : caractériser les états autorisés et ceux non autorisés

                                                                              mise en prêt
                                                                           /metEmpruntable()
                      EnCréation                     Consultable                                    Empruntable
                    entry:constructeur()                                                                                                        Document
                                                                          mise en consultation
                                                                           /metConsultable()                    emprunt              code:string
                                              retrait du rayon                                                  /emprunter()         titre:string
                                                                             retrait du rayon                                        auteur:string
                                                                                                                                     année:string
                                                                                                 restitution
                                                                                                 /restituer()                        empruntable:booléen=F
                                                                                                                                     /emprunté:booléen=F
                                                    EnDestruction                                      Emprunté                      nbEmprunts:integer=0

                                                    entry:destructeur()

        (¬empruntable ∧ ¬emprunte) ∨ (empruntable ∧ ¬emprunte) ∨ (empruntable ∧ emprunte)
        ≡ h distributivité de ∨ sur ∧i
                                                                                
         (¬empruntable ∨ empruntable) ∧ ¬emprunte                                   ∨ (empruntable ∧ emprunte)
        ≡ h principe du tiers exclu (p ∨ ¬p = true) et identité de ∧ (p ∧ true = p)i
        ¬emprunte ∨ (empruntable ∧ emprunte)
        ≡ h distributivité de ∨ sur ∧, principe du tiers exclu et identité de ∧i
        (¬emprunte ∨ empruntable) ∧ nbEmprunts ≥ 0
        h définition de =⇒ i
        emprunte =⇒ empruntable

30/38     01/2020                          Denis Conan                    CSC4102 : Conception detaillée et préparation des tests unitaires
4.1.1 Exemple : invariant de la classe Document II

     Seconde étape : prise en compte des autres attributs

                Localisation
                                  est rangé              Document                                                 Médiathèque
         salle:string                         *                             *
         rayon:string                             code:string                                                nom:string
                                                  titre:string
                                                  auteur:string
                  Genre                           année:integer
                                  posséder
         nom:string
                                              *   empruntable:booléen=F      *       concerne         0..1       FicheEmprunt
         nbEmprunts:integer=0                     /emprunté:booléen=F
                                                  nbEmprunt:integer=0

         ∧   (emprunte =⇒ empruntable)
         ∧   code 6= null ∧ code 6= vide
         ∧   titre 6= null ∧ titre 6= vide
         ∧   auteur 6= null ∧ auteur 6= vide
         ∧   nbEmprunts ≥ 0
         ∧   localisation 6= null
         ∧   genre
                    6= null                                                        
         ∧    (¬emprunte ∧ ficheEmprunt = null) ∨ (emprunte ∧ ficheEmprunt 6= null)

31/38   01/2020                 Denis Conan                 CSC4102 : Conception detaillée et préparation des tests unitaires
4.1.1 Exemple : invariant de la classe Document
                   III

        (¬empruntable∧¬emprunte)∨(empruntable∧¬emprunte)∨(empruntable∧emprunte)
        ≡ h distributivité de ∨ sur ∧i                    
         (¬empruntable ∨ empruntable) ∧ ¬emprunte ∨ (empruntable ∧ emprunte)
        ≡ h principe du tiers exclu (p ∨ ¬p = true) et identité de ∧ (p ∧ true = p)i
        ¬emprunte ∨ (empruntable ∧ emprunte)
        ≡ h distributivité de ∨ sur ∧, principe du tiers exclu et identité de ∧i
        (¬emprunte ∨ empruntable) ∧ nbEmprunts ≥ 0
        h Définition de =⇒ i
        (emprunte =⇒ empruntable) ∧ nbEmprunts ≥ 0

32/38    01/2020         Denis Conan       CSC4102 : Conception detaillée et préparation des tests unitaires
4.2 Précondition, postcondition, et algorithme
                    d’une opération
     Programmation défensive :

        •     Nous proposons de vérifier la précondition au début de l’opération
              et de lever une exception en cas de non-respect de la précondition
     Programmation par assertion :

        •     Pour les méthodes qui modifient l’état, nous proposons de vérifier l’invariant
              par assertion4 à la fin d’une opération, avant de retourner la valeur de retour
     Tests unitaires :

        • Nous proposons de vérifier dans les tests unitaires
         − la postcondition5
         − la levée des exceptions
          4. La programmation des assertions et des exceptions sont étudiées lors de la séance 6.
        En JAVA, cf. l’instruction assert : par exemple, « assert invariant(); »
          5. Rappelons qu’une postcondition exprime les conditions à vérifier à l’issue de
        l’opération, mais uniquement si la précondition est auparavant satisfaite
33/38     01/2020            Denis Conan          CSC4102 : Conception detaillée et préparation des tests unitaires
4.2.1 Exemple : constructeur de Document
     Précondition et invariant

        constructeur(String c, Localisation l, String t, String au, String an, Genre g)
            si code = null ∨ code = "" alors levée d’une exception
            ... // vérification des autres arguments
            code := c
            localisation := l
            titre := t
            auteur := au
            annee := an
            genre := g
            empruntable := false
            emprunté := false
            assert invariant()

     Postcondition qui se teste de l’extérieur de la méthode,
        c’est-à-dire dans les tests unitaires
        •   Objet effectivement et correctement construit

34/38   01/2020           Denis Conan        CSC4102 : Conception detaillée et préparation des tests unitaires
4.2.2 Exemple : emprunter de la classe Document

     Précondition et invariant

          void emprunter()
              si ¬ (empruntable ∧ ¬emprunté) alors levée d’une exception
              emprunte = true
              genre.emprunter()
              nbEmprunts++
              assert invariant()

     Postcondition pour les tests unitaires6

        •     empruntable0 ∧ emprunte0 ∧ (nbEmprunts0 = nbEmprunts + 1)

         6. Le prime exprime l’état à la fin de l’exécution de l’opération : p.ex. emprunte0 est la
        valeur de l’attribut emprunte à la fin de emprunter
35/38     01/2020             Denis Conan          CSC4102 : Conception detaillée et préparation des tests unitaires
4.3 Table de décision des opérations
     Pour les classes avec diagramme de machine à états, on construit les tables
        de décision 1) du ou des constructeurs, et 2) des opérations qui modifient
        l’état de l’objet
     P.ex, l’opération emprunter() de la classe Document
                                   Numéro de test                                            1           2            3
                  Précondition    empruntable                                               F            T           T
                                   emprunté                                                              F           T
                  Postcondition    nbEmprunts0 = nbEmprunts + 1                                          T
                                   empruntable0 = true                                                   T
                                   emprunte0 = ¬emprunte                                                 T
                     Exception     Levée d’une exception                                   oui         non          oui
                          Effet    Emprunt accepté                                          F            T            F
                                   Nombre de jeux de test                                     1           1            1

     Rappels :
        •   La postcondition n’est vérifiée que lorsque la précondition est satisfaite
        •   Le non-respect de la précondition est vérifié par la levée d’une exception

36/38   01/2020               Denis Conan            CSC4102 : Conception detaillée et préparation des tests unitaires
5 Mise en pratique en TP (2h) + HP (3h)
     Conception détaillée et préparation des tests unitaires de C1

        •   Raffinement du diagramme de classes
        •   ≥ 1 Fiche de classe, dont C1
        •   ≥ 1 diagramme de machine à états (DMEC1 ) + invariant (INVC1 )
        •   ≥ 2 algo. (ALGO1C1 , ALGO2C1 ) : constructeur + ≥1 op. impliquée dans
            DSUC1 ..DSUC3
        •   ≥ 2 tables de décision de tests unitaires, dont TDALGO1C , TDALGO2C
                                                                                      1                     1

     Rendu de la séance en HP (3h) : Umlet + PDF dans « sprint1 »

     Compléments « Pour aller plus loin » sur la conception détaillée

        •   Diagramme de composants et de paquetages de la vue développement
        •   Diagrammes de déploiement de la vues physique

     Préparation prochaine séance : prérequis « Programmation JAVA » (cours,
        exercices)

37/38   01/2020             Denis Conan      CSC4102 : Conception detaillée et préparation des tests unitaires
Références I
        Cunningham, W. (2009).
        TechnicalDebt.
        https://www.youtube.com/watch?v=pqeJFYwnkjE.

        Fowler, M. (2003).
        TechnicalDebt.
        http://martinfowler.com/bliki/TechnicalDebt.html.

        Giardino, C., Paternoster, N., Unterkalmsteiner, M., Gorschek, T., and Abrahamsson,
        P. (2016).
        Software Development in Startup Companies : The Greenfield Startup Model.
        IEEE Transactions on Software Engineering, 42(6) :585–604.

        Lamport, L. (2003).
        Specifying Systems : The TLA+ Language and Tools for Hardware and Software
        Engineers.
        Addison Wesley.

        OMG (2013).
        OMG Unified Modeling Language, Version 2.5.
        Specification number formal/2013-09-05.

38/38   01/2020           Denis Conan        CSC4102 : Conception detaillée et préparation des tests unitaires
Vous pouvez aussi lire