Test
Transcription
Test
JUnit Lionel Seinturier Université des Sciences et Technologies de Lille [email protected] 28/11/06 JUnit 1 Lionel Seinturier Plan 1. Introduction 2. Classes de test 3. Asserts 4. Suite de tests 5. Initialisations 6. JUnit 4 JUnit 2 Lionel Seinturier 1. Introduction JUnit Framework de test pour des programmes Java http://www.junit.org • ensemble de librairies pour exécuter des méthodes de test • fournit méthodes assert pour vérifier le résultat Exemple de code à tester public class Largest { public static int largest(int[] list) { int index, max=0; for (index = 0; index < list.length; index++) { if (list[index] > max) max = list[index]; return max; } } JUnit 3 Lionel Seinturier 2. Classe de tests Règles d'écriture • hérite de junit.framework.TestCase • contient méthodes de test • méthodes publiques avec un nom commençant par test public class TestLargest extends TestCase { public void testOrder() { assertEquals(9, Largest.largest(new int[]{7,8,9}); } } Lancement du test • ligne de commande • GUI Swing • plug-in Eclipse, … JUnit : java junit.textui.TestRunner TestLargest : java junit.swingui.TestRunner 4 Lionel Seinturier 2. Classe de tests Exemple Que teste-t-on ? • ne dépend pas de l'ordre des éléments • ok en cas de répétition • ok en cas de liste avec un seul élément • ok en cas de liste vide • ok en cas de valeur négative public class TestLargest extends TestCase { public void testOrder(){ assertEquals(9,Largest.largest(new int[]{7,8,9}); } p v testOrder2(){assertEquals(9,Largest.largest(new int[]{6,9,7,8}); p v testDup() { assertEquals(9,Largest.largest(new int[]{9,7,8,9});} p v testOne() { assertEquals(7,Largest.largest(new int[]{7}); } p v testEmpty() { assertEquals(0,Largest.largest(new int[]{}); } p v void testNegativeValue() { assertEquals(-8, Largest.largest(new int[]{-6,-7,-8}); } } JUnit 5 Lionel Seinturier 2. Classe de tests Exemple Remarque • testEmpty : est-ce que c'est bien ce que l'on veut ? ¾ amène un questionnement/précision sur les spécifications • testNegative There was 1 failure: 1) testNegative(TestLargest)junit.framework.AssertionFailedError: expected:<-8> but was:<0> at TestLargest.testNegative(TestLargest.java:13) ¾ bug !! ¾ max = Integer.MIN_VALUE ¾ testEmpty ? JUnit 6 Lionel Seinturier 2. Classe de tests Exemple Remarque • si list est null ? ¾ NullPointerException static int largest(int[] list) throws IllegalArgumentException { if( list == null ) throw new IllegalArgumentException("list shouldn't be null); ... } void testNull() { try { Largest.largest(null); fail("IllegalArgumentException should have been thrown"); } catch( IllegalArgumentException iae ) {} } JUnit 7 Lionel Seinturier 3. Asserts Méthodes fournies par JUnit assertEquals( [ String message , ] expected, actual ) • expected, actual • int, float, double, boolean, … • Object : la méthode equals appelée pour tester l'égalité • message : facultatif (si absent message par défaut de JUnit) assertNull( [ String message, ] Object object ) assertSame( [ String message, ] expected, actual ) assertTrue( [ String message, ] boolean condition ) assertFalse( [ String message, ] boolean condition ) fail( [ String message ] ) conduit à l'échec du test JUnit 8 Lionel Seinturier 3. Asserts Méthodes fournies par JUnit assertEquals( [ String message , ] expected, actual, delta ) • pour les types float et double • retourne vrai si actual ∈ [expected-delta , expected+delta ] • exemple Tableaux : assertEquals( 3.33, 10.0/3.0, 0.01 ); : assertEquals égalité de référence (pas de contenu) public void assertArrayEquals( Object[] a1, Object[] a2 ) { assertEquals(a1.length, a2.length); for( int i=0 ; i<a1.length ; i++ ) assertEquals(a1[i], a2[i]); } assertArrayEquals(new Object[]{4,5}, new Object[]{4,7}); JUnit 9 Lionel Seinturier 4. Suite de tests Tests exécutés par JUnit Par défaut JUnit exécute dans une classe de test • toutes les méthodes public dont le nom commence par test Possibilité de restreintre la liste des tests import ju.f.Test; import ju.f.TestCase; import ju.f.TestSuite; public class TestSimple extends TestCase { public void test1() assertTrue(true); public void test2() assertTrue(true); JUnit { } { } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest( new Simple("test1") ); return suite; } public Simple( String methodname ) { super(methodname); }} 10 Lionel Seinturier 4. Suite de tests Tests exécutés par JUnit Notion de suite de tests (TestSuite) • ensemble de tests exécutés en séquence • ajout d'un test : addTest(Test) • ajout des tests d'une autre suite : addTestSuite(Class) public class TestComposite extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest( new Simple("test2") ); suite.addTestSuite( TestSimple.class ); suite.addTest( TestSimple.suite() ); return suite; } } JUnit 11 Lionel Seinturier 5. Initialisations Initialisation des tests • chaque méthode de test est exécutée indépendamment des autres • besoin : initialisation avant d'exécuter le test ¾ méthode setUp() exécutée avant chaque méthode de test ¾ méthode tearDown() exécutée après chaque méthode de test public class TestDB extends TestCase { private Connection cx; protected void setUp() { cx = new Connection( "mysql", "localhost", "9001", "bob, ""); cx.connect(); } protected void tearDown() { cx.disconnect(); cx = null; } public void test1() { ... /*utilise cx*/ ... } public void test2() { ... /*utilise cx*/ ... } } JUnit 12 Lionel Seinturier 5. Initialisations Initialisation des tests • initialisation globale pour toutes les méthodes de tests • méthode static void oneTimeSetUp() oneTimeSetUp() setUp() test1() tearDown() setUp() test2() tearDown() oneTimeTearDown() JUnit 13 Lionel Seinturier 6. JUnit 4 JUnit 4 • mise à jour pour Java 5 • modèle d'écriture de tests à l'aide d'annotations • fonctionnalités identiques • nouvelles fonctionnalités • test paramétré • test à délai d'exécution borné • package org.junit (à la place de junit.framework) • pas nécessaire étendre TestCase • pas nécessaire de préfixer les méthodes de test par test ¾ annotation @Test • méthodes static assert... définies dans la classe org.junit.Assert • méthode static fail définie dans la classe org.junit.Assert JUnit 14 Lionel Seinturier 6. JUnit 4 Exemple import org.junit.Test; import static org.junit.Assert.assertEquals; public class TestLargest { @Test public void order(){ assertEquals(9,Largest.largest(new int[]{7,8,9}); } @Test p v order2(){assertEquals(9,Largest.largest(new int[]{6,9,7,8}); } @Test p v dup() { assertEquals(9,Largest.largest(new int[]{9,7,8,9}); } @Test p v one() { assertEquals(7,Largest.largest(new int[]{7}); } @Test p v empty() { assertEquals(0,Largest.largest(new int[]{}); } } JUnit 15 Lionel Seinturier 6. JUnit 4 Initialisations méthode setUp() méthode tearDown() méthode oneTimeSetUp() méthode oneTimeTearDown() Ö méthode annoté avec @Before Ö méthode annoté avec @After Ö méthode annoté avec @BeforeClass Ö méthode annoté avec @AfterClass Lancement des tests java org.junit.runner.JUnitCore TestLargest JUnit 16 Lionel Seinturier 6. JUnit 4 Test paramétré Pouvoir réutiliser une méthode de test avec des jeux de données ≠ • @Parameters • annote une méthode qui retourne une Collection de tableaux à 2 éléments • 1er élément : une donnée • 2ème élément : le résultat attendu du test avec la donnée précédente • @RunWith(Parameterized.class) • annote une classe qui contient des méthodes de test devant être exécutées avec le jeu de données Principe • pour chaque couple ( donnée , résultat attendu ) • la classe est instanciée • les méthodes de test exécutées JUnit 17 Lionel Seinturier 6. JUnit 4 Test paramétré import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.Collection; import import import import import org.junit.Before; org.junit.Test; org.junit.runner.RunWith; org.junit.runners.Parameterized; org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class Simple { private int value; private int expected; private Calc c = new Calc(); JUnit public class Calc { public int square( int x ) { return x*x; } } 18 Lionel Seinturier 6. JUnit 4 Test paramétré @Parameters public static Collection<Object[]> data() { return Arrays.asList( new Object[][]{ {1,1}, {2,4}, {3,8} } ); } public Simple( int value, int expected) { this.value = value; this.expected = expected; } @Test public void t1() { int result = c.square(value); assertEquals(expected,result); } } JUnit 19 Lionel Seinturier 6. JUnit 4 Autres nouvelles fonctionnalités Test à délai d'exécution borné • pouvoir définir un temps max pour l'exécution d'un test • @Test(timeout=5000) Ö long (délai en ms) Test devant se terminer par une exception • @Test(expected=une_classe_d_exception.class) @Test(expexted=MyExcept.class) public t() { ... } JUnit ≡ 20 @Test public t() { try { ...; fail(); } catch( MyExcept e ) } Lionel Seinturier