PDA

View Full Version : ditemi voi che dovrei fare...


71104
24-06-2006, 22:20
ecco un perfetto esempio del perché ci siamo bloccati:

public void testFlashGemDeleteFlashGem()
{
insertAndUpdate(createFlashingGem(), 13, 0);
insertAndUpdate(createFlashingGem(), 12, 0);
insertAndUpdate(createGem(DIAMOND), 11, 0);
insertAndUpdate(createGem(DIAMOND), 13, 7);
insertAndUpdate(createFlashingGem(), 13, 2);

insertAndDropGemsPair();
makeAllGemsFall();

controller.update(environment.getTimer().getTime());

assertNull(grid.getDroppableAt(13, 2));
assertNull(grid.getDroppableAt(13, 0));
assertEquals(grid.getDroppableAt(12, 0).getGridObject().getColor(), DIAMOND);
assertEquals(grid.getDroppableAt(13, 7).getGridObject().getColor(), DIAMOND);
}

mi vorreste spiegare che cavolo è sta porcheria? che fa? boh... ora mi trovo alle prese co sto coso che in seguito ad un mio refactoring non passa... e io secondo voi che dovrei fare? lo commento? ho già fatto praticamente una STRAGE di test commentati, io non lo so... -_-'

eh, ma qui ogni volta che il team viene richiamato all'attenzione scompaiono subito tutti e ci si blocca di nuovo... e grazie al :muro: !!
sapete che vi dico? lo commento e committo; tanto il progetto è ufficialmente chiuso, col codice possiamo farci tutto quello che vogliamo e il mio refactoring è sicuramente più utile di quel test criptico. "testFlashGemDeleteFlashGem", un nome un perché: ma per testare che una flash cancellasse un'altra flash, non bastava piazzare due flash una accanto all'altra, aggiornare e asserire? potevano essere quattro istruzioni, eh... :muro:

EDIT: a proposito, il test non passa, ma le flash cancellano ancora le flash; ditemi voi...

71104
24-06-2006, 22:26
ennò, neanche per sogno, perché il repository al momento non è up... :muro:

jappilas
24-06-2006, 23:44
...mi sa che c'è un po' di rumenta anche in testgameloop.java, ad es: le parti evidenziate di questi test, hanno senso in quel punto? :stordita:
public void testSelectVersusModeMenuItem() throws IOException
{
[.....]assertTrue("The GameLoop must be running", gameLoop.inGameLoop());

//TODO usare il mapping di config
//P1.DOWN -> KEY_S, P1.BLOW-> KEY_E
Event event = Event.create(Event.Code.KEY_E, Event.State.PRESSED);
gameLoop.getPlayerOneInput().notify(event);
assertNull("The event blow must not generate a Event", gameLoop.getPlayerOneInput().extractEvent());
}

public void testSelectAdvancedModeMenuItem() throws IOException
{
[.....]assertTrue("The GameLoop must be running", gameLoop.inGameLoop());

//TODO usare il mapping di config
//P1.DOWN -> KEY_S, P1.BLOW-> KEY_E
Event event = Event.create(Event.Code.KEY_E, Event.State.PRESSED);
gameLoop.getPlayerOneInput().notify(event);
assertNotNull("The event blow must not generate a Event", gameLoop.getPlayerOneInput().extractEvent());
}
ma per testare che una flash cancellasse un'altra flash, non bastava piazzare due flash una accanto all'altra, aggiornare e asserire? potevano essere quattro istruzioni, eh... :muro:
in teoria, direi di sì :stordita:
[mind reading mode]
in pratica , probabilmente chi ha scritto quel test voleva accertarsi che la flash desse la priorità all' altra flash senza cancellare pure la gemma e senza scrivere un altro test ... :stordita:
[/mind reading mode]

71104
24-06-2006, 23:54
bah, io sono fin troppo paziente: sono riuscito a committare senza commentare quel test; troppo paziente... -.-

^TiGeRShArK^
24-06-2006, 23:56
boh... non ho idea di cosa sia quel test... mai visto prima...
ma direi che una cosa assolutamente da fare è scrivere delle specie di "linee guida" x come testare certe cose...
ad esempio qualche volta mi è capitato di non sapere come fare un test perchè i test che facevano qualcosa simile erano completamente diversi l'uno con l'altro...
alla fine pensavo di aver capito come fare e invece...kazzi... non fungeva il test....
questo perchè con i vari refactoring mi sa che si è perso un pò "il filo" e ci sono test che usano ancora dei vecchi metodi per testare quando in realtà utilizzando i nuovi metodi aggiunti nelle varie classi sarebbero molto + semplici....

cmq... tenete duro fino a mercoledì ke finalmente potrò ricominiciare a lavorare su diamonds...
anzi... forse giovedì pure... dipende da quello ke sarà rimasto del mio cervello dopo aver studiato 8 miliardi di leggi diverse :muro:

EDIT: dimenticavo... soprattutto dovrebbe essere OBBLIGATORIO scrivere il messaggio nell'assert...altrimenti non si capisce una mazza di cosa faccia quel test...

jappilas
25-06-2006, 00:07
cmq... tenete duro fino a mercoledì ke finalmente potrò ricominiciare a lavorare su diamonds...
anzi... forse giovedì pure... dipende da quello ke sarà rimasto del mio cervello dopo aver studiato 8 miliardi di leggi diverse :muro:
ciao danilo, noi ti si aspetta speranzosi :)
però ho l' impressione che quello che deve resistere e tenere duro sia tu... mi sa che uno studio pesante più di quello che stai facendo non ci sia...
EDIT: dimenticavo... soprattutto dovrebbe essere OBBLIGATORIO scrivere il messaggio nell'assert...altrimenti non si capisce una mazza di cosa faccia quel test...
mi pare fosse anche tra i dettami di fek o vicius di un po' di tempo fa, in effetti... :stordita:

^TiGeRShArK^
25-06-2006, 00:27
ciao danilo, noi ti si aspetta speranzosi :)
però ho l' impressione che quello che deve resistere e tenere duro sia tu... mi sa che uno studio pesante più di quello che stai facendo non ci sia...
eh si lo so....:muro:
mi sono iscritto ad ingegneria per non aver NULLA a che fare con leggi et similia e ora mi ritrovo a studiare 'ste schifezze che al solo pensiero mi viene il :Puke:....
Spero solo di aver conservato un minimo di sanità mentale xkè in quest'anno mi sono letteralmente macinato il cervello e spero che siano rimasti giusto due o 3 neuroni per permettermi di riagganciarmi al team :(

e ora vado a letto ke sto scoppiando... :sob:

Bonfo
25-06-2006, 00:44
Già, i test :incazzed:

Non mi tiro fuori...anch'io a volte ho fatto porcate di test che la metà bastava.
Il problema è già venuto fuori varie volte:
http://www.hwupgrade.it/forum/showthread.php?t=1223385

Direi che i test sono da rifattorizzare tutti...e quello sarò un'altro lavoro da paura :(

71104
27-06-2006, 21:51
CHE INUMANA PORCHERIA... O_______O'''


public void testCrushesCounters()
{
insertAndUpdate(createGem(EMERALD), 13, 2);
insertAndUpdate(createGem(DIAMOND), 12, 2);
insertAndUpdate(createChest(DIAMOND), 11, 2);
insertAndUpdate(createChest(EMERALD), 10, 2);

insertAndUpdate(createGem(RUBY), 9, 2);

insertAndDropGemsPair();
makeAllGemsFall();

controller.update(environment.getTimer().getTime());

checkCountersValues(grid, 5, 1, 1);

makeAllGemsFall();

environment.getTimer().advance(
environment.getConfig().getInteger("DelayBetweenCrushes"));

controller.update(environment.getTimer().getTime());

checkCountersValues(grid, 3, 2, 2);

makeAllGemsFall();

environment.getTimer().advance(
environment.getConfig().getInteger("DelayBetweenCrushes"));
controller.update(environment.getTimer().getTime());

insertAndUpdate(createGem(DIAMOND), 13, 1);
insertAndUpdate(createChest(DIAMOND), 12, 1);

insertAndUpdate(createGem(RUBY), 11, 1);

environment.getTimer().advance(
environment.getConfig().getInteger("NewGemDelay"));
controller.update(environment.getTimer().getTime());

makeAllGemsFall();
controller.update(environment.getTimer().getTime());

checkCountersValues(grid, 6, 1, 1);
}


ma a che razza di livello è testato il codice implicato in quell'affare, qualunque esso sia...? :|

ma come può Diamond Crush contenere una cosa simile? :|

Bonfo, diciamo pure che sono da refattorizzare solo per metà: l'altra metà è da rifare -.-

71104
27-06-2006, 21:55
secondo me test come quello che ho appena sgamato e che ho quotato qui sopra sono nati in quel periodo che cercavamo di riprodurre situazioni varie per le big gems; quel test credo che cerci di riprodurre qualche assurdissima situazione in cui avevamo un bug... ma non è così che si deve fare: in queste situazioni trovare le condizioni che riproducono il bug è solo il primo passo: successivamente bisogna capire la causa del bug, ovvero quale linea di codice esattamente manca per evitarlo (o quale linea di troppo va cancellata); nel caso si debba aggiungere una linea, questa va testata nella maniera più semplice, stretta e diretta possibile, mentre nel caso se ne debba togliere una allora va rimosso anche il test che richiede la sua presenza.

cdimauro
28-06-2006, 07:39
I test non sono necessariamente legati a un bug: molto spesso rappresentano la "formalizzazione" dei requisiti richiesti (dal customer).

Comunque sono d'accordo: è un test enorme, e aggiungo che un nome più esplicativo sarebbe stato meglio. ;)

thebol
28-06-2006, 08:16
è un test che deve simulare 2 crush(con il chainCounter che cresce), e poi un altro dopo aver inserito la gemsPair(il chainCounter deve essersi resettato).

i tanti check, sono stati usati per verificare l'evolversi dei contatori.

Ho a volte trovato dei test che passavano perche testavano la condizione sbagliata, o cose simili. Per questo spesso uso piu assert, per dimostrare che prima la situazione è in un modo, e poi in un altro.(classico esempio andare a vedere se nella posizione x,y non ci deve essere la gemma, si sbagliano le coordinate e il test passa per sbaglio..)


Sicuramente si poteva fare il tutto in 2 test, ho fatto cosi, perche nel secondo avrei dovuto replicare quasi tutto il codice del primo per arrivare ad avere il chainCrush a 2(non avendo accesso al setter..)

Bonfo
28-06-2006, 09:22
è un test che deve simulare 2 crush(con il chainCounter che cresce), e poi un altro dopo aver inserito la gemsPair(il chainCounter deve essersi resettato).

i tanti check, sono stati usati per verificare l'evolversi dei contatori.

Ho a volte trovato dei test che passavano perche testavano la condizione sbagliata, o cose simili. Per questo spesso uso piu assert, per dimostrare che prima la situazione è in un modo, e poi in un altro.(classico esempio andare a vedere se nella posizione x,y non ci deve essere la gemma, si sbagliano le coordinate e il test passa per sbaglio..)


Sicuramente si poteva fare il tutto in 2 test, ho fatto cosi, perche nel secondo avrei dovuto replicare quasi tutto il codice del primo per arrivare ad avere il chainCrush a 2(non avendo accesso al setter..)

Capita spesso ... ecco perchè bisogna fare refactoring anche dei test e usare gli extract method anche nei test.
Io sono il primo che se lo scorda e preferisce la soluzione che hai usato tu. Ma se non ci abituiamo inmodo diversoil gioco si fa duro. :(

thebol
28-06-2006, 09:28
Capita spesso ... ecco perchè bisogna fare refactoring anche dei test e usare gli extract method anche nei test.
Io sono il primo che se lo scorda e preferisce la soluzione che hai usato tu. Ma se non ci abituiamo inmodo diversoil gioco si fa duro. :(

in effetti servirebbero dei metodi helper per lavorare sulla griglia(alla makeAllGemFAll()....)

cdimauro
28-06-2006, 10:03
Basterebbe spostare tanti metodi utili in un BaseTest, e far discendere i test da questa classe. ;)

thebol
28-06-2006, 10:14
Basterebbe spostare tanti metodi utili in un BaseTest, e far discendere i test da questa classe. ;)

Vero, ma ci sono dei metodi facilmente generalizzabili(makeallgemFall).

Altri meno..perche devono essere fatti in modo da lasciare pulita la griglia(senza o con la gemsPair?), e devono lasciare la griglia in uno stato ben definito(sempre lo stesso?), in modo che chi le usi dopo sappia cosa fare.

Altrimenti, si sposta solo il problema..

Bonfo
28-06-2006, 18:23
Vero, ma ci sono dei metodi facilmente generalizzabili(makeallgemFall).

Altri meno..perche devono essere fatti in modo da lasciare pulita la griglia(senza o con la gemsPair?), e devono lasciare la griglia in uno stato ben definito(sempre lo stesso?), in modo che chi le usi dopo sappia cosa fare.

Altrimenti, si sposta solo il problema..

Per me bisogna arrivare ad avere una classe di Utility per operare sulla griglia.
Ovvero nel costruttore della GridTestUtility si passa la griglia e dopo la si può settare come si pare (presenza o meno della gemsPair) ed effettuare tutte le operazioni "general-purpose" :asd:

71104
28-06-2006, 18:45
i tanti check, sono stati usati per verificare l'evolversi dei contatori. ennò, non ci siamo... se fai così vuol dire che stai testando più d'una funzionalità del programma; ogni test deve testare una sola funzionalità e lo deve fare nella maniera più diretta possibile; il TDD in forma pura (quello che faccio sempre io :p) prevede un test per ogni riga di codice, contando ovviamente solo le righe significative (non serve testare le parentesi graffe e le righe vuote insomma :p)

Ho a volte trovato dei test che passavano perche testavano la condizione sbagliata, o cose simili. Per questo spesso uso piu assert, per dimostrare che prima la situazione è in un modo, e poi in un altro.(classico esempio andare a vedere se nella posizione x,y non ci deve essere la gemma, si sbagliano le coordinate e il test passa per sbaglio..) e come mai usare più asserzioni risolverebbe la cosa...? quando scrivi i test tu non puoi partire dal presupposto che tu potresti sbagliare a scrivere il test stesso oltre al codice. a parte che non è bene scrivere numeri costanti nel codice e una delle prossime cose da fare (dopo il sistema di log, che è più urgente) sarà sostituirli tutti con costanti e formule che operano sulle costanti, ma comunque anche se sbagli a scrivere un test e questo passa i casi sono due:
1) fallisce il corrispettivo "contro-test", ovvero il test che verifica che il codice testato non solo funzioni in un certo modo, ma che non funzioni in nessun altro modo
2) a runtime ti accorgi tu stesso che il programma non funziona

Sicuramente si poteva fare il tutto in 2 test le righe di codice testate da quel test sono solo 2 escludendo parentesi graffe e righe vuote?

thebol
29-06-2006, 07:23
1) fallisce il corrispettivo "contro-test", ovvero il test che verifica che il codice testato non solo funzioni in un certo modo, ma che non funzioni in nessun altro modo

raramente fattibile.



2) a runtime ti accorgi tu stesso che il programma non funziona

togliamo i test allora? che discorso è?



le righe di codice testate da quel test sono solo 2 escludendo parentesi graffe e righe vuote?


non sempre si testano oggetti "finali". A volte si testano entita di livello un po piu alto(da gridController, a playField per esempio), e se ne testa il comportamento(magari poi realizzato da un oggetto), percui il discorso una riga un test, non è un dogma.

71104
01-07-2006, 13:02
raramente fattibile. così raramente che io lo faccio sempre. EDIT: quasi sempre :p
più fattibile di quello che pensi comunque ;)

togliamo i test allora? che discorso è? non è quello l'unico vantaggio dell'usare i test

non sempre si testano oggetti "finali". A volte si testano entita di livello un po piu alto(da gridController, a playField per esempio), e se ne testa il comportamento(magari poi realizzato da un oggetto), percui il discorso una riga un test, non è un dogma. mock

thebol
01-07-2006, 15:09
così raramente che io lo faccio sempre. EDIT: quasi sempre :p
più fattibile di quello che pensi comunque ;)

non si possono prevedere tutti i modi in cui un pezzo di codice puo funzionare(non ci vuole molto a introdurre un bug, facendo passare cmq tutti i test).


non è quello l'unico vantaggio dell'usare i test


mai detto il contrario, ma non lo vedo un vantaggio da buttar via.

mock
che testo il mock?
il mock serve nel caso inverso, quando hai un oggetto "usato" e vuoi vedere come viene usato.

Quei test, potevano essere considerati test funzionali(non ricordo la definizione esatta), cioè che testano una funzione del gioco, non una o due righe di codice.

71104
01-07-2006, 16:46
che testo il mock? ovvio che no, semplicemente lo usi... :fagiano:

i discorsi in astratto sono sterili, guarda come ho scritto i packages it.diamonds.log e it.diamonds.tests.log per capire com'è che deve essere fatto DC; nel package it.diamonds.log non c'è nemmeno un if e la massima complessità ciclomatica che puoi trovare è 2, ma solo in un metodo perché per il resto è sempre 1.

tieni presente che il package non è ancora finito, manca un ultimo pezzettino che forse richiederà un if, che sarà uno su 5 classi e non sono nemmeno sicuro che sia necessario... :rolleyes:

71104
01-07-2006, 16:54
non si possono prevedere tutti i modi in cui un pezzo di codice puo funzionare(non ci vuole molto a introdurre un bug, facendo passare cmq tutti i test). non puoi prevedere tutti i modi in cui potrà funzionare una riga di codice per il solo motivo che il dominio di valori delle variabili è virtualmente illimitato (a meno che non parliamo di booleani ovviamente :p), ma a questo si rimedia col concetto di triangolazione, e introdurre un bug senza violare coppie di test e contro-test che vanno per triangolazione è assai difficile; finora non l'ho mai visto succedere su DC, i bug che abbiamo avuto sono sempre stati per mancanza di completezza nel testare le reazioni di un metodo con tutti i possibili valori del suo dominio, o potevano essere ricondotti a tale situazione.

tuttavia ribadisco: discorso teorico == sterile