This commit is contained in:
Adrian POURCHOT 2023-05-15 10:38:18 +02:00
parent 99a3f97555
commit 4c2939df42
12 changed files with 392 additions and 0 deletions

Binary file not shown.

View File

@ -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.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
}
@Test
public void testAssertTrue() {
assertTrue("failure - should be true", true);
}
}

View File

@ -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]));
}
}

View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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<Object[]> 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));
}
}

View File

@ -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
}

Binary file not shown.