Tests unitaires avec JUnit - LIG Membreslig- .temps pour ©crire des tests Baisse de ... Tr¨s souvent

  • View
    216

  • Download
    1

Embed Size (px)

Text of Tests unitaires avec JUnit - LIG Membreslig- .temps pour ©crire des tests Baisse de ......

  • Philippe GENOUD UJF Janvier 2012 1 Philippe GENOUD UGA Dcembre 2017

    Tests unitairesavec JUnit

    Philippe GenoudPhilippe.Genoud@imag.fr

    http://creativecommons.org/licenses/by-nc-sa/4.0/http://creativecommons.org/licenses/by-nc-sa/4.0/

  • Philippe GENOUD UGA Dcembre 2017 2

    Le problme du test

    Tous les programmeurs savent quils doivent crire des tests, peu le font..

    Augmentation

    de la pression

    Moins de

    temps pour crire

    des tests

    Baisse de

    la productivit

    Code moins

    stable

    Je suis trop la bourre !

  • Philippe GENOUD UGA Dcembre 2017 3

    Test Unitaire d'une classe

    L'interface publique d'une classe dfinit "un contrat" entre celui qui fournit la classe et celui qui l'utilise.

    Ce contrat dfinit:

    les services proposs par la classe

    la manire dont ces services doivent tre utiliss

    Tester une classe consiste vrifier la validit de ce contrat

    il confronte la ralisation de la classe sa spcification.

  • Philippe GENOUD UGA Dcembre 2017 4

    Comment tester une classe ?

    Traces (instruction print) dans les programmes

    TestRational.javaSpcification

    Implmentation

    Le programme de test

  • Philippe GENOUD UGA Dcembre 2017 5

    Comment tester une classe ?

    Traces (instruction print) dans les programmes

    Spcification

    Implmentation

    Le programme de test Excution

    Trace d'excution

    Inefficace

    ncessitent un jugement humain

    temps lev, risques d'erreur si une trace contient de nombreux print, perte de lisibilit ( Scroll Blindness )

    processus renouveler chaque fois que la classe est modifie et/ou qu'un bug est corrig

    Automatiser les tests et les confier un programme

  • Philippe GENOUD UGA Dcembre 2017 6

    JUnit

    JUnit : un framework open source (www.junit.org) pour le test unitaire de programmes Java qui permet dautomatiser les tests.

    Facilite

    criture des programmes de tests unitaires

    excution des test unitaires

    l'exploitation des rsultats de test

    Terminologie JUnit

    Test unitaire (Unit test) : test dune classe

    Cas de test (Test case) : teste les rponses dune mthode un ensemble particulier dentres

    Suite de tests (Test suite) : une collection de cas de tests

    Testeur (Test runner) : programme qui excute des suites de tests et rapporte les rsultats

    http://www.junit.org/

  • Philippe GENOUD UGA Dcembre 2017 7

    Mise en uvre de tests avec JUnit

    2 versions

    JUnit 4

    Bas sur des annotations (Java 5+)

    Ces annotations permettent de marquer les classes et mthodes de test

    JUnit 3.8

    Bas sur un framework de Classes et Interfaces

    Ecriture de tests en crivant des classes s'intgrant au framework

    @Test

    public void getSolde() {

    ...

    }

    Accroche une information un lment (classe, mthode, attribut) Java

    Utilise par un mcanisme tiers (compilateur java, environnement d'excution) et non par la classe o elle est dfinie

    Nouvelles fonctionnalits et plus de souplesse (plus de contraintes d'hritage)

    Pour chaque test criture dune mthode testXX

    JUnit 5

    Septembre 2017

  • Philippe GENOUD UGA Dcembre 2017 8

    La classe tester

    Les tests unitaires de Rational

  • Philippe GENOUD UGA Dcembre 2017 9

    Ecriture dune classe de Test

    public class RationalTest {

    //

    public void testMult() {

    }}

    Cration des objets quivont interagir lors du test

    Vrification que le rsultat obtenu correspond bien au rsultat attendu.

    Code qui agit sur les objets impliqus dans le test

    static void assertTrue(boolean test)mthode JUnit : vrifie que test == true et dans le cas contraire lance une exception (en fait une Error) de type AssertionFailedError

    Lexcuteur de tests JUnit attrape ces objets Errors et indique les tests qui ont chou

    La classe de test :

    @Test

    import org.junit.Test;

    import org.junit.Assert;

    Rational r1 = new Rational(2, 3);Rational r2 = new Rational(7, 5);

    r1.mult(r2);

    Assert.assertTrue(14 == r1.getNum());

    Assert.assertTrue(15 == r1.getDenom());

    import static org.junit.Assert.*;

    JUnit 4

  • Philippe GENOUD UGA Dcembre 2017 10

    Les diffrentes mthodes assert

    static void assertTrue(String message, boolean test)

    Le message optionnel est inclus dans lError

    static void assertFalse(boolean test)static void assertFalse(String message, boolean test)

    vrifie que test == false

    assertEquals(expected, actual)assertEquals(String message, expected, actual)

    mthode largement surcharge: arg1 et arg2 doivent tre tout deux des objets ou bien du mme type primitif

    Pour les objets, utilise la mthode equals (public boolean equals(Object o)) sinon utilise ==

    assertSame(Object expected, Object actual)assertSame(String message, Object expected, Object actual)

    Vrifie que expected et actual rfrencent le mme objet (==)

    assertNotSame(Object expected, Object actual)assertNotSame(String message, Object expected, Object actual)

    Vrifie que expected et actual ne rfrencent pas le mme objet (==)

    JUnit 4

  • Philippe GENOUD UGA Dcembre 2017 11

    Les diffrentes mthodes assert

    assertNull(Object object)assertNull(String message, Object object)

    Vrifie que objet est null

    assertNotNull(Object object)assertNotNull(String message, Object object)

    Vrifie que objet nest pas null

    fail()fail(String message)

    Provoque lchec du test et lance une AssertionFailedError

    Utile lorsque les autres mthodes assert ne correspondent pas exactement vos besoins ou pour tester que certaines exceptions sont bien lances.try {

    // appel dune mthode devant lancer une Exception

    .

    // si l'exception n'a pas eu lieu on force le test chouerfail("Did not throw an ExpectedException");

    }catch (ExpectedException e) { }

    JUnit 4

  • Philippe GENOUD UGA Dcembre 2017 12

    Ecriture dune classe de Test

    Comment vrifier que des exceptions sont lances comme prvu ?

    @Test public void testDenomNull() {

    }

    JUnit 4

    Verifying that code completes normally is only part of programming. Making sure the code behaves as expected in exceptional situations is part of the craft of programming too.

    JUnit CookbookKent Beck, Erich Gamma

    try {

    fail("IllegalArgumentException non lance");

    }

    catch (IllegalArgumentException e) {

    // OK exception lance

    }

    @Test

    public void testDenomNull() {

    new ArrayList().get(0);}

    new Rational(3,0);

    (expected=IndexOutOfBoundsException.class)

    la JUnit 3.8

    Avec JUnit4 paramtre expectedde l'annotation @Test

    @Test(timeout=10)public void uneMthode() {...

    }

    Le test choue si l'excution de la mthode dpasse le temps fix par le paramtre timeout

  • Philippe GENOUD UGA Dcembre 2017 13

    Ecriture dune classe de Test

    Plusieurs mthodes de test dans une mme classe de Test

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

    public class TestCounter {//

    @Testpublic testMult() {

    Rational r1 = new Rational(2, 3);Rational r2 = new Rational(7, 5);r1.mult(r2);assertTrue(14 == r1.getNum());assertTrue(15 == r1.getDenom());

    }

    }

    @Test

    public void testAdd() {

    Rational r1 = new Rational(2, 3);Rational r2 = new Rational(7, 5); r1.add(r2);assertTrue(31 == r1.getNum());assertTrue(15 == r1.getDenom());

    }

    public void setUp() {Rational r1 = new Rational(2, 3);Rational r2 = new Rational(7, 5);

    }

    public void tearDown() {......

    }

    private Rational r1;private Rational r2;

    @Before

    @After

    Code excut avant chaque mthode de test

    Code excut aprs chaque mthode de test

    import org.junit.Before;import org.junit.After;

    JUnit 4

  • Philippe GENOUD UGA Dcembre 2017 14

    Ecriture dune classe de Test

    import org.junit.*;

    import static org.junit.Assert.*;

    public class TestCounter {

    @Before

    public void setUp() {

    ...

    }

    @After

    public void tearDown() {

    ...

    }

    @Test

    public void m1() {

    ...

    }

    @Test

    public void m2() {

    ...

    }

    }

    Code excut avant chaque mthode de test de la classe

    Code excut aprs chaque mthode de test de la classe

    JUnit 4

    @AfterClass

    public static void tearDownClass() {

    ...

    }

    @BeforeClass

    public static void setUpClass() {

    ...

    }Code excut une seule fois avant d'excuter toutes les mthodes de test de la classe

    Code excut une seule fois aprs avoir excut toutes les mthodes de test de la classe

    tearDownClass()

    setUpClass()

    setUp()

    tearDown()

    m1()

    setUp()

    tearDown()

    m2()

  • Philippe GENOUD UGA Dcembre 2017 15

    Excution dun test

    en mode texte sur la console

    JUnit 4

    $ set CLASSPATH=.:/java/junit4.10/junit-4.10.jar

    $ javac CounterTest.java

    $ java org.junit.runner.JUnitCore CounterTest

    JUnit version 4.10

    ....E.

    Time: 0,007

    There was 1 failure:

    1) testAdd(CounterTest)

    java.lang.AssertionError: expected: but was:

    at org.junit.Assert.fail(Assert.java:93)

    at org.junit.Assert.failNotEquals(Assert.java:647)

    at org.junit.Assert.assertEquals(Assert.java:128)

    at org.junit.Assert.assertEquals(Assert.java:472)

    at org.junit.Assert.assertEquals(Assert.java:456)

    at CounterTest.testAdd(CounterTest.java:42)

    at sun.r