Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[TDD] Sviluppo TDD con C#

14 views
Skip to first unread message

marcosabba

unread,
Mar 7, 2012, 11:00:50 AM3/7/12
to
Salve a tutti, non so se vado leggermente OT, ma succede che mi sto
ponendo problemi di scope cercando di sviluppare seguendo un approccio
test driven.
Quello che mi sono chiesto quasi subito è come si concilia
l'incapsulamento con la necessità di scrivere test per metodi testabili,
dunque necessariamente pubblici.
Faccio un esempio pratico:
sto lavorando a un progetto che prevede il postprocessing di una serie
di files xml da parte di una serie di plugin, dunque abbiamo delle
classi che implementano un'interfaccia IPlugin che espone due metodi:
Init e Execute.
Uno di questi plugin deve leggere in una cartella, cercare determinati
files xml, parsarli cercando al loro interno alcuni path di ALTRI files,
costruire una lista di questi ultimi e passarli a un tool che li
processa esternamente.
Pensando TDD, dovrei scrivere per prima cosa i test per i metodi che
fanno tutte quelle operazioni, ma quei metodi dovrebbero essere
nascosti, visto che il plugin espone solo due metodi.
E' dunque necessario esporre _tutti_ i metodi da testare, rompendo
l'incapsulamento "logico" della classe? Cosa ne pensate? O sto
sbagliando a interpretare il TDD?
Grazie e ciao

Mauro Servienti [MVP]

unread,
Mar 8, 2012, 12:04:07 AM3/8/12
to
Ciao marcosabba,

You wrote on 07/03/2012 :
> E' dunque necessario esporre _tutti_ i metodi da testare, rompendo
> l'incapsulamento "logico" della classe? Cosa ne pensate? O sto sbagliando a
> interpretare il TDD?

una considerazione filosofica: perché è un problema che sia tutto
"public" (sia chiaro che per me lo è eccome)

Dai un occhio all'attributo InternalsVisibleTo

.m

--
blog @ //milestone.topics.it


Giulio Petrucci

unread,
Mar 8, 2012, 7:44:23 AM3/8/12
to
Ciao Sabba,

On 07/03/2012 17:00, marcosabba wrote:
> sto lavorando a un progetto che prevede il postprocessing di una serie
> di files xml da parte di una serie di plugin, dunque abbiamo delle
> classi che implementano un'interfaccia IPlugin che espone due metodi:
> Init e Execute.
> Uno di questi plugin deve leggere in una cartella, cercare determinati
> files xml, parsarli cercando al loro interno alcuni path di ALTRI files,
> costruire una lista di questi ultimi e passarli a un tool che li
> processa esternamente.
> Pensando TDD, dovrei scrivere per prima cosa i test per i metodi che
> fanno tutte quelle operazioni, ma quei metodi dovrebbero essere
> nascosti, visto che il plugin espone solo due metodi.
> E' dunque necessario esporre _tutti_ i metodi da testare, rompendo
> l'incapsulamento "logico" della classe? Cosa ne pensate? O sto
> sbagliando a interpretare il TDD?

Io imposterei ogni test in questo modo:
1. set-up dell'ambiente esterno (crei dei files .xml ad hoc, con dentro
i path ad altri files sempre ad hoc, ecc ecc...)
2. lanci il plug-in
3. se l'esecuzione è andata a buon fine, il plug-in avrà avuto il suo
effetto sul "mondo esterno", e l'assertion del test deve misurare
proprio che questo effetto sia avvenuto.

Niente test dell'implementazione.
:-)

Ciao,
Giulio

--



marcosabba

unread,
Mar 9, 2012, 3:34:39 AM3/9/12
to
Ciao a tutti

Il 08/03/2012 06:04, Mauro Servienti [MVP] ha scritto:
> una considerazione filosofica: perché è un problema che sia tutto
> "public" (sia chiaro che per me lo è eccome)

intanto grazie per la risposta, il problema me lo sono posto perché se
non avessi avuto i test avrei tranquillamente avuto metodi privati,
dunque renderli pubblici solo perché ci sono i test, che considero come
viaggiatori su un binario parallelo, mi sembrava per lo meno "brutto",
ma questa è un'opinione "estetica". Sul fatto sostanziale, beh, avere
pubblico e privato dovrebbe essere un aiuto per il design: sapere che
alcune cose sono esposte e le vedi di fuori, altre no, aiuta la
robustezza. Poi ovviamente puoi avere tutto pubblico e aumentano le
responsabilità per chi sta "di fuori". Però non so se ho capito bene la
tua provocazione ;)

> Dai un occhio all'attributo InternalsVisibleTo
grazie, funziona, a parte il fatto che devo usare internal nella
dichiarazione dei metodi (mentre avrei usato private che non è la stessa
cosa) va benissimo e prenderò anche questa strada.
Poi col mio collega di pair abbiamo anche deciso di esternalizzare un
componente che racchiude alcuni dei metodi privati e renderlo pubblico e
testabile, ma non posso farlo con tutto.
Ciao!

marcosabba

unread,
Mar 9, 2012, 3:37:24 AM3/9/12
to Giulio Petrucci
Ciao

Il 08/03/2012 13:44, Giulio Petrucci ha scritto:
> Io imposterei ogni test in questo modo:
> 1. set-up dell'ambiente esterno (crei dei files .xml ad hoc, con dentro
> i path ad altri files sempre ad hoc, ecc ecc...)
> 2. lanci il plug-in
> 3. se l'esecuzione è andata a buon fine, il plug-in avrà avuto il suo
> effetto sul "mondo esterno", e l'assertion del test deve misurare
> proprio che questo effetto sia avvenuto.
>
> Niente test dell'implementazione.

Eh come ci dicevamo ieri "live", il problema presenta diverse sfumature,
diciamo che a tendere il tuo approccio è il più "desiderabile", ma
durante uno sviluppo from scratch il TDD ti dovrebbe aiutare proprio a
sviluppare, quindi proprio "tirare su", anche l'interno della black box,
dunque come fare? L'internalsVisibleTo mi sembra un buon compromesso.
Ciao!

pasquale [:dedalus]

unread,
Mar 9, 2012, 3:52:07 AM3/9/12
to
On 09/03/2012 09:34, marcosabba wrote:
> dunque renderli pubblici solo perché ci sono i test

Come suggerito da Mauro, l'approccio internal+[InternalsVisibleTo] è
quello maggiormente consigliato (ovviamente, trattandosi di Mauro ;-)
)... possono poi essere usati (con minore potenza) l'attributo
condizionale [Debug] oppure l'espressione #if #endif con la compilazione
condizionale (il libro per me cult al riguardo è "The Art of Unit Test"
di Roy Osherove: trovi tutte e 3 le strade lì se hai voglia di
approfondire).

Piuttosto, l'unica cosa che non mi torna è l'affermazione che ho
quotato: se devi rendere pubblici dei metodi solo perché devi fare
unit-testing, per me, vuol dire che la responsabilità di fare quelle
cose, deve spettare a un'altra classe, che poi verrà usata privatamente
dal plugin che espone solo i 2 metodi pubblici Init e Execute...

Ciao.

marcosabba

unread,
Mar 9, 2012, 4:47:24 AM3/9/12
to
Ciao
Il 09/03/2012 09:52, pasquale [:dedalus] ha scritto:
> Piuttosto, l'unica cosa che non mi torna è l'affermazione che ho
> quotato: se devi rendere pubblici dei metodi solo perché devi fare
> unit-testing, per me, vuol dire che la responsabilità di fare quelle
> cose, deve spettare a un'altra classe, che poi verrà usata privatamente
> dal plugin che espone solo i 2 metodi pubblici Init e Execute...

in qualche modo allora mi confermi che questa strada
> Poi col mio collega di pair abbiamo anche deciso di esternalizzare un componente che racchiude alcuni dei metodi privati e renderlo pubblico e testabile
non è sbagliata (salvo poi mettere privato il componente nel plugin).
Faremo un mix :)

> il libro per me cult al riguardo è "The Art of Unit Test"
> di Roy Osherove
grazie, ce l'avevo ma gli ho preferito "TDD by example" di Kent Beck che
però non mi ha entusiasmato tantissimo. Gli darò presto un'occhiata,
grazie ancora

Ciao

Mauro Servienti [MVP]

unread,
Mar 9, 2012, 6:20:43 AM3/9/12
to
Ciao pasquale [:dedalus],

You wrote on 09/03/2012 :
> On 09/03/2012 09:34, marcosabba wrote:
>> dunque renderli pubblici solo perché ci sono i test
>
> Come suggerito da Mauro, l'approccio internal+[InternalsVisibleTo] è
> quello maggiormente consigliato (ovviamente, trattandosi di Mauro ;-)

:-)

> )... possono poi essere usati (con minore potenza) l'attributo
> condizionale [Debug] oppure l'espressione #if #endif con la compilazione
> condizionale (il libro per me cult al riguardo è "The Art of Unit Test"
> di Roy Osherove: trovi tutte e 3 le strade lì se hai voglia di
> approfondire).
>
> Piuttosto, l'unica cosa che non mi torna è l'affermazione che ho
> quotato: se devi rendere pubblici dei metodi solo perché devi fare
> unit-testing, per me, vuol dire che la responsabilità di fare quelle
> cose, deve spettare a un'altra classe, che poi verrà usata privatamente
> dal plugin che espone solo i 2 metodi pubblici Init e Execute...

in questi giorni c'è stata un interessante discussione sulla mailing
list interna di C# che ha toccato questo aspetto e la conclusione è più
o meno che se devi testare qualcosa di private o internal c'è qualcosa
che non va, perché avrebbe molto senso testare ciò che c'è di pubblico
che a sua vlta utilizza la roba internal.
E ovvio che questa è una generalizzazione e che ogni casistica è da
valutare a se.

> Ciao.
0 new messages