• Aucun résultat trouvé

Fonctionnalit´e 2 : cr´eation des r`egles d’´epargne et de d´epense

5.3 Campagnes de test

5.3.2 Fonctionnalit´e 2 : cr´eation des r`egles d’´epargne et de d´epense

L’utilisateur a la possibilit´e d’enregistrer diff´erentes r`egles d’´epargne et de d´epense.

Plu-sieurs param`etres entrent en compte lors de la cr´eation d’une r`egle et une r`egle n’est cr´e´ee

1 import java.util.* ;

import java.lang.* ;

import java.io.* ;

import junit.framework.TestCase;

5 import org.jmlspecs.jmlrac.runtime.*;

import banking.*;

public class TestCreationSimple extends TestCase {

AccountMan_src CentralBancaire;

10 Balances_src Solde;

/**

* setUp() est une m´ethode appel´ee avant chaque

* appel `a une m´ethode de test.

15 * Nous l’utilisons donc pour r´einitialiser le syst`eme

* sous test en recr´eant les instances requises.

*/

protected void setUp(){

CentralBancaire=new AccountMan_src();

20 Solde=new Balances_src(CentralBancaire);

}

/**

* testSequence_0() correspond `a un cas de test.

25 * Ici on cr´ee un compte avec pour valeur 0, "bnp" et

* FLOAT.MAX_VALUE. Puis on affiche r´ecup`ere le solde

* `a l’aide de la m´ethode getBalances(x).

* Une exception est lev´ee si une assertion JML est viol´ee.

*/

30 public void testSequence_0(){

try {

CentralBancaire.BOcreate(0, "bnp", Float.MAX_VALUE);

Solde.getBalances(0);

} //precondition viol´ee

35 catch(JMLEntryPreconditionError e$) {

System.out.println(e$.getMessage());

} //postcondition, invariant, pr´econdition interne viol´ee

catch(JMLAssertionError e$){

int l$ =JMLChecker.getLevel();

40 JMLChecker.setLevel(JMLOption.NONE);

try { //demande `a JUnit d’afficher un fail.

junit.framework.Assert.fail("\n\t"+e$.getMessage());

} finally {

JMLChecker.setLevel(l$);

45 }

}

}

}

que si les param`etres satisfont certaines conditions. Voici les sp´ecifications informelles des

op´erations permettant d’enregistrer des r`egles d’´epargne (saving rule) et de d´epense

(spen-ding rule) :

public registerSavingRule(date in string, account in integer, threshold in real,

saving_account in integer, period in integer)

return integer

“Cette m´ethode permet d’enregistrer une nouvelle r`egle de transfert automatique d’un compte

(account) vers un compte d’´epargne (saving account) si le compte dispose d’une balance

sup´erieure `a un seuil (threshold). Cette r`egle doit ˆetre test´ee suivant une certaine p´eriodicit´e

(period). Une fois que la r`egle est enregistr´ee, elle sera ex´ecut´ee dans t0+period. Si un des

pa-ram`etres n’est pas conforme alors, soit une exception de type BadParameterException (type)

est lanc´ee, soit un code d’erreur est retourn´e (type). Le seuil est positif ou nul, sinon le

code d’erreur 04 est retourn´e. Si la p´eriode est nulle ou n´egative le code d’erreur 06 est

re-tourn´e. Si account ou saving account ne sont pas des comptes valides le code d’erreur 03 est

retourn´e.”

public registerSpendingRule(date in string, account in integer, threshold in real,

saving_account in integer, period in integer)

return integer

“Cette m´ethode permet d’enregistrer une nouvelle r`egle de transfert automatique d’un compte

d’´epargne (saving account) vers un compte courant (account). Si le montant du solde du

compte d´esign´e par la variable account est inf´erieure `a la valeur de la variable threshold et

si le solde du compte d´esign´e par la variable saving account le permet, une somme d’argent

est transf´er´ee du deuxi`eme compte vers le premier. Le montant de cette somme doit faire en

sorte que le solde du compte d´esign´e par account soit ´egal `a la valeur de la variable threshold.

Toutefois, si le solde du compte d´esign´e par la variable saving account ne permet pas que le

solde du compte d´esign´e par la variable account soit ´egal `a la valeur de la variable threshold

alors le transfert n’a pas lieu. Cette r`egle doit ˆetre ´evalu´ee `a chaque instant correspondant

aux intervalles de temps period, exprim´e en secondes. D`es que la r`egle est enregistr´ee, elle

est activ´ee `a t0+period. Le seuil est positif ou nul, sinon le code d’erreur 04 est retourn´e.

Si account ou saving account ne sont pas des comptes valides si, le code d’erreur 03 est

re-tourn´e. Si la p´eriode est n´egative, le code 06 est rere-tourn´e.”

Dans un premier temps, nous avons choisi de tester les cas pouvant poser probl`eme pour

ces deux r`egles. Pour ´eviter les probl`emes d’explosion combinatoire dus au nombre important

de param`etres, nous avons effectu´e un d´ecoupage par type d’erreur. Nous avons donc produit

un sch´ema de tests permettant de v´erifier qu’une r`egle n’est pas enregistr´ee si le seuil indiqu´e

est incorrect.

La trame qui nous a servi `a cr´eer ce sch´ema est la suivante : un transfert doit s’effectuer

entre deux comptes diff´erents. Ces deux comptes peuvent appartenir `a la mˆeme personne ou

`a deux personnes diff´erentes et ˆetre situ´es dans la mˆeme banque ou des banques diff´erentes.

Il nous faut, de plus, v´erifier que la r`egle a bien ´et´e cr´e´ee lorsqu’elle doit l’ˆetre : lorsque

les comptes de d´epart et d’arriv´ee sont valides (qu’ils existent), que la p´eriode (positive)

et la date (chaˆıne repr´esentant bien une date) sont valides ainsi que le montant (positif).

Nous devons v´erifier, dans le cas contraire, qu’elle n’a pas ´et´e cr´e´ee. Lorsque la r`egle est

enregistr´ee, nous voulons qu’elle soit ex´ecut´ee et pour cela nous avons fix´e une p´eriode la

plus courte possible. Nous souhaitons alors v´erifier le solde des comptes pour nous assurer que

les transferts s’effectuent correctement. `A partir de l`a, nous avons cr´e´e diff´erents groupes :

BOcreate_Gr1 = {AccountMan_src.BOcreate(cust_id, bn, balance)} avec :

cust_id ∈ {1}

bn ∈ {"bnp"}

balance∈ {100}

BOcreate_Gr2 = {AccountMan_src.BOcreate(cust_id, bn, balance)} avec :

cust_id ∈ {1,2}

bn ∈ {"bnp", "ce" }

balance∈ {100}

RegisterRuleSeuil_Gr1 = {

Transfers_src.registerSavingRule(date, account, threshold1,

saving_account, period),

Transfers_src.registerSpendingRule(date, account, threshold2,

saving_account, period)

} avec :

date ∈ {"foo"}

account ∈ {11}

threshold1 ∈ {-12.0f, 0.0f, 0.1f, 99.7f, 100.7f, 150.0f,

325.0f}

threshold2 ∈ {-12.0f, 0.0f, 0.1f, 99.7f, 100.0f, 100.1f,

150.0f, 325.0f}

saving_account ∈ {12}

period ∈ {1}

Print1 = {Balance_src.PrettyPrintBalances(cust_id)} avec

cust_id ∈ {1}

Print2 = {Balance_src.PrettyPrintBalances(cust_id)} avec

cust_id ∈ {2}

Comme aujourd’hui nous ne poss`edons pas de moyen simple, dans le langage de sch´ema

de tests, pour r´ecup´erer les valeurs retourn´ees par les appels de m´ethode, nous devons les

anticiper. Ainsi, comme nous savons que le premier compte cr´e´e aura comme num´ero “11” et

le second comme num´ero “12”, nous les avons directement inject´e dans les valeurs possibles

des param`etresaccount et saving account. Il est ´evident qu’il est important de fournir un

m´ecanisme permettant de r´ecup´erer simplement des r´esultats de fonctions pour les r´einjecter

dans des appels ult´erieurs 1. Ce manque nous fait perdre en flexibilit´e car, si le code de

l’ap-plication change, nous devons penser `a changer les valeurs d´efinies dans les groupes, et en

1

Il est n´eanmoins possible de contourner ce probl`eme en d´efinissant, pour le test, des m´ethodes type “set”

et “get” permettant, respectivement, de stocker le r´esultat d’un appel de m´ethode et de le r´ecup´erer.

puissance d’expression.

Les valeurs qui ont ´et´e d´efinies pour les seuils visent `a v´erifier que seuls les seuils n´egatifs

ou nuls sont invalides et n’entraˆınent pas l’enregistrement de la r`egle. Nous v´erifions de plus