diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples.tar.gz b/DEV2.1/TP10:TestsJUnit/Junit4Exemples.tar.gz new file mode 100644 index 0000000..9ba5217 Binary files /dev/null and b/DEV2.1/TP10:TestsJUnit/Junit4Exemples.tar.gz differ diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/AssertTests.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/AssertTests.java new file mode 100644 index 0000000..44b0c16 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/AssertTests.java @@ -0,0 +1,106 @@ +/** + Il y a en fait pleins d'assertions possibles. + + voici un exemple faisant un petit tour de ce qui est possible que j'ai pris ici. + https://github.com/junit-team/junit4/wiki/Assertions + + NB. hamcrest est un projet maintenant intégré à junit + (c'est un anagrame de matchers) + + */ + +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.both; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.everyItem; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.hamcrest.core.CombinableMatcher; +import org.junit.Test; + +public class AssertTests { + @Test + public void testAssertArrayEquals() { + byte[] expected = "trial".getBytes(); + byte[] actual = "trial".getBytes(); + assertArrayEquals("failure - byte arrays not same", expected, actual); + } + + @Test + public void testAssertEquals() { + assertEquals("failure - strings are not equal", "text", "text"); + } + + @Test + public void testAssertFalse() { + assertFalse("failure - should be false", false); + } + + @Test + public void testAssertNotNull() { + assertNotNull("should not be null", new Object()); + } + + @Test + public void testAssertNotSame() { + assertNotSame("should not be same Object", new Object(), new Object()); + } + + @Test + public void testAssertNull() { + assertNull("should be null", null); + } + + @Test + public void testAssertSame() { + Integer aNumber = Integer.valueOf(768); + assertSame("should be same", aNumber, aNumber); + } + + // JUnit Matchers assertThat + @Test + public void testAssertThatBothContainsString() { + assertThat("albumen", both(containsString("a")).and(containsString("b"))); + } + + @Test + public void testAssertThatHasItems() { + assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three")); + } + + @Test + public void testAssertThatEveryItemContainsString() { + assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n"))); + } + + // Core Hamcrest Matchers with assertThat + @Test + public void testAssertThatHamcrestCoreMatchers() { + assertThat("good", allOf(equalTo("good"), startsWith("good"))); + assertThat("good", not(allOf(equalTo("bad"), equalTo("good")))); + assertThat("good", anyOf(equalTo("bad"), equalTo("good"))); + assertThat(7, not(CombinableMatcher. either(equalTo(3)).or(equalTo(4)))); + assertThat(new Object(), not(sameInstance(new Object()))); + } + + @Test + public void testAssertTrue() { + assertTrue("failure - should be true", true); + } +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/Calculator.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/Calculator.java new file mode 100644 index 0000000..3f8e4a5 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/Calculator.java @@ -0,0 +1,30 @@ + +/** + Calculator est une classe offrant une seule méthode qui évalue une somme, donnée sous la forme d'une chaîne de caractère listant des opérandes séparées par des + + +*/ + +public class Calculator { + + /** + somme les opérandes passées sous forme d'une chaîne de caractères et retourne le résultat sous forme d'entier. + @param expression : chaîne de caractères ("nombres" séparés par des + sans espaces), par exemple "42+3" ou encore "-42+42" (le moins unaire est autorisé). + ici nombre est à comprendre au sens de parseInt(java.lang.String) + @throws NumberFormatException : si l'expression n'est pas dans ce format (par exemple "x+2" ou " 1 +2" -- il y a des espaces -- ou encore "9999999990"). + */ + public int evaluate(String expression) { + int sum = 0; + for (String summand: expression.split("\\+")) + sum += Integer.valueOf(summand); + return sum; + } + + /** + Pour appeller cette super méthode depuis la ligne de commande (on ne regarde que le premier argument, les autres sont ignorés). + + */ + public static void main(String[] args) { + Calculator calculator = new Calculator(); + System.out.println(calculator.evaluate(args[0])); + } +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest0.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest0.java new file mode 100644 index 0000000..38fc2c3 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest0.java @@ -0,0 +1,30 @@ +import static org.junit.Assert.assertEquals; // import static : une facilité offerte par java5 +import org.junit.Test; + +/** + CalculatorTest0 est un premier exemple de test pour la classe Calculator utilisant junit4 + Assert, ou comment vérifier qu'une méthode donne un résultat correct? + + Remarque en passant, pour tester en ligne de commande (une fois les classes compilées), il faut faire + $java org.junit.runner.JUnitCore CalculatorTest0 + + Remarque, comme expliqué dans la doc de org.junit.runner.JUnitCore +JUnitCore is a *facade* for running tests. It supports running JUnit 4 tests, JUnit 3.8.x tests, and mixtures. To run tests from the command line, run java org.junit.runner.JUnitCore TestClass1 TestClass2 + + Oh le joli design pattern. C'est cadeau. + */ + +public class CalculatorTest0 { + + + // un test pour Junit4 c'est une méthode avec l'annotation suivante devant la méthode. + @Test + public void evaluatesGoodExpression() { + Calculator calculator = new Calculator(); + int sum = calculator.evaluate("1+2+3"); + // on peut stipuler que des choses sont normalement égales (il faut charger de manière statique les Assert si on veut éviter d'avoir à écrire de quelle classe on parle) + assertEquals(6, sum); + } + + +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest1.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest1.java new file mode 100644 index 0000000..f8bed1d --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest1.java @@ -0,0 +1,18 @@ +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + CalculatorTest1 est un exemple de test pour la classe Calculator utilisant junit4. + Comment vérifier qu'on lance bien une exception? + */ + +public class CalculatorTest1 { + + + // un test pour Junit4 qui cherche à vérifier qu'il y a bien une exception + @Test(expected = NumberFormatException.class) + public void doesNotEvaluateBadExpression() { + Calculator calculator = new Calculator(); + int sum = calculator.evaluate("1 +2+3");//notez l'espace qui va génèrez une exception + } +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest2.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest2.java new file mode 100644 index 0000000..25b6590 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest2.java @@ -0,0 +1,48 @@ +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import org.junit.BeforeClass; // ne pas oublie de charger le fait qu'on veut l'annotation @BeforeClass +import org.junit.AfterClass; + +/** + + CalculatorTest2 est un exemple de test pour la classe Calculator utilisant junit4 + Il réunit en fait les deux tests des 2 classes précédentes dans une seule classe. + + Typiquement on a en effet tous les tests simples portant sur une classe "métier" regroupée dans une classe de test correspondante. + Avec les annotations, on peut factoriser des choses concernant tous ces tests. + + */ + +public class CalculatorTest2 { + static Calculator calculator; + + // On peut si on le souhaite faire un traitement avant tous les tests (typiquement on fait quelque chose de cher comme se connecter à une base de données, ici j'économise une instance de Calculator (on s'en moque un peu pour être honnête). + @BeforeClass + public static void setUp() { + System.out.println("Avant tous les tests"); + calculator = new Calculator(); + } + + @Test + public void evaluatesGoodExpression() { + System.out.println("Test evaluation bonne expression"); + int sum = calculator.evaluate("1+2+3"); + assertEquals(6, sum); + } + + + @Test(expected = NumberFormatException.class) + public void doesNotEvaluateBadExpression() { + System.out.println("Test evaluation mauvaise expression"); + int sum = calculator.evaluate("1 +2+3"); + } + + // On peut si on le souhaite faire un traitement après tous les tests (typiquement on fait quelque chose de cher comme se connecter à une base de données, ici j'économise une instance de Calculator (on s'en moque un peu pour être honnête). + @AfterClass + public static void tearDown() { + System.out.println("Après tous les Test"); + calculator = null; + } + +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest3.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest3.java new file mode 100644 index 0000000..64caf19 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/CalculatorTest3.java @@ -0,0 +1,20 @@ +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + CalculatorTest3 est un exemple de test pour la classe Calculator utilisant junit4 qui est volontairement non satisfait + + */ + +public class CalculatorTest3 { + + + @Test + public void evaluatesGoodExpression() throws Exception{ + Calculator calculator = new Calculator(); + int sum = calculator.evaluate("1+2+3"); + assertEquals(42, sum); + } + + +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/Readme.txt b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/Readme.txt new file mode 100644 index 0000000..993782c --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/Readme.txt @@ -0,0 +1,43 @@ +Les fichiers et ce qu'ils illustrent + +Calculator.java le fichier contenant la classe qu'on va prétendre couloir tester. + +CalculatorTest0.java mon premier test avec Junit4 et assert +CalculatorTest1.java mon second test avec Junit4 pour des exceptions +CalculatorTest2.java les deux précédents +CalculatorTest3.java un test volontairement non satisfait + +Jusqu'ici pour exécuter un test, on compile tous les fichiers (une fois le classpath correct) puis on fait : + +$java org.junit.runner.JUnitCore CalculatorTest0 + +voir plusieurs classes de tests suite à suite, en faisant : + +$java org.junit.runner.JUnitCore CalculatorTest0 CalculatorTest1 + +Des choses un peu plus avancées + +RunForestRun.java un exemple de runner (alternative à la ligne de commande qui fait la même chose en java). +TestParam.java mon premier test avancé permettant d'exécuter un test simple sur une liste de paramètres. +TestSuite.java comment combiner plusieurs tests (par exemple si on veut tester plusieurs classes en même temps). +AssertTests.java Squelette de toutes les variantes d'assertion proposées par Junit4 + +=== + +Pour pouvoir utiliser ces tests à bon escients, il faut : +_ avoir installé Junit4 (c'est un jar) +_ faire ce qu'il faut au CLASSPATH pour que Junit4 soit dedans. + +Par exemple sur ma machine, j'ai plusieurs versions de junit: + +$ ls -l /usr/share/java/junit* +-rw-r--r-- 1 root root 108762 mai 18 2012 /usr/share/java/junit-3.8.2.jar +-rw-r--r-- 1 root root 313072 mars 8 2016 /usr/share/java/junit4-4.12.jar +lrwxrwxrwx 1 root root 15 mars 8 2016 /usr/share/java/junit4.jar -> junit4-4.12.jar +lrwxrwxrwx 1 root root 15 mai 18 2012 /usr/share/java/junit.jar -> junit-3.8.2.jar + +Du coup, j'ai fait en sorte que mon CLASSPATH contienne /usr/share/java/junit4.jar + +$ echo $CLASSPATH +.:/usr/lib/jvm/java-8-openjdk-amd64/lib:/usr/share/java/junit4.jar + diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/RunForestRun.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/RunForestRun.java new file mode 100644 index 0000000..8626247 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/RunForestRun.java @@ -0,0 +1,24 @@ +/** + + Alternative à la ligne de commande, on peut appeller le runner depuis java avec org.junit.runner.JUnitCore.runClasses +qui retourne un objet de type Result qui modélise les résultats des tests. + +En particulier, on peut accéder à la liste des échecs -- un échec eest un objet Failure -- avec getFailures + + */ + + +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; + +public class RunForestRun { + + public static void main(String[] args) { + final Result result = org.junit.runner.JUnitCore.runClasses(CalculatorTest0.class,CalculatorTest1.class,CalculatorTest3.class); + for (final Failure failure : result.getFailures()) { + System.out.println(failure.toString()); // affiche détail sur chaque échec + } + System.out.println(result.wasSuccessful()); // affiche true ssi aucune erreurs + } +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/TestParam.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/TestParam.java new file mode 100644 index 0000000..2416862 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/TestParam.java @@ -0,0 +1,47 @@ +/** + + Example d'utilisation d'un runner spécial : Parameterized. + + Ce runner permet de facilement itérer des tests similaires sur plusieurs choix de valeurs. + + + */ +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + + +// l'annotation @RunWith propre aux runners +@RunWith(Parameterized.class) +public class TestParam { + + // l'annotation @Parameters pour aller chercher les paramètres des tests (on itère sur des tuples d'objet) + @Parameters(name = "{index}: {0} = {2}") + public static Iterable data() { + return Arrays.asList(new Object[][] { { "1+2+3", 6 }, { "40+2", 42 }, + { "001+41", 42 }, { "0000", 0 }, { "999+-999", 0 } }); + } + + // les attributs qui correspondent aux éléments de nos tuples + private String expression; + private int res; + + // le constructeur + public TestParam(String expression, int res) { + this.expression = expression; + this.res = res; + } + + // le test qui va manger les paramètres qu'on vient de définir + @Test + public void evaluatesGoodExpressions() { + Calculator calculator=new Calculator(); + assertEquals(res, calculator.evaluate(expression)); + } +} diff --git a/DEV2.1/TP10:TestsJUnit/Junit4Exemples/TestSuite.java b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/TestSuite.java new file mode 100644 index 0000000..d342de3 --- /dev/null +++ b/DEV2.1/TP10:TestsJUnit/Junit4Exemples/TestSuite.java @@ -0,0 +1,26 @@ +/** + Un runner spécial qui sert à créer une collection de tests. + Typiquement, on peut avoir une classe de tests unitaires pour chaque classe métier et une "suite de tests" qui va appeller tous les tests de classes ayant un lien (par exemple dans le même paquet). + + Ceci est de nouveau un test, qu'on peut exécuter en faisant par exemple dans une console + java org.junit.runner.JUnitCore TestSuite + + */ + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +// @RunWith permet d'indiquer le runner +@RunWith(Suite.class) + +//les tests à faire et dans quel ordre. +@Suite.SuiteClasses({ + CalculatorTest0.class, + CalculatorTest1.class, + CalculatorTest3.class +}) + +public class TestSuite { + // La classe est vide en fait + // C'est juste un conteneur pour les annotations du dessus, utilisés par Junit4 +} diff --git a/DEV2.1/TP10:TestsJUnit/junit.tar.gz b/DEV2.1/TP10:TestsJUnit/junit.tar.gz new file mode 100644 index 0000000..dff03de Binary files /dev/null and b/DEV2.1/TP10:TestsJUnit/junit.tar.gz differ