46
Développement guidé par les tests

Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Embed Size (px)

Citation preview

Page 1: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Développementguidé par les tests

Page 2: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Tests logiciels

• Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas de figure– problèmes matériels– problèmes logiciels

• Un test est un procédure partielle d'un système informatique– l'objectif est de trouver le nombre maximum de

comportement problématique du logiciel

Tests 2

Page 3: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Tests logiciels

• Un test examine une hypothèse formulées par– des données en entrées– un module à tester– un observation attendue

• Un test est un ensemble d'un ou plusieurs cas de test

• Un test respecte l'exigence de répétabilité– vérification de la non régression

Tests 3

Page 4: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Tests logiciels

• Organismes, normes et projets– IEEE 829-1998– ISTQB : International Software Testing Qualification

Board– CFTL : Comité Français des Tests Logiciels– projet STSARCES : Software quality and safety

requirements

Tests 4

Page 5: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Défaut (Bug)

• Un défaut est une imperfection dans un composant ou un système qui peut en perturbéer le fonctionnement– un code étant syntaxiquement et algorithmiquement

correct peut présenter un défaut qui se manifestera plus tard• défaut de performance par exemple

Tests 5

Page 6: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Sûreté de fonctionnement

• Prévention des fautes– ensemble des dispositions prises pour assurer un

développement maîtrisé du produit– concerne donc le processus général de conception du

système

• Tolérance aux fautes– ensemble de techniques destinées à fournir un service

en dépit des fautes– concerne la détection des fautes et mise en position

de repliTests 6

Page 7: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Sûreté de fonctionnement

• Élimination des fautes– application au cours de chaque phase du cycle de vie

de méthodes et techniques destinées à réduire la présence de fautes

• Prévision des fautes– évaluation du comportement du système par rapport

à l'apparition de fautes

Tests 7

Page 8: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Vérification du logiciel

• Objectifs– démontrer que le produit logiciel issu d'une phase de

développement est conforme aux spécifications– détecter et rendre compte des fautes pouvant avoir

été introduites au cours des phases précédent la vérification

• Techniques utilisées– tests– revue et analyse de code

Tests 8

Page 9: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Test logiciel

• Approche dynamique de la vérification– l'objectif est de s'assurer que le logiciel possède les

caractéristiques requises pour son contexte d'utilisation

– il faut donc décrire avec précision le contexte• les fonctionnalités attendues• les contraintes d'environnement• les situations dangereuses• ...

Tests 9

Page 10: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Tests du logiciel

• Détection d'éventuels écarts entre le comportement attendu et le comportement observé

• Obtenir la confiance nécessaire avant l'utilisation opérationnelle

Tests 10

Page 11: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Types de tests du logiciel

• Tests unitaires– chaque module effectue toute la fonction et

seulement la fonction prévue– on distingue :• les tests logiques : recherche d'erreur, vérification de

l'enchaînement des branches parcourues• les tests de calcul : vérification des résultats, des

performances, de l'exactitude des algorithmes

Tests 11

Page 12: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Types de tests du logiciel

• Tests d'intégration du logiciel– démonstration du bon fonctionnement d'unités

fonctionnelles constituées de modules– vérification des enchaînements entre modules, de la

circulation des données– vérification des reprises en cas d'interruption

Tests 12

Page 13: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

Types de tests du logiciel

• Tests de validation– s'assurer que le logiciel dans son environnement

matériel répond aux spécifications fonctionnelles

Tests 13

Page 14: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit

• Framework de rédaction et d'exécution de tests unitaires– www.junit.org

• Imaginé et développé par Kent Beck et Erich Gamma

• Offre au développeur une environnement simple de rédaction de tests

Tests 14

Page 15: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• Diagramme des classes principales

Tests 15

Test

run(TestResult)

TestCase

run(TestResult)runTest()setUp()tearDown()

TestSuite

run(TestResult)addTest(Test)TestResult

Page 16: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• Pour utiliser JUnit dans votre projet– sélectionnez les propriétés du projet– dans Java Build Path sélectionnez l'onglet Libraries– cliquez sur le bouton Add External Jar– recherchez le jar de JUnit dans le répertoire plugins du

répertoire d'installation d'Eclispe• selon la version d'Eclipse vous aurez le choix entre les

versions 3 et 4 de JUnit

Tests 16

Page 17: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

Tests 17

Page 18: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• Écriture d'un test– dériver une classe de junit.framework.Testcase– coder les tests, dans des méthodes testxxxx• méthodes publiques contenant des assertions

• TestCase implémente l'interface Test et dérive de la classe Assert– la classe Assert possède de nombreuses méthodes

permettant de valider le code

Tests 18

Page 19: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• Exemple de test– le test peut-être lancé sous Eclipse par Run As... JUnit Test

Tests 19

public class CalculatriceTestSimple_1 extends TestCase{

public void testAddition(){

int a = 3;int b = 4;int r = a+b;Calculatrice calc = new Calculatrice();assertTrue(r==calc.additionner(a, b));

}}

Page 20: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• L'exécution du test ouvre une nouvelle vue– les méthodes commençant

pat testxxx sont exécutées– les tests qui ne sont pas passés

sont indiqués en failure• un double clique sur le test

positionne le curseur sur lecode correspondant

Tests 20

Page 21: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• Méthodes d'assertion

Tests 21

Méthode Description

assertEquals vérifie l'égalité entre deux objets

assertFalse vérifie si l'expression est fausse

assertNotNull vérifie que l'objet n'est pas null

assertNotSame vérifie que deux références sont différente

assertNull vérifie que l'objet est null

assertSame vérifie que deux références sont les mêmes

assertTrue vérifie que l'expression est vraie

fail provoque l'échec du test

Page 22: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3

• Méthodes d'assertion– deux formes

• assertYYY(valeur1 [,valeur2])• assertYYY(messageSiErreur, valeur1 [,valeur2])

• Utilisation d'une fixture–méthodes protected

Tests 22

Méthode Description

setUp initialisation, invoquée avant chaque méthode de test

tearDown libération des ressources, invoquées après chaque méthode de test

Page 23: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3 - suite de tests

• Écriture d'une méthode Test suite()– création d'un objet de type TestSuite dans la

méthode– codage du chaînage des appels aux tests

• addTest()– invoque le test passé au constructeur de notre classe de test– nécessite un constructeur avec String dans la classe de Test

• addTestSuite()– invoque l'ensemble des tests de la classe de test

Tests 23

suite.addTest(new CalculatriceTestSimple_1("testAddition"));

public CalculatriceTestSimple_1(String test){

super(test);}

Page 24: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3 - suite de tests

• Exemple de suite de tests

Tests 24

public class CalculatriceTestsSuites{

public static Test suite(){

TestSuite suite = new TestSuite("Exemple de suite de tests");suite.addTestSuite(CalculatriceTestSimple_1.class);suite.addTestSuite(CalculatriceTestSimple_2.class);

return suite;}

}

Page 25: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3 - suite de tests

• Répétition de test– classe RepeatedTest

Tests 25

public class CalculatriceTestRepetition{

public static Test suite(){TestSuite suite = new TestSuite();suite.addTest(new RepeatedTest(new CalculatriceTestSimple_1("testAddition"), 10));

return suite;}

}

Page 26: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3 - assistant Eclipse

• Eclipse propose un assistant permettant de mettre rapidement en place des tests– par un new JUnit Test Case sur le projet– il suffit de renseigner

l'assistant– la vue suivante de l'assistant

permet de choisir lesméthodes à tester

Tests 26

Page 27: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 3 - assistant Eclipse

• La classe de test générée

Tests 27

public class Tests extends TestCase{

public void testAdditionner(){

fail("Not yet implemented");}

public void testMultiplier(){

fail("Not yet implemented");}

public void testSoustraire(){

fail("Not yet implemented");}

public void testDiviser(){

fail("Not yet implemented");}

}

Page 28: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit - assistants Eclipse

• De même pour créer un chainage de tests– File -> New -> Other -> Java -> JUnit -> JUnit Test Suite

Tests 28

Page 29: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4

• Le framework JUnit a été largement remanié lors de son passage à la version 4– utilisation du framework Hamcrest– utilisation des annotations

• L'utilisation dans les projets nécessite l'importation des archives (répertoire plugins)– junit.jar de JUnit 4– org.hamcrest.core_1.1.0.v20090501071000.jar– ces archives sont importées si l'assistant est utilisé

Tests 29

Page 30: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4

• De nouvelles fonctionnalités font leur apparition– annotations pour les tests et suites de tests– nouvelles assertions– suppositions– tests paramétrés

Tests 30

Page 31: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - annotation @Test• Les méthodes de test sont annotée avec @Test– pas besoin de dériver de TestCase– les assertions sont des méthodes statiques de la

classe org.junit.Assert– les méthodes n'ont pas l'obligation d'être nommées

en testXxxx

• Paramètres principaux de l'annotation– expected : classe Throwable attendue– timeout : durée maximale en millisecondes

• @Ignore permet d'ignorer un testTests 31

Page 32: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - annotation @Test

Tests 32

import org.junit.Test;import static org.junit.Assert.*;

public class TestsUnitaires{

@Testpublic void testAddition(){

Calculatrice calc = new Calculatrice();assertTrue(5 == calc.additionner(2, 3));

}}

public class TestTimeout{

@Test(timeout = 1000)public void dureeRespectee(){}

@Test(timeout = 1000)public void dureeNonRespectee() throws InterruptedException{

Thread.sleep(10000);}

}

Page 33: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - fixture

• Méthodes annotées avec @Before ou @After–méthodes exécutées avant et après chaque méthode

de test–méthode publique– plusieurs méthodes peuvent être annotées avec la

même annotation• l'ordre d'invocation des méthodes annotées est

indéterminé

Tests 33

Page 34: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - fixture

• Méthodes annotées avec @BeforeClass ou @AfterClass–méthodes exécutées avant l'invocation du premier

test de la classe, et après le dernier test de la classe–méthodes publiques et statiques– une seule méthode par annotation

Tests 34

Page 35: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4- fixture

Tests 35

public class TestFixture{

@BeforeClass public static void montageClasse(){

System.out.println(">> Montage avant tous les tests");}

@AfterClass public static void demontageClasse(){

System.out.println(">> Démontage après tous les tests");}

@Before public void montage(){

System.out.println("------ AVANT");}@After public void demontage(){

System.out.println("------ APRES");}

@Test public void test1(){

System.out.println("Test 1");}

@Test public void test2(){

System.out.println("Test 2");}

}

Page 36: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - suite de tests

• Classe vide annotée avec– @RunWith, possibilité de changer la classe d'exécution

de la suite• Suite.class par défaut

– @SuiteClasses(Class[]) pour former la suite de tests

Tests 36

@RunWith(Suite.class)@SuiteClasses({TestsUnitaires.class,TestTimeout.class})public class TousLesTests{}

Page 37: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - tests paramétrés

• La classe de test– est annotée avec @RunWith(Parameterized.class)• exécuteur de test acceptant les paramètres

– contient un constructeur avec les données et le résultat

– contient une méthode renvoyant une collection des paramètres : données et résultat• annotée avec @Parameters

Tests 37

Page 38: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - tests paramétrés

Tests 38

@RunWith(Parameterized.class)public class TestsParametres{

private int a,b, resultat;

public TestsParametres(int a, int b, int resultat){

this.a = a; this.b = b; this.resultat = resultat;}

@Parameterspublic static Collection getParametresAddition(){

return Arrays.asList(new Object[][]{{1,2,3}, {3,5,8}, {9,6,15}});}

@Testpublic void additionTest(){

Calculatrice calc = new Calculatrice();Assert.assertEquals(resultat, calc.additionner(a, b));

}}

Page 39: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - les suppositions

• Une supposition vérifie une condition– classe org.junit.Assume

• Si la supposition n'est pas vérifiée, les test s'arrête– ne passe pas en échec ou erreur

Tests 39

Supposition Description

assumeNoException vérifie qu'une opération s'est déroulée sans lever de Throwable

assumeNotNull vérifie qu'aucun paramètre n'est nul

assumeThat vérifie qu'une condition par contrat est respectée

assumeTrue vérifie que le paramètre est vrai

Page 40: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - les suppositions

Tests 40

public class Supposition{

@Test public void verifierExistenceFichier() { final File lFile = new File("fichier.txt"); Assert.assertTrue("Le fichier doit exister", lFile.exists()); } @Test public void lireFichier() throws IOException { final File lFile = new File("fichier.txt"); Assume.assumeTrue(lFile.exists()); final FileInputStream lFileInputStream = new FileInputStream(lFile); final byte[] lBytes = new byte[16]; lFileInputStream.read(lBytes); Assert.assertArrayEquals("Bonjour le monde".getBytes(), lBytes); }}

Page 41: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - nouvelles assertions

• Assertions d'égalité pour les tableaux– tableaux de byte, char, short, int, long ou Object– assertion assertArrayEquals(...)

• Assertion pour les double avec un delta maximal entre les deux valeurs à comparer– assertEquals(double attendu, double resultat, double delta)

• Assertion sur une condition définie par contrat– assertion assertThat(...)– contrats définis dans JUnit, ou en dehors de JUnit

Tests 41

Page 42: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - assertion par contrat

Tests 42

public class ContratIsSame{

@Testpublic void pasPareil(){

Assert.assertThat(new String("toto"), IsSame.sameInstance("toto"));}

@Testpublic void pareil(){

Assert.assertThat("toto", IsSame.sameInstance("toto"));}

}

Page 43: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - contrats JUnits

Tests 43

Contrat Description

IsSame vérifie l'identité des instances

IsEqual vérifie l'égalité de deux instances

IsInstanceOf vérifie que l'instance du premier paramètre est de la classe du second paramètre

IsNull vérifie que la référence passée est nulle ou non, méthode nullValue(...), ou notNullValue(...)

Is vérifie que l'instance passée en premier paramètre correspond à ce qui est passé en second paramètre (valeur, classe, contrat)

IsNot vérifie que l'instance passée en premier paramètre ne correspond pas à ce qui est passé en second paramètre

AllOf vérifie que tous les contrats passés soient respectés

AnyOf vérifie qu'au moins un des contrats passés est respecté

Page 44: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - exemple contrat

Tests 44

public class ContratIs{ @Test public void classeDeString() { Assert.assertThat("texte", Is.is(String.class)); }

@Test public void classeDeInteger() { Assert.assertThat("texte", Is.is(Integer.class)); }

@Test public void egal() { Assert.assertThat("texte", Is.is("texte")); }

@Test public void pasEgal() { Assert.assertThat("Texte", Is.is("texte")); }

@Test public void pareil() { Assert.assertThat("texte", Is.is(IsSame.sameInstance("texte"))); }

@Test public void pasPareil() { Assert.assertThat(new String("texte"), Is.is(IsSame.sameInstance("texte"))); }}

Page 45: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - contrats hors JUnit• Les assertions par contrats ont à l'origine été

développé par JMock• Il faut ajouter au projet les librairies– jmock– hamcrest-core– hlacrest-library

Tests 45

Page 46: Développement guidé par les tests. Tests logiciels Il n'est pas possible de prouver qu'un système informatique fonctionne correctement dans tous les cas

JUnit 4 - contrats hors JUnit• Les contrats sont séparés en 7 groupes– core : intégrés à JUnit– beans : contrats sur les JavaBeans– collection : contrats sur les tableaux et collections– number : contrats sur les comparaisons numériques– object : contrats sur les objets et classes– text : comparaisons de texte– xml : contrats sur les documents XML

Tests 46