fin de séance
This commit is contained in:
commit
14851fbf4f
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.class
|
11
.vscode/settings.json
vendored
Normal file
11
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"files.exclude": {
|
||||||
|
"**/.git": true,
|
||||||
|
"**/.svn": true,
|
||||||
|
"**/.hg": true,
|
||||||
|
"**/CVS": true,
|
||||||
|
"**/.DS_Store": true,
|
||||||
|
"**/Thumbs.db": true,
|
||||||
|
"**/*.class": true
|
||||||
|
}
|
||||||
|
}
|
10
Apres.java
Normal file
10
Apres.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Apres {
|
||||||
|
|
||||||
|
}
|
19
Assert.java
Normal file
19
Assert.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/** La classe Assert définit des méthodes de vérification. Pour l'instant, la
|
||||||
|
* seule méthode de vérification est assertTrue mais d'autres pourraient être
|
||||||
|
* définies (voir JUnit).
|
||||||
|
*
|
||||||
|
* @author Xavier Crégut
|
||||||
|
* @version $Revision: 1.1 $
|
||||||
|
*/
|
||||||
|
abstract public class Assert {
|
||||||
|
|
||||||
|
/** Vérifier que la condition est vraie.
|
||||||
|
* @param condition la condition à vérifier
|
||||||
|
*/
|
||||||
|
static public void assertTrue(boolean condition) {
|
||||||
|
if (! condition) {
|
||||||
|
throw new Echec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
Avant.java
Normal file
7
Avant.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Avant {
|
||||||
|
|
||||||
|
}
|
35
CasLimitesTest.java
Normal file
35
CasLimitesTest.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/** Tester quelques cas limites.
|
||||||
|
* @author Xavier Crégut
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public class CasLimitesTest {
|
||||||
|
|
||||||
|
public void testOK() {
|
||||||
|
// OK.
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testMethodePrivee() {
|
||||||
|
throw new RuntimeException("Une méthode privée n'est pas un test !");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testMethodeProtegee() {
|
||||||
|
throw new RuntimeException("Une méthode protected n'est pas un test !");
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMethodePaquetage() {
|
||||||
|
throw new RuntimeException("Une méthode de droit d'accès paquetage n'est pas un test !");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void testMethodeDeClasse() {
|
||||||
|
throw new RuntimeException("Une méthode de classe n'est pas un test !");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAvecParametre(int a) {
|
||||||
|
throw new RuntimeException("Une méthode avec des paramètres n'est pas un test !");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAvecParametre2(int a) {
|
||||||
|
throw new RuntimeException("Une méthode avec des paramètres n'est pas un test !");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
DeviseInvalideException.java
Normal file
13
DeviseInvalideException.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/** L'exception DeviseInvalideException indique des devises incompatibles sur
|
||||||
|
* des opérations entre monnaies.
|
||||||
|
*
|
||||||
|
* @author Xavier Crégut
|
||||||
|
* @version $Revision: 1.1 $
|
||||||
|
*/
|
||||||
|
public class DeviseInvalideException extends Exception {
|
||||||
|
|
||||||
|
public DeviseInvalideException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
Echec.java
Normal file
12
Echec.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/** L'exception Echec permet de signaler l'erreur fonctionnelle d'un test.
|
||||||
|
* @author Xavier Crégut
|
||||||
|
* @version $Revision: 1.1 $
|
||||||
|
*/
|
||||||
|
public class Echec extends Error {
|
||||||
|
public Echec() {
|
||||||
|
super("condition non vérifiée");
|
||||||
|
}
|
||||||
|
public Echec(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
17
ErreurTest.java
Normal file
17
ErreurTest.java
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/** ErreurTest est un programme de test qui définit trois méthodes de test
|
||||||
|
* dont une provoque une erreur.
|
||||||
|
*/
|
||||||
|
public class ErreurTest {
|
||||||
|
|
||||||
|
public void tester1() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tester2() {
|
||||||
|
Assert.assertTrue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tester3() {
|
||||||
|
Assert.assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
FausseException.java
Normal file
3
FausseException.java
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
public class FausseException extends Exception {
|
||||||
|
|
||||||
|
}
|
147
LanceurIndependant.java
Normal file
147
LanceurIndependant.java
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L'objectif est de faire un lanceur simple sans utiliser toutes les clases de
|
||||||
|
* notre architecture JUnit. Il permet juste de valider la compréhension de
|
||||||
|
* l'introspection en Java.
|
||||||
|
*/
|
||||||
|
public class LanceurIndependant {
|
||||||
|
private int nbTestsLances;
|
||||||
|
private int nbErreurs;
|
||||||
|
private int nbEchecs;
|
||||||
|
private List<Throwable> erreurs = new ArrayList<>();
|
||||||
|
|
||||||
|
public LanceurIndependant(String... nomsClasses) {
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// Lancer les tests pour chaque classe
|
||||||
|
for (String nom : nomsClasses) {
|
||||||
|
try {
|
||||||
|
System.out.println(nom + " : ");
|
||||||
|
this.testerUneClasse(nom);
|
||||||
|
System.out.println();
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
System.out.println("Classe inconnue !");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Problème : " + e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Afficher les erreurs
|
||||||
|
for (Throwable e : erreurs) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Afficher un bilan
|
||||||
|
System.out.printf("%d tests lancés dont %d échecs et %d erreurs.", nbTestsLances, nbEchecs, nbErreurs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNbTests() {
|
||||||
|
return this.nbTestsLances;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNbErreurs() {
|
||||||
|
return this.nbErreurs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNbEchecs() {
|
||||||
|
return this.nbEchecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testerUneClasse(String nomClasse)
|
||||||
|
throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
|
||||||
|
IllegalArgumentException, InvocationTargetException, SecurityException {
|
||||||
|
// Récupérer la classe
|
||||||
|
Class<?> classe = Class.forName(nomClasse);
|
||||||
|
|
||||||
|
// Récupérer les méthodes "preparer" et "nettoyer"
|
||||||
|
Method preparer = null;
|
||||||
|
Method nettoyer = null;
|
||||||
|
|
||||||
|
for (Method method : classe.getMethods()) {
|
||||||
|
if (method.isAnnotationPresent(Avant.class)) {
|
||||||
|
preparer = method;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Method method : classe.getMethods()) {
|
||||||
|
if (method.isAnnotationPresent(Apres.class)) {
|
||||||
|
nettoyer = method;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instancier l'objet qui sera le récepteur des tests
|
||||||
|
// Object objet = classe.newInstance();
|
||||||
|
Object objet = classe.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
// Exécuter les méthods de test
|
||||||
|
Method[] methods = classe.getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if (method.isAnnotationPresent(UnTest.class)) {
|
||||||
|
if (method.getAnnotation(UnTest.class).enabled()) {
|
||||||
|
|
||||||
|
this.nbTestsLances++;
|
||||||
|
|
||||||
|
if (preparer != null) {
|
||||||
|
preparer.invoke(objet);
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<? extends Throwable> exep = method.getAnnotation(UnTest.class).expected();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (exep != FausseException.class) {
|
||||||
|
System.out.println("exep != FausseException.class");
|
||||||
|
try {
|
||||||
|
method.invoke(objet);
|
||||||
|
System.out.println(method.getName() + " : echec");
|
||||||
|
this.nbEchecs++;
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
Class<? extends Throwable> exep2 = method.getAnnotation(UnTest.class).expected();
|
||||||
|
if (e.getCause().getClass().isAssignableFrom(exep)) {
|
||||||
|
System.out.println(method.getName() + " : success");
|
||||||
|
} else {
|
||||||
|
System.out.println(method.getName() + " : erreur");
|
||||||
|
this.erreurs.add(e);
|
||||||
|
this.nbErreurs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
method.invoke(objet);
|
||||||
|
System.out.println(method.getName() + " : success");
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
if (e.getCause() instanceof Echec) {
|
||||||
|
System.out.println(method.getName() + " : echec");
|
||||||
|
this.erreurs.add(e);
|
||||||
|
this.nbEchecs++;
|
||||||
|
} else {
|
||||||
|
System.out.println(method.getName() + " : erreur");
|
||||||
|
this.erreurs.add(e);
|
||||||
|
this.nbErreurs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (java.lang.IllegalArgumentException e) {
|
||||||
|
System.out.println(method.getName() + " : erreur, pas de test avec arguments");
|
||||||
|
this.nbErreurs++;
|
||||||
|
System.out.println("d");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nettoyer != null) {
|
||||||
|
nettoyer.invoke(objet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
new LanceurIndependant(args);
|
||||||
|
}
|
||||||
|
}
|
59
Monnaie.java
Normal file
59
Monnaie.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/** La classe Monnaie est caractérisée par une valeur et une devise. Deux
|
||||||
|
* monnaies peuvent être ajoutées ou retranchées.
|
||||||
|
*
|
||||||
|
* @author Xavier Crégut
|
||||||
|
* @version $Revision: 1.1 $
|
||||||
|
*/
|
||||||
|
public class Monnaie {
|
||||||
|
private int valeur;
|
||||||
|
private String devise;
|
||||||
|
|
||||||
|
/** Initialiser une monnaie à partir de sa valeur de et sa devise.
|
||||||
|
* @param valeur valeur de la monnaie
|
||||||
|
* @param devise devise de la monnaie
|
||||||
|
*/
|
||||||
|
public Monnaie(int valeur, String devise) {
|
||||||
|
this.valeur = valeur;
|
||||||
|
this.devise = devise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Obtenir la valeur de cette monnaie.
|
||||||
|
* @param la valeur de cette monnaie
|
||||||
|
*/
|
||||||
|
public int getValeur() {
|
||||||
|
return this.valeur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Obtenir la devise de cette monnaie.
|
||||||
|
* @param la devise de cette monnaie
|
||||||
|
*/
|
||||||
|
public String getDevise() {
|
||||||
|
return this.devise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ajouter une autre monnaie à cette devise.
|
||||||
|
* @param autre l'autre devise
|
||||||
|
* @depend - <send> - DeviseInvalideException
|
||||||
|
*/
|
||||||
|
public void ajouter(Monnaie autre) throws DeviseInvalideException {
|
||||||
|
verifierMemesDevises(autre);
|
||||||
|
this.valeur += autre.valeur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Retrancher une autre monnaie à cette devise.
|
||||||
|
* @param autre l'autre devise
|
||||||
|
* @depend - <send> - DeviseInvalideException
|
||||||
|
*/
|
||||||
|
public void retrancher(Monnaie autre) throws DeviseInvalideException {
|
||||||
|
verifierMemesDevises(autre);
|
||||||
|
this.valeur -= autre.valeur;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifierMemesDevises(Monnaie autre) throws DeviseInvalideException {
|
||||||
|
if (! this.devise.equals(autre.devise)) {
|
||||||
|
throw new DeviseInvalideException("Devises incompatibles : "
|
||||||
|
+ this.devise + " et " + autre.devise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
MonnaieTest.java
Normal file
39
MonnaieTest.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/** Classe regroupant les tests unitaires de la classe Monnaie. */
|
||||||
|
public class MonnaieTest {
|
||||||
|
|
||||||
|
protected Monnaie m1;
|
||||||
|
protected Monnaie m2;
|
||||||
|
protected Monnaie m3;
|
||||||
|
|
||||||
|
@Avant
|
||||||
|
public void debut() {
|
||||||
|
this.m1 = new Monnaie(5, "euro");
|
||||||
|
this.m2 = new Monnaie(7, "euro");
|
||||||
|
}
|
||||||
|
|
||||||
|
@UnTest(enabled = false)
|
||||||
|
public void ajouter() throws DeviseInvalideException {
|
||||||
|
m1.ajouter(m2);
|
||||||
|
Assert.assertTrue(m1.getValeur() == 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UnTest
|
||||||
|
public void retrancher() throws DeviseInvalideException {
|
||||||
|
m1.retrancher(m2);
|
||||||
|
Assert.assertTrue(m1.getValeur() == -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UnTest(expected = NullPointerException.class)
|
||||||
|
public void retrancher2() throws DeviseInvalideException {
|
||||||
|
m1.retrancher(m2);
|
||||||
|
m3.ajouter(m1);
|
||||||
|
Assert.assertTrue(m1.getValeur() == 1234567890);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Apres
|
||||||
|
public void rwwwwit() {
|
||||||
|
this.m1 = null;
|
||||||
|
this.m2 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
MonnaieTest2.java
Normal file
12
MonnaieTest2.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/** MonnaieTest2 : Vérifier que les méthodes de test de la superclasse sont bien
|
||||||
|
* prises en compte !
|
||||||
|
* @author Xavier Crégut
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
public class MonnaieTest2 extends MonnaieTest {
|
||||||
|
|
||||||
|
public void testSupplementaire() {
|
||||||
|
// OK.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
UnTest.java
Normal file
9
UnTest.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface UnTest {
|
||||||
|
boolean enabled() default true;
|
||||||
|
|
||||||
|
Class<? extends Throwable> expected() default FausseException.class;
|
||||||
|
}
|
Loading…
Reference in a new issue