Programmation Objet en JAVA Cours 8 : Projet de Programmation, JUnit, retour sur le partiel

Preview:

DESCRIPTION

Programmation Objet en JAVA Cours 8 : Projet de Programmation, JUnit, retour sur le partiel. Infos pratiques. Rattrapage du 11/11 TD : lundi 16/11 Cours jusqu’au 2/12 Le projet a démarré : Il y a 6 séances Ne ratez pas les évaluations ! Les retards seront pénalisés. - PowerPoint PPT Presentation

Citation preview

Programmation Objet en JAVA

Cours 8 : Projet de Programmation, JUnit, retour sur le partiel

Infos pratiques

• Rattrapage du 11/11

– TD : lundi 16/11

– Cours jusqu’au 2/12 • Le projet a démarré :

– Il y a 6 séances

– Ne ratez pas les évaluations !

– Les retards seront pénalisés.

Gestion de projet : méthode

Agir avec méthode

• Pour un développement conséquent, ne pas se perdre. • Les objectifs de base :

– quels sont les objets nécessaires ?

– quelles sont les interfaces de ces objets ?

– existent-t-ils des classes ? Comment les écrire si nécessaire ?• Phase 0 : faire un plan !• Phase 1 : définir l’objectif -> cahier des charges

– Quel est le « produit » ? une application java

– Faire des scénarii d’utilisation (use case)• Permet de répondre aux 3 questions de base.• Faire un fichier par classe, y écrire les signatures des méthodes

publiques, et surtout beaucoup de commentaires.• Commencer l’écriture des interfaces qui répondent aux use cases.• Pas d’implémentation

Méthode - suite

• Phase 2 : Comment construire ? Classes et interaction

– Etendre la phase 1 et prévoir des classes utilisables et réutilisables.

– Commencer l’écriture de chaque classe.

– Bien choisir son nom.

– Définir les responsabilités de chaque classe.

– Définir les collaborations entre les classes.

– Aboutir à un diagramme de classe

– Un fichier source par classe, des classes courtes !

– Dans les commentaires, indiquer quelles sont les informations stockées et comment elles sont traitées.

– Penser au polymorphisme.

Méthode - suite

• Phase 3 : écrire le coeur de l’application– écrire les classes principales– «  remplir » les fichiers, réaliser les commentaires.– implémentation, choix des attributs– encapsulation des données.– Tests unitaires

• Phase 4 : Retour sur les scénarii utilisateur.– compléter, augmenter les use cases – Ajouter des classes et des méthodes– retour à la phase 2.

• Phase 5 : évolution

Mise en oeuvre

• Stratégies pour le code

– Extreme programming : écrire d’abord les tests.

– Pair programming• Divers :

– n’oubliez les packages dans la conception.

– Ne pas réinventer la roue, utiliser l’API Java, les conteneurs, ...

– Documenter au maximum son code, pour l’utilisation et la réutilisation -> javadoc, vous travaillez à deux !

– L’utilisation de CVS (ou svn) est obligatoire

• Voir sur le wiki de l’IE2, il existe un server svn paramétrable

• Contacter Gilles Soufflet pour avoir un compte.

Test Unitaire, JUnit 4

Pourquoi tester ?

• Principe de programmation :

un programme terminé est un programme testé !• L’objectif est de garantir le fonctionnement d’un programme :

– test formel : démontrer qu’un algorithme respecte un ensemble de spécification formel.

– test exhaustif : envisager tous les cas possibles !!!

– test heuristique : choisir judicieusement des cas d’utilisation critique.

Les différents types de test

• test unitaire : – test les modules indépendamment

• test d’intégration : – intégration des différents modules é– orienté utilisateur

• test de régression :– s’assurer qu’une modification ne remet pas tout en cause.

Les manières : • black box testing

– vérification du respect par un objet de son interface, ses spécifications ⇒ test fonctionnel

• white box testing – vérification des déI tails d’une implémentation.

Problématique des tests unitaires

• Cycle de développement «  en TP » :

– écriture d’un petit bout de code (quelques heures)

– test avec le debugger ou avec des println.

– vérification «  à la main » des résultats• Le code ajouté au fur et à mesure est testé incrémentalement. • Mais :

– peut-on ré-exécuter les tests ? non.

– comment faire avec plus de 10 classes qui interagissent ? rien.

– Comment visualiser tous les println ?• Peut mieux faire !

Principe des tests unitaires

• Détecter les erreurs le plus tôt possible dans le cycle de développement : – tester la méthode dès son écriture– répéter l’ensemble des tests à chaque modification (régression)– garder la trace des résultats.

• Les questions à se poser pour écrire un « bon test » :– la méthode fait-elle ce qui est attendu ? – supporte-t-elle les modifications d’autres méthodes ? – envisager des cas critiques d’utilisation.

• Une approche extrême : – écrire les tests d’abord à partir du cahier des charges, coder

ensuite !

Principe des tests unitaires - conséquences

• Au moins un test par méthode !• Le contenu d’un test :

– fixture : code d’initialisation du test

– assert : comparer la valeur attendue avec celle obtenue

– un rapport (mail, gaphique, ...)

– les tests sont indépendants.• Couverture : envisager le plus de cas possible • Conditions « au bord »• Répétition d’opération

Erreurs habituelles -> tests habituels

• On a tendance a répéter les mêmes erreurs

– faire des tests au plus tôt permet de réduire cet effet• Les erreurs habituels :

– avec les nombres : 0, le plus grand/petit, positif/négatif, ...

– avec des structures de données :

• structure vide

• avec un seul éléments

• avec le maximum d’éléments

• accès répéter à un même élément

• duplication d’un élément

• effacer un élément

• ...

Selon les phases de travail

• Phase de développement :

– les tests qui doivent réussir :

• test aux limites : trier une liste vide ou avec un seul élément

• cas intéressant simple : trier une liste de deux valeurs

• cas général : trier une liste de 11 valeurs

– les tests qui doivent échouer :

• entrée, accès invalides

• mauvaise « entrée de l’utilisateur »• Phase de test :

– dès qu’une anomalie est détectée : écrire le test qui correspond

– documenter ses erreurs courantes.

Exemple chiffré

Logiciel resolver (www. resolversystems.com)• 57k lignes de codes• 2 millions de dollars• 1 an et demi de développement pour 10 développeurs (10 lignes par

jours)• 31k lignes de tests unitaires : 55%

QuickTime™ et undécompresseur

sont requis pour visionner cette image.

JUnit 4 / Java > 1.4

• Un ensemble de test est regroupé dans une classe «  normale » :

– avec des attributs et des méthodes.• Les méthodes relatives aux tests utilisent les annotations :

@Test

public void methodeDeTest(){ .... }

– Les annotations accrochent une information à une méthode, un attribut, ou une classe.

– Cette information peut ensuite être traitée par un mécanisme indépendant (compilateur, interpréteur, environnement d’exécution, ... ).

• Se créer et s’exécute avec un IDE. • Voir un exemple avec Eclipse :

– création de la classe de test

– exécution

JUnit4 - les assertions

• static void assertTrue(boolean test)

– méthode JUnit : vérifie (test == true)

– dans le cas contraire lance une exception (en fait une Error) de type AssertionFailedError => traitée par l’exécuteur JUnit.

• Les autres :

– assertFalse

– assertEquals

– assertSame, sur les références

– assertNotSame

– assertNull, assertNotNull• fail : lance une erreur, avec un message.

Les « fixtures » et autres subtilités

• Pour initialiser avant chaque test : @Before• Initialiser une seule fois : @BeforeClass • Pour après : @After, @AfterClass• Ignorer un test @Ignore• Tester dans un temps contraint : @Test(timeout=1)• @Test(expected=IndexOutOfBoundsException.class)

Pour plus d’information :

– Le site junit.org

– Un étude de cas : abreslav.googlepages.com/j-junit4-a4.pdf

– Le site des furieux : extremeprogramming.orgPratiquer pendant le projet :

– Les tests unitaires seront bienvenus !

Projet de programmation

• Introduction

Un projet de développement (objet)

Les 5 phases fondamentales• Analyse du problème• Conception objet• Implémentation• Test et vérification• Documentation

• Ces 5 phases sont d’égales importances.• Le projet se fait en binôme.

Les objectifs du projet

• réaliser entièrement, de zéro, un projet à partir de spécifications informelles (énoncé en français) et formelles (un ensemble d'interfaces);

• étape de conception préalable à l'implémentation;• encapsuler vos données pour obtenir des programmes robustes;• éprouver l'intérêt de séparer la partie traitement d'un programme de

sa partie interface utilisateur; • tester au fur et à mesure !• des programmes réutilisables par d’autres et par vous; donc les

écrire lisiblement en les commentant judicieusement;• utiliser javadoc pour générer la documentation• utiliser des outils développements appropriés.

Le sujet, le jeu

• Parcourir l’Ardèche en passant par un maximum de villages différents• Mais à chaque route son moyen de transport.

QuickTime™ et undécompresseur

sont requis pour visionner cette image.

Les éléments de Jeu

• Les joueurs (un nom, une couleur)• La carte de l’Ardèche : 20 villages reliés par 36 routes• Une route relie 2 villages et traverse un type de paysage parmi 4 :

– plaine, forêt, garrigue, montage

– le type de la route implique des moyens de transport et des coûts spécifiques.

• Un carte moyen de transport = un crédit pour un mode de transport :

– l'âne, le sanglier, le vélo, le tracteur, la mobylette, et l'ULM• Un pion de transport :

– permet d’indiquer pour une route de la carte quel moyen de transport DOIT être utilisé.

– un seul pion par route (hors obstacle)

Tour de jeu : 6 étapes

• Etape 1 : distribution des cartes Voyage (8 par joueur)– Les cartes doivent donc être distribuée aléatoirement– Créer toutes les cartes, et les ranger dans un paquet– Prévoir une méthode pour distribuer les cartes (une à une, ou n

fois)– Un joueur doit pouvoir « contenir » ses cartes

• Etape 2 : Attribution du pion de transport caché – Chaque joueur reçoit un pion de transport que lui seul connait,

pris dans le paquet des pions de transport.– Comme pour les cartes et le paquet de cartes– Un joueur doit connaître son pion caché, mais pas les autres

joueurs.

Tour de jeu - suite

• Etape 3 : Attribution des pions de transport

– Parmi le paquet de pions de transport, 5 pions sont au préalable piochés et posés face visible

– Chaque à tour de rôle joueur a le choix :

• prendre un des 5 pions visibles, dans ce cas le pion pris est remplacé

• ou piocher dans le paquet.

– Au total, chaque joueur doit acquérir 3 pions de cette manière.

– Ces trois pions sont visibles des autres joueurs.

Tour de jeu - encore

• Etape 4 : préparation des routes

– chacun son tour, un joueur pose un pion de transport sur une route

– Sur une route, il ne peut y avoir qu'un seul pion moyen de transport.

– Un moyen de transport ne peut être posé sur une route que s'il est approprié

– Ces moyens de transportposés sur le plateau peuvent être utilisés par tous les joueurs lors de leurs déplacements (phase suivante).

• Au lieu d’un pion moyen de transport, un joueur peut placer un obstacle.

– Sur un moyen de transport déjà en place. Sur une route il ne peut y avoir qu'un obstacle.

– Un obstacle sur une route oblige à payer plus cher. • Un joueur peut aussi passer son tour. • Si aucun joueur ne veut ou ne peut plus poser de moyen de transport, cette

phase est terminée.

Tour de jeu - encore

• Etape 5 : le voyage

– chacun son tour, le joueur se déplace sur les routes où sont posés les pions de transport

– en payant avec ses cartes de transport,

– sur autant de routes qu'il veut et en visitant autant de villages qu'il peut en respectant les règles.

• Le but : atteindre des villes différentes.• Premier passage dans une ville, le joueur prend un pion/marqueur de

sa couleur. • Une ville doit donc contenir un marqueur par joueur ! on peut l’enlever

une fois, c’est tout.

Tour de jeu - c’est presque fini

• Etape 6 : résolution du tour

– Le rôle de premier joueur passe au suivant.

– Chaque joueur doit redonner tous ses pions moyen de transport pour n'en garder qu'un seul (caché ou visible).

– Les obstacles utilisés sont retirés du jeu définitivement.

– Toutes les cartes Voyage qui ont été jouées ou défaussées sont remises dans le paquet de cartes

• Il y a 4 tours de jeu !

Représentation du plateau

• Pas besoin d’être réaliste• Obligatoire :

– 20 villes, 36 routes

– des idées dans le sujet• Comment coder une carte ?

– une Ville ?• un nom• une ville doit-elle connaître ses

routes ?• Un marqueur par joueur, ...

– une route ?• un type• deux villes • un pion adapté, un obstacle, ...

QuickTime™ et undécompresseur

sont requis pour visionner cette image.

Conception du moteur (l’IG, connait pas)

• Lister les classes, écrire pour chacune son interface• Choisir ses packages• Ecrire le main d’un tour de jeu

– ici les 6 phases

– chaque phases peut manipuler les interfaces Joueur, Ville, Pion, ... .

– Faire des schémas d’utilisation et des diagrammes de classes !

Exemple de l’étape 1 : distribution des cartes

• Une classe Carte ? – Comment lier le type des routes, le type des pions transport et le type des

cartes ?– Comment faire pour qu’une carte Voyage puisse s’utiliser sur une route

ayant un certain pion de transport ? – Une route avec un pion de transport ne pourra être empruntée par un

joueur qu’avec une carte adaptée !• Le joueur transmet une liste de carte ? • Comment traiter les Exceptions ?

• Une classe Paquet de Carte : – contient au plus 72 cartes => un tableau– répartition des types de cartes => constructeur– une interface pour les constantes ? Une classe Config ?– méthode shuffle (mélange les cartes)– méthode distribution(Joueur j, int nbCartes)

• Que renvoie-t-elle ? • Exception ?

Autre exemple de use case

• Le joueur veut déplacer son pion :

– comment caractériser le déplacement ? le choix de la voie est mieux que le choix de la destination (plusieurs voies possibles)

– Le paramètre de la méthode peut être une voie de transport.

– Il faut alors vérifier que le joueur peut effectuer ce déplacement :

• qui le fait ? le joueur, la voie ?

– Prévoir par exemple un « type » voie avec une méthode

• public int empruntablePar(Joueur j)

• Cette méthode doit avoir accès à la position et les cartes du joueur => getters

• On peut contraindre le choix du joueur en lui passant toutes les voies empruntables (pratique pour le moteur et pour l’IG).