Friday, 11 June 2010

Importanza test

Importanza test

Vi sottopongo un caso reale in cui si potrebbe creare un bug.

Carlo
  • Modifica la lettura dei messagi di SALKI inserendo un semplice if-then-else del tipo: se il messaggio inizia con 'B' leggi in un modo altrimenti leggi nel modo consueto.
  • In fretta si implementa la modifica per fare delle prove e dopo un po di tentativi funziona.
  • Risolto il problema urgente Carlo dovrebbe chedere a Fabio di inserire nei dati di test un caso che faccia scattare la nuova lettura per metterla sotto test. Alla fine per non perdere tempo, tanto la modifica e' banale ed e' stata provata a mano, decide di soprassedere. Una riga di programma rimane non testata.
  • Lancia i test e passano.....

Passano i giorni, la modifica e' finita nella versione ufficilale del sw usato da tutti.

Qualcuno DBL
  • Per qualche motivo cambia la codifica del messaggio (invece di B, C) per fare magari una prova al volo e la modifica finisce nella versione "ufficiale" del sw DBL.

Qualcuno JAVA
  • Riprende il sw ufficiale con la nuova lettura, non sapendo magari che e' stata fatta, perche riprende tutto il sw senza guardare le modifche per mancanza di tempo (cosa che avviene sempre da parte di tutti)
  • Lancia i test e passano... tutto OK pensa!
  • Fa delle modifche urgenti alla UI, magari toccando la visualizzazione proprio dei campioni.
  • Lancia AlcXXX in ditta e tutto funziona perfettamente perche' casualmente riprende dei dati che non fanno scattare il nuovo tipo di lettura.
  • Installa la procedura dal cliente con rete lenta etc, perdendo diverse ore...
  • Cliente inizia ad usarla e funziona...

Passa qualche giorno....
  • Cliente la usa pesantemente e chiama un campione con molte prove che fa scattare il nuovo tipo di lettura.
  • Applicazione si pianta perche la lettura nuova non coincide piu' con la gestione DBL
  • Qualcuno JAVA va in panico!?!?!  Dov'e il problema? UI crashia perche' la modifica che ho fatto di recente ha un bug? Problema della persistenza? Versione del seerviizo non corrispondente? BOH!!!!
  • Intanto il programma magari e' stato scaricato nel frattempo su molte postazioni e web start ancora non aggiorna bene in automatico come dovrebbe...
  • Qualcuno JAVA deve capire il problema, una volta individuato risolvero da solo o con altri, rifare il deploy del programma, ritrasferirlo, aggiornare le postazioni che hanno preso la versione non funzionante (alcune postazioni magari se ne accorgono giorni dopo...)

In conclusione: per non aver perso 15min? 30min? !1h? per creare il caso, si perdono diverse ore, con in piu' stati d'animo alterati, figura non molto bella presso il cliente (che essendo pubblico si arrabbia poco, ma se fosse un privato...)

Wednesday, 9 June 2010

XP programming


XP e' un metodologia  "leggera" per teams di dimensioni medio-piccole che sviluppano software avendo requisiti vaghi o che cambiano rapidamente.

A molti XP puo' sembrare una metodologia basata sul buon senso. Allora perche il termine X = estremo P = programmazione?
La risposta e' che XP porta questi principi di buon senso ad estremi livelli.

Cioe':
  • Se la revisione del codice e' una buona cosa, revisioneremo il codice di continuo (pair programming = programmazione tra pari = io rivedo il tuo codice, tu rivedi il mio)
  • Se testare e' una buona cosa, tutti testeranno sempre (unit testing), anche con i clienti (test funzionale).
  • Se la progettazione e' una buona cosa, essa fara' parte dell'attivita' giornaliera di ciascuno (refactoring)
  • Se la semplicita' e' una buona cosa, faremo in modo di lasciare il sistema con il piu' semplice progetto che implementa la funzionalita' correntemente richiesta (la cosa piu' semplice che possa funzionare).
  • Se l'architettura e' importante, ogniuno lavorera' definendo e affinando l'architettura di continuo (metaphor = metafora)
  • Se i test di integrazione (test i vari pezzi del programma insieme: es. WS + FileExServer + DBL) sono importanti allora integreremo e testeremo diverse volte al giorno (CI = continuos integration)
  • Se iterazioni di rilascio del sf brevi sono una buona cosa, faremo le iterazioni molto, molto corte - secondi, minuti e ore, non settimane, mesi e anni (Planning game = gioco della pianificazione)

Adozione di XP dovrebbe portare i seguenti benefici:

Ai programmatori:
  • Saranno in grado di lavorare sempre su cose veramente importanti, ogni giorno.
  • Non dovranno affrontare situazioni pericolose da soli.
  • Saranno in grado di fare ogni cosa in loro potere per portare il sistema al successo
  • Prenderranno le migliori decisioni che possono prendere
  • Non prenderanno decisioni che non sono i piu' qualificati a prendere

Ai clienti e manager:
  • Avranno il massimo risultato possibile da ogni settimana di lavoro.
  • Ogni settimana vedranno concreti progressi sugli obbiettivi a loro cari
  • Potranno cambiare direzione al progetto nel mezzo dello sviluppo senza incorrere in costi esorbitanti

In sinstesi XP promette di:
  1. ridurre il rischio del progetto: non portarlo a termine affatto o di non soddisfare le richieste del cliente
  2. migliorare la produttivita' per tutto il ciclo di vita del sistema
  3. sviluppare divertendosi in gruppo

Ancora su cosa e' XP:
  • E' avere un feedback anticipato, concreto e continuo dall'adozione di cicli brevi
  • E' una pianificazione incrementale la quale fornisce in poco tempo un piano generale che evolvera' durante il ciclo di vita del progetto
  • Ha la possibilita' di schedulare in modo flessibile nuove funzionalita' per rispondere ai cambiamenti delle richieste del cliente
  • Si basa su test automatizzati scritti dai programmatori e dai clienti per controllare il generale avanzamento dello sviluppo, per consentire al sistema di evolversi e scovare in anticipo i difetti.
  • Si basa sulla comunicazione orale, tests, e sorgenti per comunicare la struttura del sistema e intenti.
  • Si basa su una progettazione continuativa che dura fintanto che dura il sistema che si sta' sviluppando.
  • Si basa sulla collaborazione degli sviluppatori che hanno capacita' simili
  • Si basa su pratiche che funzionano sia con l'istinto a breve termine del programmatore e con gil interessi a lungo termine del sistema che si sta sviluppando.

XP e' una disciplina di sviluppo del software. E' una disciplina perche' ci sono alcune cose che debbono essere fatte per poter dire di stare sviluppando in XP. Non si puo' scegliere se si scriveranno i test o no: se non lo fai non sei estremo: fine della discussione.


TDD

In una frase possiamo dare il significato di TDD:"Scrivere soltanto il minimo codice necessario per far funzionare un test che fallisce".

  • Prima scriviamo un test
  • Poi scriviamo il codice per farlo passare
  • Poi affiniamo il codice riprogettandolo (refactor), basandoci sul test appena scritto in modo da non rompere la funzionalita' appena creata nel tentativo di migliorarla.


Vantaggi per il programmatore:
  • Raramente dovremmo avere chiamate di asistenza o finire in lunghe sessioni di debug
  • Siamo confidenti sul lavoro da noi svolto (NON E' COLPA MIA SE NON FUNZIONA)
  • Abbiamo piu' tempo per altre attivita' per migliorare come professionisti (STUDIO) e/o migliorare il sistema
Vantaggi per azienda (qualita'):











Friday, 21 May 2010

Conversione date da XMLDataSource in IReport

Dato il file xml di dati con la data nel formato yyyyMMdd :

<datanascita>20100101</datanascita>

Per importarlo convertendo le date occorre definire il pattern come in figura:


ATTENZIONE
Qui abbiamo specificato quale e' il formato della data in modo che iReport la possa convertire in un oggetto java.util.Date.
Qui non abbiamo specificato il formato di visualizzazione. Il formato di visualizzazione si specifica tramite la proprieta' pattern del campo di testo.


Quindi nel template jrxml il field settarlo come:

<field name="datanascita" class="java.util.Date"> <fieldDescription><![CDATA[datanascita]]></fieldDescription> </field>

Il campo di testo corrispondente nel dettaglio come:

<textField isStretchWithOverflow="true"> <reportElement x="247" y="24" width="295" height="20"/> <textElement/> <textFieldExpression class="java.lang.String"><![CDATA[$F{datanascita}]]></textFieldExpression>

Settandolo cosi la data verra' visualizzate tramite il toString di java.util.Date.

Se si vuole riformattare la data occorre utilizzare il campo pattern come qui sotto. Si noti anche come e' stata settato il campo class che deve essere di tipo Date per poter operare la conversione su di esso.


<textField isStretchWithOverflow="true" pattern="MM/dd/yyyy" > <reportElement x="247" y="24" width="295" height="20"/> <textElement/> <textFieldExpression class="java.util.Date"><![CDATA[$F{datanascita}]]></textFieldExpression>



Wednesday, 17 March 2010

Maven dipendenze e versioni

Fare attenzione alla versione che si specifica in maven.

Se normalmente si scrive nel pom.xml
      <dependency>
         <groupId>org.easytesting</groupId>
         <artifactId>fest-swing-junit</artifactId>
         <version>0.5</version>
      </dependency>

Maven lo interpreta cosi: utilizza qualsiasi versione, preferibilmente la 0.5.

Nel caso specifico essendo presente nel repository la 1.2 andava ad utilizzare quest'ultima invece della 0.6

Per usare una versione specifica inserire il numero della versione tra [].

      <dependency>
         <groupId>org.easytesting</groupId>
         <artifactId>fest-swing-junit</artifactId>
         <version>[0.5]</version>
      </dependency>

Monday, 8 March 2010

CP di Eclipse con Maven

Per quanto riguarda la gestione del CP da parte del plugin di Maven ho notato che se nel pom si inserisce una versione di una libreria corrispondente ad una versione di un progetto presente nel workspace il plugin di maven fa riferimento al progetto e non al jar.

Ad esempio se in StorpaModel si fa riferimento a ClassiSCS e si inserisce una versione di ClassiSCS corrispondente alla versione che si ha attualmente sul workspace il plugin di maven fa riferimento alla cartella.

Questa caratteristica permette di far riferimento ad un altro progetto direttamente all'interno del workspace senza fare deploy dello snapshot o manipolare il pom e il CP del progetto.

Fare attenzione pero' che il progetto a cui ci si riferisce sia compilato.

Nel caso di cui sopra ad esempio le applicazioni non partivano perche non venivano trovate alcune risorse a cui le classi facevano riferrimento.

Friday, 26 February 2010

File CVS e caratteri riservati

Fare attenzione ai file CSV che contengono caratteri come doppio apice: se si aprono con Open Office e si salva il file essi vengono malposti.

Ad es. se ho un file CSV che contiene la stringa (si noti uso di \ per fare escape del doppio apice):

"ESTRAZIONE FILE \"C\""

Aprendolo e salvandolo da Open Office si avra':

"ESTRAZIONE FILE \C\"""""

quindi con modifica del dato.

Purtroppo occorre ripristinare a mano aprendolo con file di testo quindi e' opportuno che suoi file CSV non si usino caratteri tipo " all'interno dei dati.

Thursday, 18 February 2010

Test 2

Quando si effettuano modifiche alla persistenza occorre inserire anche rispettive modifiche nei test.


Ad es. e' stata fatta questa modifica.
Da:
if (aTipo == 2) {

    // 15 - PROGRAMMARE
    op.setProgrammarePer(ProgrammarePer.converti(record.get(15)));

A:
// 15 - PROGRAMMARE
op.setProgrammarePer(ProgrammarePer.converti(record.get(15)));

if (aTipo == 2) {

Apparentemente minima ma essa comporta che il campo programmarePer viene settato per tutti i messagi che utilizzano il record RECPROANLZ, in particolare per il metodo extGetProveByAnalizzatore(..).

Quindi: 
  1. e' bene testare il nuovo campo in modo che se un domani cambio idea e rispristino situazione iniziale ho un test che mi segnala dove questo campo non sara' piu' disponibile.
  2. Se test e' condiviso con persistenza DB (tutti saranno progressivamente condivisi) mi segnala che occorre fare modifica anche su quest'ultima per allinearla con SALKI/SALVAL.

Test modificato:
public void testExtGetProveByAnalizzatore2() {
try {
List<Prova> rows = lab.extGetProveByAnalizzatore("PSM");

........

// Spostato  da tipo 2 a 1, quindi restituito qui
assertEquals(ProgrammarePer.TUTTI, prova.getProgrammarePer());

} catch (Exception e) {



Test

 Alcune considerazioni sulla scrittura dei test partendo da questo test iniziale:
   @Test 

    public void testExtModificaStatoAnalizzatore2() {
        try {            

            String sigla = "PieSSeeMMe";
            
            List rows = lab.extGetAnalizzatoriByDes(sigla);
            
            assertEquals (1,rows.size());
            
            Analizzatore ana = (Analizzatore) rows.get(0);

            if (ana.isStatoColloquio()) {
                lab.extModificaStatoAnalizzatore("",
                        OpAnalizzatore.DISATTIVA_COLLOQUIO, ana.getCod());
            } else {
                lab.extModificaStatoAnalizzatore("",
                        OpAnalizzatore.ATTIVA_COLLOQUIO, ana.getCod());
            }
            assertTrue(true);        
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }   
 

  1. Sulle collection specificare il tipo di oggetti contenuti, facilita scrittura e comprensione. Invece di List List<Analizzatore>.
  2. Dare sempre occhiata che non ci siano warnings oltre che errori (tabs dei problemi). 
  3. Fissare import (CTRL + O).
  4. Alla fine dei test i dati devono essere invariati. Ad es. se aggiungo accettazione la devo cancellare alla fine del test. Esiste su DBL un modo per ripristinare i dati nel caso si verifichi errore durante esecuzione dei test che ha modificato i dati? Ad es. sul DB spiano e ricarico i dati di test e si riparte sempre dalla stessa situazione
  5. Sui test far lanciare le eccezioni, meno codice da scrivere.
  6. Fare sempre controllo su ID dell'oggetto per sapere se e' lui! Nel test di cui sopra si controlla solo il numero di oggetti restituiti.
  7. Le verifiche quando e' possibile vanno fatte rileggendo oggetti modificati dalla persitenza. Nell'esempio di cui sopra il test uscirebbe positivo anche se lo stato dell'analizzatore non e' cambiato: si testa solo che la chiamata non generi eccezione.

Il test e' stato modificato come riportato sotto, si noti in particolare la rilettura e il ripristino dello stato dei dati alle condizioni iniziali.
@Test 
public void testExtModificaStatoAnalizzatore2() throws Exception {

String sigla = "PieSSeeMMe";

List<Analizzatore> rows = lab.extGetAnalizzatoriByDes(sigla);
assertEquals(1, rows.size());
Analizzatore ana = (Analizzatore) rows.get(0);

assertEquals("PSM", ana.getCod());

// Stato dell'oggetto iniziale
assertEquals(false, ana.isStatoColloquio());

// Cambio lo stato dell'oggetto
lab.extModificaStatoAnalizzatore("",
OpAnalizzatore.ATTIVA_COLLOQUIO, ana.getCod());
// Verifico cambiamento dei dati rileggendoli
rows = lab.extGetAnalizzatoriByDes(sigla);
assertEquals( 1, rows.size());
ana = (Analizzatore) rows.get(0);
assertEquals("PSM", ana.getCod());
assertEquals(true, ana.isStatoColloquio()); // nuovo stato

// Ripristino e riverifico
lab.extModificaStatoAnalizzatore("",
OpAnalizzatore.DISATTIVA_COLLOQUIO, ana.getCod());
rows = lab.extGetAnalizzatoriByDes(sigla);
assertEquals( 1, rows.size());
ana = (Analizzatore) rows.get(0);
assertEquals("PSM", ana.getCod());
assertEquals(false, ana.isStatoColloquio()); // stato di partenza (dati invariati)
}


Passi della via di mezzo

Passi della via di mezzo

Giusti punti di vista: punti di vista, cioe', e parere esenti da falsi concetti e da fini egoistici

Giueste aspirazioni: grazie alle quali si possono avere intenzioni e opinini nobili e degne

Giusto modo di esprimersi: grazie al quale si e' cortesi, rispettosi e sinceri.

Giusto comportamento: esso consente di essere sereni, onesti e altruisti

Giusto modo di vivere: per attenersi a questo precetto occore evitare di nuocere a uomini e naimali ed e' necessario riconoscere a questi ultimi il diritto all'esistenza.

Giusto impegno: occorre sapersi dominare e sottoporsi ad un addestramento continuo

Giusta circospezione: nel pensare solo cio' che e' giusto e nel fare soltanto cio' che si sa essere giusto.

Giusto rapimento: e' questo il piacere tratto dalla meditazione sulla realta' della vita e del super Io.

Followers