XPlayer

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

Michael Feathers on Testing Private Methods

| Comments

Da un articolo di InfoQ, la posizione di M.Feathers sul testare i metodi privati: Michael Feathers suggested last year in The Deep Synergy Between Testability and Good Design that TDD encourages good design and, conversely, code that is not testable should make us think twice:
When I write tests and I have the urge to test a private method, I take it as a hint. The hint tells me that my class is encapsulating so much that it has ceased to be “understandable” by tests through its public interface. I listen to the hint, and factor my design differently. Usually, I end up moving the private method (and possibly some methods around it) to a new class where it can be non-private and accessible to tests.
Condivido al 100%! E interessante anche quello che dice dopo, nel post originale, riguardo alla relazione tra coupling, cohesion e testabilita’.
In the end, it all comes down to cohesion and coupling.  If classes are deeply coupled with their neighbors, it is hard to control them in a test or observe them independently.  If a class isn’t cohesive, it may have some logic which is not easily exercisable through its public interface. It seems that reverse is true also.  Classes which are hard to instantiate and use in a test harness are more coupled than they could be, and classes with private methods that you feel the urge to test, invariably have some sort of cohesion problem: they have more than one responsibility.

[A-ha! Moment] Finalmente Ho Capito La Configurazione Di DBCP

| Comments

Questo post e’ piu’ che altro indirizzato a me stesso nel futuro, ma ovviamente se potesse servire ad altri, ora o nel futuro, ne saro’ contento. Ho finalmente capito il significato dei parametri di configurazione di DBCP! I miei dubbi riguardavano in particolare i parametri minIdle, maxIdle e maxActive. Le connessioni aperte in un dato istante possono potenzialmente essere comprese tra zero e maxActive. Quando il n. di connessioni aperte e’ compreso tra maxIdle e maxActive, tutte le connessioni ritornate al pool saranno immediatamente chiuse dal pool. Quando il n. di connessioni aperte e’ compreso tra minIdle e maxIdle, tutte le connessioni ritornate al pool saranno soggette all’eventuale evictor (che si attiva con la prop timeBetweenEvictionRunsMillis). Questo significa che quando l’evictor parte, chiudera’ tutte le connessioni in eccedenza (rispetto a minIdle), ovviamente secondo le impostazioni dei parametri numTestsPerEvictionRun e minEvictableIdleTimeMillis (quest’ultima in particolare indica quando tempo una connessione ‘in eccesso’ puo’ rimanere idle nel pool prima di essere considerata ‘chiudibile’ dall’evictor thread). Quando il n. di connessioni aperte e’ compreso tra zero e minIdle, tutte le connessioni ritornate al pool saranno lasciate nel pool. In altre parole non si dovrebbe mai scendere al di sotto di minIdle connessioni aperte verso il db. Ora, magari questo puo’ sembrare scontato a voi, ma a me no! DBCP ha una documentazione piuttosto fumosa, e in particolare faccio ancora fatica a capire la differenza tra i vari parametri di configurazione… per esempio, cosa si intende per abandonedConnection? E come si distingue da una normale connessione idle? Comunque intanto mi godo il mio a-ha! moment :)

Measuring Lines of Code

| Comments

Mi e’ piaciuta molto questa frase di Kent Beck da una mail sulla lista xp americana, sull’uso del numero di linee di codice come metrica di produttivita’:
Lines of code has many limitations – it’s like measuring a factory based on its consumption of raw materials not on its output.
Ricorda un po’ quella di Edsger W.Dijkstra
Yet people talk about programming as if it were a production process and measure “programmer productivity” in terms of “number of lines of code produced”. In so doing they book that number on the wrong side of the ledger: we should always refer to “the number of lines of code spent”.

Microsoft E Il Continuous Improvement

| Comments

Su InfoQ si parla di tal Jay Bazuzi, ”Development Lead for the C# Editor”, che lascia Microsoft e che in occasione di questo “evento”, ha postato sul suo blog delle riflessioni su alcuni punti deboli nello sviluppo del sw in Microsoft. sunset in val di casies A parte le osservazioni su come in Microsoft si usa l’OO o si applica refactoring, l’ultimo punto e’ particolarmente interessante, quando parla di “doing better”. Le domande che Jay raccomanda di farsi per migliorare (e che lui personalmente si faceva e faceva al suo team) sono
  • “How can I make sure this problem goes away forever?”
  • “How can I produce fewer bugs?”
  • “How can I make it easier to fix the bugs I have?”
  • “How can I make it easier to respond to change quickly?”
  • “How can I make it easier to make my software fast enough?”
Mica paglia! Che sotto sotto Jay volesse rendere piu’ agile Microsoft? :-)

Il Mio Feedback Sull’agile Day 2007

| Comments

Complimenti a Marco e agli altri organizzatori, l’agile day 2007 e’ stato molto interessante, con contenuti ed organizzazione migliori dello scorso anno. Cosa mi e’ piaciuto:
  • lo speak di Tim Mackinnon, uno dei padri dei mock objects. In particolare:
    • l’accento sull’appreciative inquiry e sul positive thinking
    • le pratiche da lui adottate, in particolare quelle a supporto della riflessivita’ e del miglioramento continuo del team, come la timeline e la retrospective
  • l’esperienza di Antonio Terreno su un progetto in ThoughtWorks dove c’era stato un cambio totale di team, e si e’ riusciti a fare bene
  • le incursioni di Francesco Cirillo, vedi la campagna anti-if (comprate la maglietta anti-if!) e le riflessioni su cosa voglia dire essere agili e su quali passi dovrebbe intraprendere la comunita’ xp italiana per favorire la diffusione dei metodi agili.
  • la presentazione di Alessandro Ruzzon sull’uso di Spring in progetti “agili” (!!)
  • in generale ho apprezzato la logistica a supporto delle presentazioni, vero punto debole dell’agile day 2006 (troppo rumore perche’ non c’era una vera separazione delle diverse track “concorrenti”)
Cosa non mi e’ piaciuto:
  • la location (troppo difficile da raggiungere)
Ah, e ovviamente, aderite anche voi alla campagna anti-if! Campagna Anti-IF

La Mia Piccola Illuminazione Di Oggi: GANTT Planning vs XP Planning

| Comments

La mia piccola illuminazione di oggi riguarda il modo tradizionale di pianificare e gestire un progetto software, ovvero con un bel GANTT e MS Project. Per la prima volta ho dovuto analizzare il GANTT per la nuova release di un progetto su cui sto lavorando, e rivedere alcune attivita’ a nostro carico per capire se mancava qualcosa e verificare le dipendenze e le stime. Ci mancherebbe, se c’e’ da fare, si fa’, ma ho sentito pian piano sorgere un senso di frustrazione… Ho poi capito il senso di fastidio che provavo: il GANTT (almeno, questo GANTT) e’ piuttosto “tecnical-task centrico”, ovvero organizza le attivita’ “tecniche”, ma non considera in nessun modo le features dal punto di vista del customer. Tutto il contrario della pianificazione in XP, che e’ “business-value centrica”, ovvero usa le user stories (“units of customer-visible functionality”) per pianificare pezzi di funzionalita’, a prescindere poi dai task tecnici che possono esserci dietro (e che vanno certo esplicitati, se e’ il caso, ma che non hanno valore di business di per se’). Ma perche’ questa differenza? Forse questo e’ dovuto al fatto che, mentre il GANTT e’ uno strumento del project manager per guidare il team di sviluppo (il customer lo vedra’ mai?), le user stories sono invece uno strumento del customer per guidare lo stesso team. In altre parole la pianificazione in XP coinvolge in prima persona il team dei customers (project manager, product manager, marketing, utenti, …), mentre in un progetto tradizionale la dinamica e’ del tipo “eccoti le specifiche, ci si rivede a fine progetto”. Sta di fatto che io, abituato a ragionare innanziutto per user stories, mi sono ritrovato piuttosto a disagio a ragionare per task tecnici, perche’ facevo fatica a vederci dietro le funzionalita’, e spesso anzi trovavo che la somma dei task tecnici non bastava a coprire la funzionalita’ che il sistema dovrebbe realizzare. E’ un po’ come descrivere un quadro attraverso la somma dei tratti del pennello che lo compongono… si rischia di perdere il senso complessivo dell’opera. Il rischio nel caso del software e’ quello perdere tra i tanti task tecnici i veri obbiettivi di una feature, ovvero produrre qualcosa che risponde a delle necessita’ del customer.

Come Object Mentor Guida La Transizione XP Dai Propri Clienti

| Comments

Di recente Bob Koss di Object Mentor ha pubblicato un post sul possibile cattivo uso della velocity come metrica di processo. A parte il tema del post, Bob parla anche di come tipicamente Object Mentor guida la transiziona ad XP dai loro clienti. Prima di tutto tengono un corso su XP per tutti (gruppo di programmatori e gruppo di customers).
When Object Mentor does an XP transition with a client, we start with our XP Immersion course to get everybody on the same page about what our goals are.
Poi due istruttori seguono separatamente i due gruppi, uno insegna ai programmatori le pratiche piu’ tecniche, l’altro invece affronta con i customers le pratiche di planning e managing del progetto XP (scrivere le carte, le iterazioni, la pianificazione incrementale, …)
Ideally, we use two instructors, one to train the programmers in topics such as Test Driven Development and Refactoring, and the other coach teaches story writing, iteration planning, and release planning to the customer team.
Poi i due gruppi lavorano assieme per un giorno intero ad un progetto di prova, per far vedere a tutti come funziona il processo XP
We then bring the two groups together for a day and have the customer team drive the programming team on a classroom exercise so everybody can experience how the process works.
I due mentor rimangono poi per seguire le prime iterazioni del progetto “vero”
The instructors then stay and work with the team for a few iterations, coaching them on how to use what they learned in class on their own project.
E poi tornano di tanto in tanto per vedere come vanno le cose, magari partecipano alle retrospective di iterazione per vedere quali sono i problemi, come vanno le metriche (in questo caso la velocity). Interessante, no? Quanto meno perche’ mi fa riflettere su quali siano i modi migliori per introdurre XP in una realta’ nuova. Certo, qui c’e’ un cliente che coscentemente decide di adottare XP e paga (tanto immagino) per essere guidato nella transizione verso un processo agile. La realta’ in cui invece mi trovo io e’ diversa, si deve procedere in modo incrementale, a piccoli passi, perche’ qui nessuno (tra i dirigenti almeno) ha chiesto di adottare XP, anche se c’e’ molto interesse e (qualche) consapevolezza dei punti deboli dell’attuale processo. C’e’ quindi un lavoro doppio, dal basso verso i programmatori e dall’altro verso i manager, per far vedere i piccoli miglioramenti che si possono ottenere lavorando in modo agile. Miglioramenti che consentono di lavorare in modo piu’ divertente e soddisfacente (il famoso “ease at work” di cui parlava Kent Beck in una sua presentazione tempo fa’). Vabbe’ magari ne parlero’ in un altro post, visto che sto andando fuori tema! Alla prossima!

Come Usare l’UML?

| Comments

Recentemente mi e’ stato chiesto come si sposano XP e l’utilizzo del UML, ovvero se e’ molto usato il design delle classi in UML prima di implementarle. Per mia esperienza, l’UML puo’ essere utile come strumento di comunicazione nel team, per trasmettere una idea di design, per esplorare la struttura statica e dinamica degli oggetti di un sistema. Una volta ottenuto il risultato (comunicare l’idea, chiarirsi le idee, mettere a fuoco una issue), si butta via il diagramma. Non fraintendetemi pero’. Una delle prime cose che ho studiato quando sono entrato nel team Xplayers di Quinary e’ proprio la notazione UML. In particolare sono magistrali alcuni capitoli del libro di Larman “Applying UML and Patterns” e alcuni articoli di Bob Martin (per esempio questo). Questo per dire che un bravo xper deve conoscere bene l’UML perche’ deve saperlo leggere e scrivere (in particolare come dicevo i class diagram, i collaboration diagram e i sequence diagram), cosi’ come deve conoscere mooolto bene i pattern, perche’ deve saperli riconoscere quando emergono dal design del codice in evoluzione (stessa cosa vale per i principi dell’OO). Uno degli usi migliori per mia esperienza della notazione UML e’ per esplorare un sistema legacy, ovvero per capire che tipo di legami e di dinamiche ci sono dietro al sistema, magari disegnando qualche class diagram e/o collaboration diagram. E’ quindi molto utile per avere una visione di insieme, seppure molto limitata, di un sistema. Anche qui si disegna il diagramma, e poi, appena diventa inutile (si spera presto), lo si butta via.

Perche’ Non Si Dovrebbero Mockizzare Classi Concrete

| Comments

Mi sono sempre chiesto perche’ mai Steve Freeman e gli altri ‘padri’ dei Mock Objects e dello stile di testing interaction-based sconsigliassero di fare mock di classi concrete, tanto che jMock ed EasyMock non supportavano questa possibilita’ ‘nativamente’, ma si doveva installare un’estensione a parte, che usa la famosa libreria CGLIB (per inciso con il nuovo jMock 2 e’ possibile fare mock di classi concrete, ma si deve usare la classe UnsafeHackConcreteClassImposteriser, ed il nome dice tutto di come scoraggino questa pratica). Tanto che tempo fa avevo anche commentato un post di Freeman chiedendogli perche’ lui giudicasse il mock di classi concrete come una sorta di ultima possibilita’ da adottare solo in casi di emergenza (es quando si affronta codice legacy particolarmente ostico e chiuso). E lui mi aveva risposto cosi’:
Because then the interface is implicit, which means you can’t see it and you haven’t given it a name. Instead of using the test to expose a feature of the design, you have more to think about whenever you’re working in that area: is the method overwritten? is it in a super class? what about the state of the rest of the class I’m extending? That sort of thing. For me, the CGLIB should have a “Break Glass in Case of Emergency” written on the front. It’s useful in tight situations, but not to be recommended.
Eppero’ nonostante la sua risposta la cosa non mi era ancora chiara fino in fondo. Poi un recente post su mockobjects.com (Test Smell: Mocking concrete classes) mi ha finalmente aiutato a capire meglio le cose. Il fatto e’ che lo scopo del TDD con i Mock Objects e’ quello di scoprire e far emergere relazioni tra oggetti, e dare nomi a queste relazioni. Se pero’ si mantiene la relazione tra oggetti a livello di classi concrete, queste relazioni rimangono per cosi’ dire piu’ nascoste, implicite, e quindi diventa difficile individuarle e darle un nome. Cito direttamente il post, laddove spiega cosa non va con i mock di classi concrete:
The problem with this approach is that it leaves the relationship between the objects implicit. I hope we’ve made clear by now that the intention of Test-Driven Development with Mock Objects is to discover relationships between objects. If I subclass, there’s nothing in the domain code to make such a relationship visible, just methods on an object. This makes it harder to see if the service that supports this relationship might be relevant elsewhere and I’ll have to do the analysis again next time I work with the class.
Addirittura si spinge a dire che lasciando le relazioni tra oggetti a livello di classi concrete, si rischia di violare l’Interface Segregation Principle, perche’ le classi dipendono da una interfaccia piu’ grande di quella che usano veramente. E poi poco piu’ avanti spiega che l’approccio mockist aiuta anche a dare nomi alle relazioni ed ai ruoli, e a ragionare piu’ in termini di dominio piuttosto che di implementazione:
There’s a more subtle but powerful reason for not mocking concrete classes. As part of the TDD with Mocks process, I have to think up names for the relationships I discover—in this example the ScheduledDevice. I find that this makes me think harder about the domain and teases out concepts that I might otherwise miss. Once something has a name, I can talk about it.
Il tutto e’ poi riassunto bene nell’altro post, What the tests will tell you, da leggere e rileggere, dove elenca alcuni benefici derivanti dall’approccio TDD+MockObjects
  • Keeping knowledge local
  • If it’s explicit I can name it
  • More names mean more domain information
  • Pass behaviour rather than data
Detto questo, ammetto che sono sempre stato affascinato da questo approccio ma non ho mai trovato la forza necessaria per decidere di applicarlo un po’ piu’ sistematicamente, metterlo alla prova insomma. Un po’ perche’ nel mio team da sempre si usa l’approccio classico, e l’approccio interaction-based e’ visto con qualche dubbio/sospetto, un po’ perche’ i nostri progetti per ora sono tutti Java 1.4 e quindi buona parte delle comodita’ delle versioni piu’ recenti dei framework jMock e Easymock te le perdi (soprattutto la loro maggiore letteralita’, cosa importante per avere dei test validi).

Ascoltare I Propri Test: Quando La Lunghezza Di Un Costruttore Ci Puo’ Insegnare Tanto…

| Comments

Ancora una volta i post su mockobjects.com mi ricordano che c’e’ molto da imparare dai propri test. E’ il caso di Test Smell: Bloated Constructor e Test Smell: Everything is mocked. Bloated Constructor… Se si usa il TDD, capita di finire per avere oggetti con un costruttore gigante, che prende una lista infinita di parametri, tipicamente i peers (ovvero i collaboratori) dell’oggetto. In tali casi fare i test, e soprattutto farli coi mock, e’ la morte. E in molti casi ce la si prende coi mock, rei di complicare i test. Ma spesso la difficolta’ a testare un oggetto e’ sintomo di problemi di design sull’oggetto stesso… E riflettere su queste difficolta’ e riportarle sul codice sotto test ci consente di migliorarne il design. O, come dice Steve Freeman, being sensitive to complexity in the tests can help me clarify my designs. In questo caso un costruttore lungo potrebbe indicare che magari ci sono oggetti che potrebbero essere raggruppati a formare un nuovo oggetto. Questo semplifica anche i test dell’oggetto da cui siamo partiti e consente di ridurre le sue responsabilita’, tutte cose buone e giuste. Freeman usa due euristiche per l’estrazione di componenti:
When I’m extracting implicit components, I look first for two conditions: arguments that are always used together in the class, and that have the same lifetime. That usually finds me the concept, then I have the harder task of finding a good name.
Nel secondo post che cito all’inizio, Test Smell: Everything is mocked, si sfata un mito duro a morire: non si devono fare mock per tutte le classi che si incontrano. In particolare non e’ assolutamente necessario mockizzare value objects, e soprattutto “don’t mock third-party libraries!”. Piuttosto, un approccio migliore e’ quello di far emergere col TDD e i mock un sottile straterello di codice che faccia da adaptor verso le API esterne, e che fornisca al nostro dominio i servizi di cui ha bisogno. E poi testare questo thin layer con dei test di integrazione che garantiscano che ci si agganci correttamente alla libreria.