Cosa puoi fare riguardo alla qualità dell'integrazione esistente e dei test unitari mentre sei il nuovo ragazzo in una squadra?


21

Un tema ricorrente che mi sono imbattuto nella mia carriera è quello di essere il nuovo sviluppatore ad arrivare in un team e avere rapidamente una diffidenza nei confronti dell'unità esistente e delle suite di test di integrazione.

Durante il colloquio ti viene detto dal management che "supportano fortemente i test unitari" e che lo incoraggiano apertamente. Lo fanno, ma tutto ciò che riguarda i test stessi è semplicemente sbagliato. Come il fatto che stiano reclamando una copertura del 100% quando c'è una copertura del test di integrazione del 100% ma una copertura del test unitario ripetibile inferiore al 10%. Alcuni altri problemi che ho riscontrato:

  1. Nessuna chiara indicazione tra cos'è un test unitario e cosa è un test di integrazione. I test unitari e di integrazione sono mescolati insieme nella stessa classe.

  2. Test di integrazione che hanno dichiarato esplicite dipendenze su dati dinamici molto specifici su un database di un ambiente specifico.

  3. Test di integrazione non transazionale, fondamentalmente test che possono o meno preoccuparsi di ripulire dopo se stessi, a volte richiedono "scrubbing" manuale del database per rendere ripetibile il test.

  4. Nessun beffardo di sorta, e il codice dell'applicazione richiede una profonda revisione solo per renderlo possibile. In altre parole, progettare senza pensare.

  5. Nessuna convenzione di denominazione chiara per esaminare rapidamente un nome di test e determinare approssimativamente quali test vengono eseguiti.

Tutto ciò non vuol dire che TUTTI i test sono inutili o cattivi, molti di loro sono piuttosto buoni e vale la pena conservarli, ma a volte è come cercare l'oro. Eviterei di proposito di eseguire i test solo perché avevo paura di rovinare il database per i miei casi di test black-box.

Questo mi ha essenzialmente dato una diffidenza intrinseca nei test unitari e di integrazione che non ho scritto o rivisto personalmente in alcun modo. Ad un certo livello se non si ha fiducia nella qualità della propria suite di test, questo non apporta davvero alcun valore al team o al progetto.

Cosa fai quando ti trovi in ​​questa situazione? Quale pensi che sarebbe il miglior piano di attacco per affrontare qualcosa del genere?

Tutti i test dovrebbero essere rifattorizzati in uno sforzo monumentale che attraversa le versioni? Dovresti semplicemente abbandonare l'idea che questo progetto legacy possa avere una solida copertura di test unitari un giorno?


6
Benvenuto nel mondo reale, amico.
tdammers,

20
Sii felice di avere dei test.
Joel Etherton,

3
Perché lavori per aziende chiaramente al di sotto del tuo livello di competenza?
TrojanName

3
@Brian, apprezzo il colpo dell'ego, ma senza più persone che pensano come me, queste aziende non saliranno mai al di sopra. Questa è la prima volta che mi trovo in una posizione di potere reale, poiché per una volta ho sviluppato una modesta importanza politica. Ho una vera opportunità qui per indirizzare risorse per migliorare le cose. Non ho ancora trovato un'azienda perfetta senza bisogno di lavoro. È come il marito o la moglie perfetti, non arrivano e basta, arriva una persona abbastanza brava e poi li cambi in quello che vuoi che siano;)
maple_shaft

1
Penso che potremmo lavorare per la stessa squadra. Ora tu (e io) sappiamo davvero come fare domande durante le nostre prossime interviste. (In realtà, il mio ambiente non ha una copertura dei test di integrazione quasi del 100% o addirittura del 10% [test di unità reali? È un discorso folle!], Ma hai risolto tutti gli altri punti con cui ho a che fare.)
Anthony Pegram

Risposte:


6

Prima di tutto, come hanno già scritto altri poster, dovresti essere felice che i test di unità / integrazione siano compresi (non in modo tecnico, intendo il motivo per cui dovrebbe essere fatto è compreso) e spinti dalla direzione.

Prima di iniziare a fare tutto ciò che è necessario esporre i problemi alla gestione, perché qualcosa dovrebbe essere fatto, e molto diplomaticamente in modo che non pensino che tu pensi di essere il miglior programmatore del mondo (anche se lo sei! :-). Forse ti diranno che l'applicazione verrà sostituita da qualcosa di completamente nuovo e, in tal caso, perché preoccuparsi. E forse si renderanno conto che sarebbe bello e accelerare la fase di test prima di ogni versione. Ed essere diplomatico con i tuoi compagni di squadra , ci possono essere milioni di ragioni per cui è così com'è e non c'è proprio motivo di cercare un colpevole.

Un'idea migliore sarebbe quella di provare a parlare con loro in modo che possano partecipare allo sforzo, e avrai meno possibilità di apparire come un coglione, sarebbe più "noi" che "io".

Adesso, dai la priorità a ciò che vuoi fare. Dai la priorità alle attività, sapendo sempre che la tua prima priorità sarà sempre la tua attuale assegnazione di progetto ... Per quanto riguarda il tuo problema di test, ecco cosa farei, in tre fasi:

  1. Come fare la differenza tra test unitari e di integrazione? Possono essere applicabili le seguenti soluzioni e non sono esclusive:

    • Rifattorizzare il nome dei metodi del test case (non le classi poiché il comportamento corretto è che il test case condivida lo stesso nome della classe testata)
    • Crea due annotazioni, una denominata "UnitTest", l'altra "IntegrationTest". Queste annotazioni possono essere utilizzate su classi e metodi. Se un'intera classe è composta da test unitari o di integrazione, è possibile contrassegnare la classe con l'annotazione corretta. In caso contrario, è possibile contrassegnare ciascun metodo con l'annotazione corretta. Inoltre, queste annotazioni potrebbero essere utili per iniettare dinamicamente i dispositivi prima di avviare i test (fase 3)
  2. Per ogni test di integrazione, elenca quale sia il "set di dati" che dovrebbe essere nel database all'inizio di ogni test e cosa dovrebbe essere rimosso alla fine di esso (es: tabella X, necessita di un record con "id" impostato su "1" e "nome" impostato su "pippo", ecc.). Nota che ciò che rimuovi potrebbe essere più grande / più piccolo di quello che hai all'inizio poiché il codice stesso può rispettivamente aggiungere / rimuovere oggetti dal livello di persistenza. Molto probabilmente noterai rapidamente che molti di questi casi di test richiedono lo stesso set di dati o parte dello stesso set di dati.

  3. Le prime due fasi possono essere eseguite relativamente rapidamente ... rispetto alle altre. Ora che hai il tuo set di dati, usi creare dispositivi di set di dati per ogni test case che ne ha bisogno. Ma questo costerà un po 'di tempo ... Quindi potresti farne uno, vedere quanto tempo ti costa e stimare quanto altro tempo hai bisogno per fare tutto. Inoltre, potresti usare quel test per dimostrare ai tuoi colleghi cosa hai fatto e perché la vita è molto più semplice quando non hai bisogno di avere un database in uno stato specifico per eseguire i test.

Si può notare che le fasi 1, 2 e 3 possono essere eseguite su una singola classe di test, se si desidera mostrare rapidamente ai colleghi / dirigenti come può essere fatto. Ciò sarebbe utile, come ha scritto Péter Török, al fine di mostrare immediatamente il "buon modo" ai tuoi compagni di squadra in modo che smettano di produrre codice errato. Tuttavia, penso che il resto della fase 2, identificando l'intero set di dati di test, venga eseguito al meglio in un unico grande passo.

Per quanto riguarda l'API / la tecnologia dietro tutto ciò, sembra che tu sappia l'argomento.

Spero che abbia aiutato un po '.

Nota: per la mia proposta, suppongo che il codice sia in Java / C # dove conosco le annotazioni e AOP è possibile. Sono sicuro che ciò sia possibile anche in altre lingue, ma non scriverò di qualcosa che non conosco.


1
Grazie ... Ho considerato l'utilizzo delle annotazioni come etichette per identificare cos'è un test di integrazione e cos'è un test di unità ... Sai se è possibile configurare un server CI come CruiseControl per escludere determinati test basati su annotazioni? Forse è una domanda separata.
maple_shaft

Mi dispiace non so usare CruiseControl, quindi non lo so. Ho cercato nella configurazione del plugin Surefire di Maven solo per curiosità e non sembra possibile, tuttavia è possibile saltare i test in base ai nomi, ovviamente.
Jalayn,

14

Non sarai in grado di risolvere tutti i test insieme. Penso che dovresti concentrarti sulla parola miglioramento rispetto alla revisione . Né il management né gli sviluppatori saranno d'accordo su una revisione, ma se si dimostra che esiste un modo per migliorare le cose senza influire negativamente sul progetto, sarà più probabile che ascoltino.

Innanzitutto, non è possibile "correggere" o refactificare il codice esistente a meno che non si disponga di una copertura dei test di qualità, quindi mi concentrerei innanzitutto sulla riparazione della tua infrastruttura di test.

Fai un elenco di cose che necessitano di miglioramenti e cerca di assegnarle le priorità. Penso che la capacità di eseguire i test in modo indipendente e individuale (quindi non si influenzano a vicenda) e la separazione dei test unitari e di integrazione sono alcune delle prime cose su cui lavorare. Devi rendere facile per te e gli altri fare la cosa giusta.

Per quanto riguarda il codice dell'applicazione ... Non sarai in grado di fare la revisione completa dell'architettura dell'applicazione solo in modo che possa essere testato meglio l'unità. Invece, quando si inserisce un nuovo codice, provare ad applicare i principi che semplificano il test unitario (come l'iniezione di dipendenza). Potresti pensare che questo non sia un cambiamento abbastanza grande, ma è sorprendente quanto velocemente gli sviluppatori se ne accorgano se ne vedono il vantaggio. Deve solo esserci qualcuno che inizia a cambiare in meglio.

Parla con il tuo team e fagli comprare. Una delle cose più importanti che puoi fare è seguire la " regola del boy scout " e apportare piccoli miglioramenti per lasciare una classe o fare un test in una forma migliore di quando l'hai trovata . Se l'intero team applica questa regola, le cose migliorano molto più velocemente.

Dopo un po ', avrai un sacco di codice che segue buoni principi e aree dell'applicazione che sono in cattive condizioni. A questo punto, hai una base di ciò che è buono e il team può decidere se è utile fare un rifrattore più grande per le cose legacy più vecchie o può continuare a vivere così com'è.


8
+1 e aggiungerò "inizia dando l'esempio". Nessuno apprezza il ragazzo che entra e dice "stai sbagliando", ma se mostri miglioramenti è più probabile che seguano.
StevenV,

2
+1 per la regola del boy scout , è molto più facile da usare e vendere di qualsiasi approccio di revisione.
Matthieu M.

10

Devo ammettere che lo prenderei come un regalo raro per arrivare a un progetto in cui hanno già un numero significativo di test unitari / di integrazione - finora non ho mai avuto quella fortuna nella mia vita. Anche se non tutti funzionano come dovrebbero, sono già stati fatti molti sforzi e anche se il team e il management non seguono sempre le migliori pratiche, tuttavia sono già impegnati nella causa, quindi tu non c'è bisogno di perdere tempo a discutere sul motivo per cui vale la pena scrivere unit test.

Tuttavia, i test così come li descrivi possono effettivamente migliorare. Ma devi stare attento con il tuo tono quando discuti i problemi con i tuoi compagni di squadra . Se inizi affermando che "tutto ciò che riguarda i test stessi è semplicemente sbagliato" , potresti finire molto presto per alienare il resto della squadra. Invece, dovresti concentrarti su come migliorare lo stato attuale delle cose, che - devo ripetere - è ancora significativamente migliore della media secondo la mia esperienza finora.

IMO il tuo primo obiettivo dovrebbe essere quello di impedire alla squadra di produrre altri test sbagliati . Quindi inizia dimostrando il vantaggio di ogni miglioramento specifico per i tuoi compagni di squadra. Se vedono l'utilità di una determinata tecnica, che si tratti di tagliare le dipendenze esterne, ripristinare lo stato originale dopo ogni test o separare i test di unità e integrazione, inizieranno ad applicarli. Questo di per sé migliorerà lentamente ma sicuramente la qualità complessiva della base di test a lungo termine (se hai 1000 casi di test errati ora, e il team produrrà 1000 buoni test entro il prossimo anno, avrai ridotto il rapporto dei test sbagliati dal 100% al 50%). Una volta assicurato, puoi decidere di eseguire il refactoring dei test esistenti caso per caso. Ancora una volta, piccoli miglioramenti si sommeranno a grandi cambiamenti nel tempo.

Come nota a margine, dal tono del tuo post sento che potresti essere in un posto dove ero anche una volta: non fidarmi del lavoro svolto da altri, incapace di delegare compiti a chiunque abbia paura del loro lavoro non essere all'altezza del tuo propri standard di qualità. Nella mia esperienza, questo non è un buon posto in cui stare, perché a lungo termine potrebbe facilmente portare a conflitti e esaurimenti personali. Non puoi fare tutto da solo, devi lavorare insieme al resto della squadra. Puoi solo avere successo insieme.


6

Lavorare per testare l'indipendenza. Se il test X modifica il database di test in modo tale che il test Y fallisca, allora cambia il test Y. In questo piccolo scenario la cosa su cui concentrarsi non è che X abbia incasinato il database, ma piuttosto che Y abbia dipendenze inadeguate. Rimuovere tali dipendenze (eliminando il database, ristrutturando il test o inizializzando il database su uno stato in cui Y passerà) e ora si dispone di un altro test funzionante indipendente. Questo è un progresso (probabilmente, "riparare" X per non rovinare il database non lo sarebbe).

Sii paziente e rispettoso, nel miglior modo possibile, delle persone con cui lavori, nonostante il disordine che hanno creato. Stanno cercando di fare la cosa giusta, con ogni probabilità; tienilo a mente e aiutali a farlo.


2
Avrei dovuto menzionare che nessuno dei creatori di pasticci originali è più qui. Non avevano voglia di affrontare il debito tecnico che hanno creato e sono passati.
maple_shaft

4
@maple_shaft: è bello che se ne siano andati ... puoi migliorare le cose senza che nessuno perda la faccia.
Kevin Cline,

2

La cosa buona dell'essere nuovi nel team è che hai un approccio "fresco" alle cose. La parte brutta potrebbe essere che gli altri potrebbero avere difficoltà a crederti.

Non fare un elenco di cose da fare. Ma scegli UNA cosa che sembra urgente e alla quale è più probabile che altri rispondano e suggerisci una soluzione. Se funziona, ottimo, quindi suggerisci un'altra soluzione a un altro problema, sulla base del tuo primo successo.

Ma prendi piano, uno per uno, e spera che le tue idee lentamente "prendano piede" nel nuovo gruppo.


2

dare l'esempio che si desidera vedere, ma apprezzare la prospettiva di un altro sviluppatore in un test: uno sviluppatore può verificare la presenza di esiti positivi, mentre un altro può verificare la presenza di errori, uno sviluppatore ha scritto la classe mentre un altro potrebbe averla usata la prima volta durante la scrittura del test.

i test esistenti (erm, la maggior parte) hanno ancora uno scopo, anche se potrebbe non essere immediatamente evidente. non consiglio di revisionare e refactoring tutto in una volta (è noioso e soggetto a errori). i test errati alla fine devono essere aggiornati, riscritti o potrebbero semplicemente diventare obsoleti con l'evoluzione del software.

se il tuo approccio ai test è superiore per alcuni aspetti, le persone impareranno da quel modello o ti chiederanno la tua assistenza. ci sarà un equilibrio di risorse, ma puoi estenderlo secondo necessità per supportare i tuoi test.

in definitiva, si desidera aumentare la qualità dei programmi tramite test e migliorare la copertura. puoi farlo ponendo maggiore enfasi sui test e dando il buon esempio, ma apprezzi le prospettive degli altri.

quando si sottolinea l'importanza, è possibile rendere diverso l'ambiente operativo dei test - un esempio evidente è quello di eseguire i test in parallelo; se non rientra, hai trovato un bug nel tuo programma o test (win / win). un ambiente di test più rigoroso costringerà a correggere e / o riscrivere i test errati (si spera nel modo giusto la seconda volta). introdurre lentamente tali cambiamenti (non interrompere la metà dei test tutti in una volta - questo è un vero problema), costringendoli a imparare cosa rende un buon test e, alla fine, un buon programma. quindi quando tu e gli altri partecipate e modificate / riparate / estendete i test, applicate ciò che avete appreso: è incrementale e avete una migliore comprensione del contesto / programma in quel momento.


2

Risolvili nel tempo

Sono stato nella stessa situazione. Ho appena trascorso un'ora ogni mattina sottoponendomi a test e riparandoli fino a quando non fossero stati tutti riparati. Era una base di codice di medie dimensioni e penso di aver finito in 1,5 mesi. Ho anche avuto molta più fiducia nei nostri test.

Personalmente non mi interessa se un test è un test unitario o un test di integrazione purché sia ​​un buon test. Con una buona prova intendo che:

  • pulisce dopo se stesso
  • è ripetibile
  • minimizza le interazioni ambientali
  • è consistente

Lungo la strada ho evangelizzato meglio i test di costruzione (vale a dire che ho infastidito molte persone).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.