 
View Full Version : TDD in J2ME...sviluppare l'interfaccia test driven
Devo svilupapre un progetto J2ME...e sono sorte le prime difficoltà... La prima è il debugging, ma con EclipseME sono riuscito a fare un passo avanti riuscendo a debuggare anche le MIDLet...
Volevo sviluppare Test First un'applicazione J2ME... Il problema è che le API MIDP vanno a fare chiamate native al "cellulare" ogni volta che anche solo si instanzia una Item...
Avevo pensato a fare diversi Mock Object per le Form e le Item da immettere sulle form...
Prima di tutto faccio una FormInterface con questi metodi:
public interface FormInterface
{
    int append(Image img);
    
    int append(ItemInterface item);
    int append(String str);
    void delete(int itemNum);
    void deleteAll();
    ItemInterface get(int itemNum);
    int getHeight();
    int getWidth();
    void insert(int itemNum, ItemInterface item);
    void set(int itemNum, ItemInterface item);
    int size();
}
Poi mi faccio una classe MyForm che implementa FormInterface e estende Form...
I metodi da implementare dovranno semplicemente fare una chiamata al corrispondente metodo della API facendo un cast al tipo Item...
Poi creo una classe MockForm che implementa l'interfaccia FormInterface...di fatto questo MockForm è una semplice collection...
Quello che mi "puzza" è ItemInterface... ItemInterface è un'interfaccia che è praticamente identica a quella di Item...
Il problema a questo punto è che per qualsiasi Item XXXXX che voglio inserire nella Form devo:
- creare XXXXXInterface che estende ItemInterface
- creare MyXXXXX che estende XXXXX e implementa XXXXXInterface (i metodi dell'interfaccia sono già implementati da XXXXX)
- creare MockXXXXX che implementa l'interfaccia XXXXXInterface (tutti i metodi del mock vanno implementati e devono simulare il funzionamento dell'item)
La cosa mi sembra abbastanza complicata...cosa ne pensate ? C'è un modo più veloce ?
Sicuramente l'implementazione dei metodi potrebbe essere minimale (tanto per chiarire molti dei metodi di Item non credo di doverli implementare)...o comunque implementerei gli altri metodi solo al momento in cui mi servirebbero nel codice...
Pensavo che esistessero delle librerie che "simulavano" il funzionamento di un cellulare senza fare il deploy dell'applicazione sul simulatore...
theClimber
29-04-2006, 10:48
Volevo sviluppare Test First un'applicazione J2ME...
Lodelvole iniziativa, ci sono passato ma non e' affatto banale. E' un progetto con scopi  "didattici" o sviluppi una vera applicazione? 
Provo a spiegare qualcosa di quello che ho sperimentato, penso sia abbastanza interessante, anche se non e' tutto collegato al TDD.
Il problema è che le API MIDP vanno a fare chiamate native al "cellulare" ogni volta che anche solo si instanzia una Item...
Le api MIDP spesso non sono facilmente mockabili,con implementazioni final di classi e metodi. Questi metodi, di cui non e' possibile fare override, spesso sono proprio quelli che chiamano funzioni native (storage e display..). Una soluzione e' quella di wrappare tutto con classi e interfacce di adapter, ma questo e' problematico (Vedi sotto).
Un alternativa e' quella di usare tecniche di Aspect Oriented programming (aspectj in particolare) per istrumentare il codice (i .jar) delle librerie J2ME e rimpiazzare metodi e classi con implementazioni mock. Occhio che non e' assolutamente possibile distribuire i jar J2ME modificati per questioni di licenza.
Avevo pensato a fare diversi Mock Object per le Form e le Item da immettere sulle form...
L'applicazione dovra' mai funzionare su veri device? di che tipo ? 
Tieni presente che per applicazioni vere, il numero di interfacce, classi, metodi è da minimizzare specie se i dispositivi finali hanno limitazioni sulla dimensione delle midlet. Questo spesso obbliga a compromessi nel design (dello stesso tipo di quelli visti nelle API MIDP  :cry:  :cry: ). Ti butto li tre trucchi banali che sono praticamente un Must per guadagnare memoria da dedicare al "design" dell'applicazione:
 Tutte le classi devi farle nel package di default, se le metti in un altro package occupano memoriaù
 Offusca il codice, i metodi ed i campi diventano piu' corti
 Non usare mai getter e setter 
 Minimizza le classi. In un applicazione normale se ci sono due responsabilita' collegate faresti 2 classi nello stesso package che collaborano. In J2ME fai una sola classe!
Spesso mi sono trovato a dover mantenere un delicato equilibrio tra astrarre e ripulire il design e dover procedere ad inlining di metodi dove necessario.
Pensavo che esistessero delle librerie che "simulavano" il funzionamento di un cellulare senza fare il deploy dell'applicazione sul simulatore...
Il wireless toolkit della sun lo usi? http://java.sun.com/products/sjwtoolkit/
Alcune case produttrici forniscono tool specifici (Mi viene in mente Nokia, se ti iscrivi al loro sito di dev, o motorola ...), ma spesso sono solo modifiche minimali al WTK sun.
Comunquei tool di questo tipo non sono poi cosi' utili. In un progetto che ho seguito la fase di sviluppo e test sui device e' durate anche 4/5 volte piu' lunga della fase in cui abbiamo usato gli emulatori ed ha portato ad un drastico redesign che ha rimosso molti dei layer di astrazione utilizzati. I problemi sono vari:
 Non tutti i device supportano correttamente le API J2ME (Esempio: Mi e' capitato di dover wrappare il layer di accesso allo storage in un package parallelo perche' alcuni device avevano problemi di concorrenza, nonostante le API "ufficiali" della piattaforma indicavano i metodi come synchronized). In questi casi ci si gioca la memoria disponibile per creare un layer di astrazione "indispensabile" anche se teoricamente inutile. NOTA: emulatori specifici rilasciati dal produttore del device OVVIAMENTE non avevano questo problema
 E' complesso tracciare il comportamento in esecuzione su device senza strumenti specifici, e non sono facili da avere. In alcuni casi sono stato costretto ad usare un framework per loggare tramite chiamate di rete
 Hai un modo per deployare le midlet sul device? non tutti i dispositivi permettono un upload via cavo o infrarosso, potrebbe essere necessario fare un download da rete.
 Se devi supportare device multipli, specie se con diverse versioni delle specifiche J2EE, ti può essere utilie un precompilatore per fare include condizionato di segmenti di codice(Vedi il progetto antenna con alcuni tools utili: http://antenna.sourceforge.net/) 
 
Ciao
Il progetto è per scopi didattici e lo volevo provare almeno sul mio cellulare (LG 8330), ma viste le difficoltà credo che mi appoggerò al debugger e mi limiterò a sviluppare Test First la logica anche se questo probabilmente mi imporrrà un aumento del numero di classi...
Chiaramente non volevo fare un Mock per tutto, ma mi sarei limitato solamente a quei componenti che avrei usato...
Un alternativa e' quella di usare tecniche di Aspect Oriented programming (aspectj in particolare) per istrumentare il codice (i .jar) delle librerie J2ME e rimpiazzare metodi e classi con implementazioni mock. Occhio che non e' assolutamente possibile distribuire i jar J2ME modificati per questioni di licenza.
Però una volta fatto questo lavoro in teoria sarebbe trasportabile su tutti i progetti...ma da come dici sembra che non ci sia nemmeno speranza di trovarli in giro  :muro: 
L'applicazione dovra' mai funzionare su veri device? di che tipo ? 
Tieni presente che per applicazioni vere, il numero di interfacce, classi, metodi è da minimizzare specie se i dispositivi finali hanno limitazioni sulla dimensione delle midlet. Questo spesso obbliga a compromessi nel design (dello stesso tipo di quelli visti nelle API MIDP  :cry:  :cry: ). Ti butto li tre trucchi banali che sono praticamente un Must per guadagnare memoria da dedicare al "design" dell'applicazione:
 Tutte le classi devi farle nel package di default, se le metti in un altro package occupano memoriaù
 Offusca il codice, i metodi ed i campi diventano piu' corti
 Non usare mai getter e setter 
 Minimizza le classi. In un applicazione normale se ci sono due responsabilita' collegate faresti 2 classi nello stesso package che collaborano. In J2ME fai una sola classe!
Spesso mi sono trovato a dover mantenere un delicato equilibrio tra astrarre e ripulire il design e dover procedere ad inlining di metodi dove necessario.
Grazie per i suggerimenti...tutto interessante e utile (anche se non mi piace  :cry: )
Il wireless toolkit della sun lo usi? http://java.sun.com/products/sjwtoolkit/
Sì...certo... Mi riferivo alla possibilità che le mie classi JUnit si appoggiassero direttamente al "layer" dell'emulatore che "riceve" le chiamate native... Esistono delle EmptyAPI nel WTK22, ma sono proprio Empty, nel senso che se metto una stringa in una StringItem e dopo la recupero, mi ritorna null...
Alcune case produttrici forniscono tool specifici (Mi viene in mente Nokia, se ti iscrivi al loro sito di dev, o motorola ...), ma spesso sono solo modifiche minimali al WTK sun.
Comunquei tool di questo tipo non sono poi cosi' utili. In un progetto che ho seguito la fase di sviluppo e test sui device e' durate anche 4/5 volte piu' lunga della fase in cui abbiamo usato gli emulatori ed ha portato ad un drastico redesign che ha rimosso molti dei layer di astrazione utilizzati. I problemi sono vari:
Purtroppo questo lo so...ma mi limiterò alla compatibilità con un solo device...
Hai un modo per deployare le midlet sul device? non tutti i dispositivi permettono un upload via cavo o infrarosso, potrebbe essere necessario fare un download da rete.
L'ho già hackato ;) Ora lo permette...
La cosa che più mi ha stupito di J2ME è l'assoluta assenza di VM per PALMARI... Tranne in rari casi (alcuni modelli HP), la VM non viene distribuita con il palmare e si trova solo a pagamento (IBM J9 ad esempio)...
Comunque ti ringrazio per i suggerimenti...ora saprò a chi rivolgermi  :D
Ah...l'idea era di realizzare una shell remota... Mi sono già fatto uno spike per la parte server e sono risucito a controllare perfettamente stdin e stdout da Java... Ora devo fare uno spike sul cellulare... Credo che il problema amggiore sarà il numero di righe di output che può contenere anche un semplice "ls" o "dir"... Dovrò studiarmi un metodo per gestirmi il buffer di queste righe (credo che anche la dimensione delle righe bufferizzate sarà determinante) e come farle "scorrere" sul dispositivo mobile...
theClimber
29-04-2006, 13:15
Su alcuni LG ho fatto qualche prova, per un esperimento sulle API Push Registry (http://developers.sun.com/techtopics/mobility/midp/articles/pushreg/), prova a vedere se il tuo modelle la supporta. Io l'ho utilizzata per installare una midlet che si risveglia quando riceve comandi telnet. La cosa positiva degli LG e' che hanno dato meno rogne dei motorola. 
Per le liberie instrumentate con AOP, per riusarle in modo efficace su piu' progetti lo sforzo non e' banale. Se non sei piu' che esperto di aspectj e' meglio partire con casi e situazione specifiche, e piano piano riutilizzare la conoscenza.
Ciao
Consoco il Push Registry, ma dimmi una cosa... Come si fa a ricevere una connessione entrante se tutti i cellullari sono dietro ad un proxy (o almeno mi sembra) ?
theClimber
29-04-2006, 22:05
Ci sono varie modalita di connessione per Push registry. Quello che dici è corretto se si vogliono usare datagram UDP o connessioni TCP; un questo caso devi essere sulla stessa rete IP del device, quindi su un server dell'operatore che ti ha fornito l'IP. 
Questa soluzione va bene per applicazioni/servizi dell'operatore che vogliono attivare una midlet.
C'e' un alternativa, ed è quella di attivare il push registry con un SMS. La midlet quindi si attiva ed apre la connessione di dialogo in direzione opposta.
Sapevo degli SMS, ma mi imporrebbe di mettere un cellulare anche sul server...
Riguardo alla rete interna fra gli apparecchi collegati allo stesso operatore...hanno un indirizzo ip privato assegnato ? Sai come si potrebbe recuperare l'indirizzo ip privato assegnato ? Mi viene in mente una cosa interessante  :D Anche se mi immagino che una connessione diretta cellulare-cellulare sia impossibile...
theClimber
30-04-2006, 21:52
Anche a me era passata per la testa l'idea della connessione Cell-Cell. In linea di principio potrebbe funzionare, i cellulari che si registrano hanno un indirizzo IP assegnato, e rispondono al ping! Se non funziona è dovuto a configurazioni particolari della rete che bloccano connessioni che non vanno sui server di gateway.
Non so pero' dirti come recuperare IP direttamente da cellulare. Magari con dei nokia 6630 o 6680, che sono simbian, si puo' installare qualche SW e scoprire l'indirizzo IP.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.