XPlayer

A blog on my daily efforts to be a better developer, and keep improving every day.

Ascoltare I Propri Test, Ovvero Migliorare Il Codice Partendo Dagli Smell Dei Propri Test

| Comments

Steve Freeman e Nat Pryce hanno iniziato una serie di interessanti post sul loro blog mockobjects sul tema dei Test Smells, ovvero su come ‘ascoltare’ i propri test per scoprire possibilita’ di miglioramento nel design del codice sotto test
In our experience, when we find that our tests are awkward to write, it’s usually because the design of our target code can be improved.
Una cosa su cui mi trovo d’accordo, piu’ che altro perche’ ho avuto la stessa esperienza in passato (e anche nel presente!) Test Smells… Il primo post della serie e’ Test Smell: I need to mock an object I can’t replace (without magic), dove si parte da un codice piuttosto ‘chiuso’, con dipendenze nascoste (magari usando dei Singleton), e passo passo lo si rifattorizza, aprendolo, prima introducendo un fake (o stub che dir si voglia) e poi passando ai mock, mostrando come il codice migliori, prima esplicitando le dipendenze e poi assegnando meglio le responsabilita’. Se vi capita dategli un’occhiata!

Law of Demeter

| Comments

Di recente ho seguito un thread intitolato “The Law of Demeter and Testability” sulla lista xp americana. A partire dal primo post di Jay Flowers (niente di travolgente), il discorso si e’ poi spostato sulla legge di demeter di per se’, il cui ‘peso’ personalmente non ho mai capito fino in fondo. Ne’ tantomeno mi sembra che se ne parli molto, al contrario magari di altri principi piu’ noti come OCP, DIP, LSP, SRP, eccetera. Alcuni messaggi di questo thread mi hanno fatto capire meglio questo ‘principio’ (chiamarla legge fa un po’ ridere) e a vederlo in un’ottica diversa. Vi sottopongo gli spunti piu’ interessanti, sperando possano esservi di stimolo quanto lo sono stati per me Michael Feathers:
It’s a great article, but the thing to remember about LoD is that it is not iron-clad. There are cases where you’re better off not having demetered code. The classic example is the Excel Object model. You get the workbook from the application and the worksheet from the workbook, and drill down through ranges to cells. It works because the model is very stable. In general, when the structure of data has meaning, LoD gets in the way; when you care more about behavior (and usually you can), LoD is the way to go.
Ron Jeffries:
Yes … the observation about structure is a good one. If you think of what you’d have to do, otherwise, with the Excel model, you’d have to make each call to Excel, parameterized with workbook name, worksheet name, maybe range, then cell. Pulling the innards out amounts to an addressing prefix, or stepping down through a hierarchy.
Mostly, though, I’d say LoD is the way to bet.
E infine Brad Appleton:
I actually took a class from Dr. Lieberherr on the full Demeter method (of which LoD is one small part). Having had the benefit of that, I think I have a lot of additional insight into the above.
The issue with the LoD is that, the way it is usually stated, the assumption is any/every class in an O-O program should be exhibiting functional behavior and hiding the details of what it contains, and how it contain them.
There are classes whose job is to encapsulate functional behavior/services, and there are classes whose job is to encapsulate structural behavior/services. That is to say that for some classes, the “secret” they need to “hide” isnt the fact that they contain some kinds of objects, but the details of HOW they contain those objects. Simple examples of these would be data-structures, lists, collections, iterators, dictionaries, data-stores, etc. Accessing the interfaces of the objects contained by such encapsulated structures actually doesnt violate the principle behind the LoD. But because of the way LoD is stated in such an oversimplified manner, those things appear to be violations when they really arent.
When a method-call returns a subobject of its containing object, then consider that invocation to be a violation of LOD *only* *if* the containing object is supposed to encapsulate behavior concerning its subobjects. If the object really only needs to encapsulate structural details about HOW it contains that object (rather than WHAT it contains), then it’s not really a violation of LoD.
So it’s less about whather or not the caller cares about the behavior or structure of the data, it more about whather the callee cares about (should be encapsulating) the behavior or the structure of what it contains.

Il Mio Feedback sull’Agile Day 2006 - Milano 01.12.06

| Comments

Venerdi’ primo dicembre ho partecipato al secondo Agile Day, organizzato a Milano al Centro congressi MilanoFiori. Innanzitutto devo ringraziare Marco Abis e tutti coloro che hanno contribuito (anche economicamente) alla sua realizzazione. Di seguito qualche mia considerazione sulla giornata: Interessante la presentazione del gruppo corse Ferrari (Nicola Canalini e Luca), anche se meno d’impatto di quella dell’anno scorso. Di quello che hanno detto mi hanno colpito alcune cose:
  • la grande attenzione che pongono nello standup meeting, dove mi sembra di capire che ognuno dice qualcosa. Addirittura ognuno se lo prepara il giorno prima (che e’ piu’ o meno quello che facciamo nel nostro team quando compiliamo il journal sul wiki a fine giornata). Ognuno arriva allo standup con una carta con i propri feedback, che ruotano attorno a poche domande:
    1. cosa ha fatto ieri
    2. cosa fara’ oggi
    3. di cosa ha bisogno
    4. problemi incontrati
    5. comunicazioni generali
  • un forte accenno alla leggibilita’ del codice (e noi come siamo messi a riguardo, eh?)
  • per gestire l’alto numero di progetti (circa 100!) e la loro complessita’, stabiliscono degli standard a cui tutti si attengono, tipo: c’e’ un solo modo di accedere alle basi dati, e chi deve accedere ad una base dati deve seguirlo. In tal modo diventa piu’ facile e veloce ‘entrare’ in un progetto o capire cosa non va.
  • uno sforzo per il miglioramento continuo e per l’auto-organizzazione
  • una delle metriche che adottano e monitorano costantemente e’ il numero di test scritti nell’arco di tempo (ogni giorno, ad ogni iterazione), sia come team che a livello ‘individuale’. Il delta dei test scritti dal team viene pubblicato quotidianamente su un monitor visibile a tutti.
La presentazione di Davide e Giuliano ha avuto luci ed ombre: bella e frizzante la presentazione con le slide, un po’ debole il video, sia per problemi tecnici (non si vedeva/sentiva bene), sia perche’ forse piu’ che una sessione di pair remoto dava l’impressione di essere una sessione di TDD. Non sempre ho trovato interessanti alcuni temi delle track (mi e’ capitato di non essere interessato a nessuna track che si stava svolgendo in quel momento). Il pubblico era vasto ma generalmente non sembrava da molto addentro all’xp e al mondo agile, per cui spesso le track tecniche per forza di cose si ‘appiattivano’ sul livello dei meno esperti. Per carita’, questo va benissimo, diffondere l’xp e i principi agili e’ una cosa molto importante e positiva, ma penso che il formato dell’open-space poco si presti a questa cosa, mentre e’ piu’ adatto a favorire lo scambio di esperienze tra persone piu’ o meno addentro agli argomenti trattati (io me lo immagino come un BOF). Come alcuni hanno detto lo stanzone dove si teneva la riunione e la sua acustica hanno disturbato non poco lo svolgimento delle track: solo le persone nelle immediate vicinanze della persona che parlava lo riuscivano a sentire, le altre no. Avrei poi preferito che le track fossero organizzate in modo che sembrassero meno delle presentazioni da uno a molti e piu’ una discussione tra tutti: magari mettersi tutti attorno ad un tavolo avrebbe semplificato, magari no. Non so. Io ho ‘tenuto’ due track: una sui test (“Scrivere Test che incoraggiano il cambiamento”) con Enrico Mangano e una sui Mock Objects. In tutti e due i casi siamo andati a volte fuori tema, soprattutto con la prima sui test. Sui mock objects sono soddisfatto a meta’: alcune persone erano interessate, ma una buona meta’ non sapeva cosa fossero i mock o comunque non li avava mai utilizzati. Avrei preferito tornare a casa con qualcosa di nuovo sui mock e sul loro uso, ma niente da fare. Pazienza In generale sono tornato a casa con pochi veri spunti di riflessione, giusto quelli che ho detto di ferrari e Cirillo sul ROI, qualcosa sulle metriche e basta. PS: Gabriele Lana ha fatto qualche foto della giornata…

Le Metriche Del Codice Per Quelli Della NASA…

| Comments

Ieri stavo leggendo questo articolo datato 1997 sulle metriche, pubblicato sul sito di un centro della NASA (Software Assurance Technology Center, http://satc.gsfc.nasa.gov/), che tra l’altro ha una sezione dedicata proprio alle metriche nel software (http://satc.gsfc.nasa.gov/metrics/index.html e http://satc.gsfc.nasa.gov/metrics/codemetrics/index.html). Vabbe’, in questo articolo si presentano diversi tipi di metriche, sia tradizionali che OO. Quando parla del numero ciclomatico dice: ”In general, the cyclomatic complexity for a method should be below ten, indicating decisions are deferred through message passing.” Un altra metrica tradizionale e’ poi la seguente: ”METRIC 3: Comment Percentage The line counts done to compute the Size metric can be expanded to include a count of the number of comments, both on-line (with code) and stand-alone. The comment percentage is calculated by the total number of comments divided by the total lines of code less the number of blank lines. The SATC has found a comment percentage of about 30% is most effective. Since comments assist developers and maintainers, this metric is used to evaluate the attributes of Understandability, Reusability, and Maintainability.” Quanti progetti legacy per quelli della NASA avrebbe delle ottime metriche? :-) E comunque voi sapete come mai anche il piu’ recente studio sulle metriche OO non arriva al 2000?! Cercando su google ho trovato articoli vecchi, nessun nuovo studio, niente di niente! Come mai?

Affinare La Metrica

| Comments

La recente discussione in seno al team XPlayers di Quinary sulle nostre metriche e su come affinarle mi ha fatto riflettere un po’ e volevo condividere con voi questi pensieri, ovvero una proposta di cambiamento della metrica (da sottoporre a prova sul campo, si intende). Il nostro magic number, dopo varie discussioni su quali fattori includere, e’ stato definito all’inizio in questo semplice modo Magic Number = NCSS / (LCOM * CCN) dove le premesse erano che (ditemi se sbaglio): se NCSS cresce e’ un bene (maggiore produttivita’?) se LCOM scende e’ un bene (maggiore coesione) se CCN (McCabe) scende e’ un bene (minore complessita’ “di flusso”) Io penso che in questa formula NCSS abbia un peso troppo forte, e questo favorisce oscillazioni come quelle che abbiamo osservato nelle scorse settimane (vedi thread su “Metriche di oggi”). Ora, non so per certo se queste oscillazioni siano giuste o meno, e capisco anche che, cosi’ come esiste il ‘debito di refactoring’ quando si scrive molto codice ma lo si rifattorizza poco, possa esistere una sorta di ‘debito di produttivita diretta’ quando si rifattorizza molto (e quindi si produce un delta di NCSS piccolo o addirittura negativo). Pero’ penso che sia giusto far entrare nella formula un fattore che premia il codice rifattorizzato, e pertanto propongo di provare la seguente formula Magic Number = NCSS / (LCOM * CCN * lunghezza media dei metodi) dove lunghezza media dei metodi = NCSS / #metodi il che significherebbe, semplificando i fattori Magic Number = #metodi / (LCOM * CCN) questa variazione permette secondo me (ma vorrei provarla per avere una qualche certezza) di premiare certamente la produzione di codice (come accadeva per l’NCSS), ma di codice rifattorizzato (che poi sia ben rifattorizzato questo non saprei come misurarlo). In altre parole se scrivo tanto codice nuovo, ma lo metto in pochi metodi grossi ho un incremento minore di quanto non avrei se lo stesso codice fosse messo in metodi piu’ brevi e concisi. Che ne dite?

Commenti Al Post “Don’t Over-Use Mock Objects” Di K.Ray

| Comments

Tempo fa Giuliano aveva segnalato questo post di K.Ray: Don’t Over-Use Mock Objects Mi sembra che le tesi dell’articolo siano un po’ forti (“Avoid them. Mocks make your tests more fragile and more tightly-coupled. And at the same time, they reduce the integration-test aspects of TDD. They make your tests larger and more complicated and less readable.”). Certo, se usati male possono dare problemi di fragilita’ eccessiva del test e di leggibilita’ (a meno che non si usi un po’ di literate programming con jMock), e soprattutto se non si usano per riflettere su eventuali debolezze del proprio codice (a questo riguardo il blog su www.mockobjects.com fa spesso illuminanti esempi di codice che usa scorrettamente i mock). L’obiezione che i mock ridurrebbero la robustezza dei test e’ debole (“If you change an object’s API, a mock object’s API may not change, making your tests out-of-date with respect to your non-test code”), perche’ con EasyMock si usano le API ‘vere’, pertanto non esite la possibilita’ di avere dei metodi ‘out of date’ (non so come funzioni invece jMock). L’unica osservazione secondo me con un certo fondamento e’ la critica al modo di procedere degli interaction-based testers (“In TDD, you normally write a test, write some code in a target class/method that passes the test. The third step is refactoring. … Test-Driving with Mocks inverts that order: you create your target class and a mock class up-front, and plan on how they interact, instead of evolving that interaction in TDD’s refactoring steps. You pre-judge the class design rather than evolve it.”). Anche a me suona innaturale di norma procedere come gli interaction-based testers, ma penso anche che ci siano casi in cui questa ‘esplorazione’ delle interazioni e’ utile. Suonera’ un po’ eccessivo, ma qualcuno diceva che la programmazione dei mock in un test e’ un po’ come un sequence diagram sotto forma di codice! :-) Siamo invece d’accordo che i mock sono utili per rendere piu’ indipendenti i test (“Mocks are tool for decoupling, and I do sometimes use them. I limit my use of Mocks to those situations where the real object will not reliably do what I want. Examples: simulating errors in writing a file; simulating connections with a remote server; simulating errors from remote server.”).