|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
Mi sono esercitato :D (NullSound inside)
Ho deciso di esercitarmi un po' stamattina prima di studiare (
![]() ![]() Così ho deciso di creare l'infausta "NullSound" che manca per risolvere il bug del crash col device audio occupato. Ecco cos'ho fatto. Come fek mi ha insegnato ho creato due test paletto che segnano la fine del task (ammetto di averli scopiazzati un po' su quelli della NullAudio) : Codice:
TestEnvironment.java public void testSoundCreationFromNullAudio() { AudioFactory audioFactory = new FailingAudioFactoryMock(); environment.createAudio(audioFactory); Sound sound = environment.getAudio().createSound("diamond"); assertTrue(sound.isNull()); } public void testSoundCreationFromNonNullAudio() { AudioFactory audioFactory = new MockAudioFactory(); environment.createAudio(audioFactory); Sound sound = environment.getAudio().createSound("diamond"); assertFalse(sound.isNull()); } ![]() Codice:
public class TestNullSound extends TestCase { public void testNullSound() { Sound sound = new NullSound(); assertTrue(sound.isNull()); } public void testNullSoundPlayed() { Sound sound = new NullSound(); assertFalse(sound.wasPlayed()); sound.play(); assertTrue(sound.wasPlayed()); } public void testNullSoundPlayedReset() { Sound sound = new NullSound(); sound.play(); sound.reset(); assertFalse(sound.wasPlayed()); } public void testNullSoundPlayedFreeMemoryReset() { Sound sound = new NullSound(); sound.play(); sound.freeMemory(); assertFalse(sound.wasPlayed()); } public void testReturnNullSoundNameNull() { Sound sound = new NullSound(); sound.getName().equals("null"); } } Il risultato di tutta questa trafila di tests , oltre all'aggiunta della "isNull()" in Sound.java, OpenALSound.java, MockSound.java, è stata la creazione di una classe NullSound.java che ha questo codice : Codice:
public class NullSound implements Sound { private boolean wasPlayed = false; public void freeMemory() { wasPlayed = false; } public Object getName() { return "null"; } public void play() { wasPlayed = true; } public void reset() { wasPlayed = false; } public boolean wasPlayed() { return wasPlayed; } public boolean isNull() { return true; } } ![]() Alla fine ho scommentato i due tests finali che avevo creato e lanciandoli ho constatato che non fallivano ... questo immagino significhi che ho fatto qualcosa di ridondante , vero? ![]() Il risultato finale è comunque che il programma non crasha più. Non ho committato, aspetto i commenti di chi è più esperto con il test-driven che mi dica se ho fatto cavolate ![]() Ciao
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
In due ore ieri sera ho creato un mostro ![]()
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2005
Città: Bologna
Messaggi: 1303
|
|
![]() |
![]() |
![]() |
#5 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
c'è qualcosa che non mi convince
![]() in Sound e derivate i metodi getName e isNull vengono usati solo dai test; stessa cosa per i metodi isCreated e isNull di Audio e derivate. dobbiamo eliminarli? ![]() e se proprio dobbiamo tenerli io francamente quel getName lo convertirei in toString, per amor di Java ^^ inoltre in Audio e derivate c'era un metodo isInitialised (scritto pure male visto che si dice initialized ![]() |
![]() |
![]() |
![]() |
#6 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
segnalo altri metodi utilizzati esclusivamente dai test: Sound.wasPlayed, Audio.isMusicPlaying.
fek, in generale dicci come dobbiamo comportarci quando vediamo situazioni simili (metodi usati solamente dai test). io sono per l'eliminazione e il testing di quelle funzionalità in altre maniere ![]() sono dell'idea che il TDD non debba causare l'aggiunta di codice che non sarebbe stato messo in un ipotetico sviluppo untested, perché altrimenti significa che il TDD incrementa la quantità di codice causando danni oltre che benefici. il massimo che si potrebbe accettare sono metodi come i vari createForTesting statici (sono delle sorte di costruttori alternativi). Ultima modifica di 71104 : 26-01-2008 alle 23:56. |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
Quote:
Comunque credo già di sapere la risposta di Fran (che ci arriverà dopo il fine settimana). Penso lui preferisca avere tutte le classi perfettamente testate e coi metodi di test piuttosto che classi più "economiche" in fatto di metodi , ma meno testate, o che comunque iniziano a creare eccezioni dalla via del TDD. Penso che la paura sia che se si inizia con le eccezioni al TDD alla ricerca di un improbabile incremento dell'efficienza si possa finire nel baratro , come tra l'altro mi sembra sia già successo in passato al progetto. Dopotutto si parla dell'aggiunta di qualche metodo che alla fine non viene mai chiamato nel codice di produzione e che quindi il compilatore dinamico non perde tempo a compilare in fase di esecuzione. L'unico svantaggio può essere l'incremento della dimensione dei .class , ma visti i tipi di funzioni (più che altro getter) direi che l'incremento può essere al massimo di qualche kilobyte. Quindi IMHO non vale la pena cercare di piallare via questi metodi, che tra l'altro si potrebbero anche rivelare utili in futuro e caratterizzano bene gli oggetti in questione (chissà quando potrebbe essere necessario sapere se la musica è in riproduzione o se l'oggetto Audio o Sound instanziato è null o meno). Ciao
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
TUTTI i metodi usati in produzione DEVONO avere ALMENO un test che li eserciti e ben più d'uno nel caso in cui abbiano parametri e/o dipendenze da altri valori, come variabili d'istanza o di classe: si deve, insomma, formalizzare il "contratto" fra chiamante e chiamato.
Se ci sono metodi NON di test (quindi esposti pubblicamente) e NON usati nel codice di produzione io sono per la loro eliminazione seduta stante. YAGNI!
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
![]() |
![]() |
![]() |
#9 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
|
|
![]() |
![]() |
![]() |
#10 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
![]() Ultima modifica di 71104 : 27-01-2008 alle 11:19. |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
Quote:
E infatti io ho scritto che l'unico svantaggio può essere l'aumento della dimensione dei file .class AL MAX di qualche KB (tutti insieme intendo ![]() Quei metodi però hanno il merito di specificare con chiarezza il contratto della classe e di specificare quindi le funzionalità che questa deve avere. Insomma, non credo valga la pena toglierli, inoltre mi sembra che nei test vengano usati (perlomeno isMusicPlaying() di AudioInterface che è l'unico che mi ricordo così sull'unghia) Ciao
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#12 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
ricordo ancora la prima volta che io scrissi dei metodi che rimasero utilizzati solo dai test: era il task per l'implementazione della classe che mostra i punteggi. fek mi disse di togliere (o rendere privati) quei metodi e di testare in altra maniera; quella volta imparai cos'è il Black Box Testing.
altra cosa che ho imparato: mai cercare di indovinare le decisioni di fek ![]() per questo gli ho anche chiesto in generale cosa fare in situazioni del genere, così diventiamo autonomi e non dobbiamo più aspettare che lui legga il forum; anche se in realtà, memore di quando scrissi la famosa classe Number, credo di sapere cosa risponderà. |
![]() |
![]() |
![]() |
#13 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
|
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
Quote:
![]()
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Gli altri metodi (non di produzione) teoricamente non dovrebbero nemmeno esistere, per cui o si trova il modo di toglierli di mezzo, oppure dovrebbero stare soltanto sugli oggetti di test. Sempre se possibile, eh!
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Dec 2000
Città: bologna
Messaggi: 1309
|
se un metodo pubblico non di produzione rende (molto) più semplice scrivere i test per me può rimanere. Ad esempio testare un componente che controlla qualcosa di basso livello(che si assume funzioni) andando a controllare questo componente cosa fà(scrive sul buffer audio della scheda audio?) non è sempre obbligatorio.
Certo si può fare con un mock, passando il mock al nostro componente, e verificare che faccia le chiamate giuste(ci sarà il mock ad ascoltarle). Ma non è piu blackboxtesting, e secondo me ci si lega troppo all'implementazione.(può comunque valer la pena farlo in certe occasioni, magari per test di integrazione). |
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
Il secondo principio e' l'interfaccia pubblica di una classe dev'essere il piu' semplice e minimale possibile: quindi se si puo' eliminare un metodo dall'interfaccia pubblica in maniera semplice, va fatto (senza infrangere il principio primo ovviamente). Il terzo principio: non mi interessa alcuna considerazione prestazionale fino a che qualcuno non mi porta dati concreti che mostrano un problema concreto. E dubito fortemente questo accadra' in Diamonds.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:35.