Domanda

Come sviluppatore alle prime armi che sta entrando nel ritmo del mio primo progetto professionale, sto cercando di sviluppare buone abitudini il prima possibile.Tuttavia, ho scoperto che spesso mi dimentico di testare, rimandare o fare tutta una serie di test alla fine di una build invece che uno alla volta.

La mia domanda è: a quale ritmo ti piace entrare quando lavori su progetti di grandi dimensioni e in che modo si adattano i test.

È stato utile?

Soluzione

Beh, se vuoi seguire i ragazzi di TDD, prima di iniziare a programmare ;)

Sono più o meno nella tua stessa posizione.Voglio approfondire i test, ma attualmente sono in una posizione in cui stiamo lavorando per "ottenere il codice" piuttosto che "ottenere il codice giusto", il che mi spaventa a morte.Quindi sto lentamente cercando di integrare i processi di test nel mio ciclo di sviluppo.

Attualmente, Provo mentre scrivo, cercando di decifrare il codice mentre lo scrivo.Trovo difficile entrare nella mentalità TDD..Ci vuole tempo, ma lo farei così Volere lavorare..

MODIFICARE:

Ho pensato che probabilmente avrei dovuto approfondire questo argomento, questo è il mio "processo lavorativo" di base...

  1. Pianifica ciò che voglio dal codice, possibile progettazione di oggetti, qualunque cosa.
  2. Crea la mia prima classe, aggiungi un enorme commento alla parte superiore delineando quale sia la mia "visione" per la classe.
  3. Descrivere gli scenari di test di base.Questi diventeranno sostanzialmente i test unitari.
  4. Crea il mio primo metodo..Anche scrivendo un breve commento che spiega com'è previsto lavorare.
  5. Scrivi un test automatizzato per vedere se fa quello che mi aspetto.
  6. Ripeti i passaggi 4-6 per ciascun metodo (nota che i test automatizzati si trovano in un elenco enorme che viene eseguito su F5).
  7. Creo quindi alcuni test robusti per emulare la classe nell'ambiente di lavoro, risolvendo ovviamente eventuali problemi.
  8. Se in seguito vengono alla luce nuovi bug, torno indietro e scrivo il nuovo test, mi assicuro che fallisca (questo serve anche come prova di concetto per il bug) quindi lo risolvo.

Spero che aiuti..Aperto a commenti su come migliorare questo, come ho detto è una mia preoccupazione..

Altri suggerimenti

Prima di controllare il codice.

Prima e spesso.Se sto creando nuove funzionalità per il sistema, cercherò di definire inizialmente le interfacce e quindi di scrivere test unitari per tali interfacce.Per capire quali test scrivere, considera l'API dell'interfaccia e le funzionalità che fornisce, prendi carta e penna e pensa per un po' alle potenziali condizioni di errore o ai modi per dimostrare che sta facendo il lavoro corretto.Se questo è troppo difficile, è probabile che la tua API non sia abbastanza buona.Per quanto riguarda i test, vedi se puoi evitare di scrivere test di "integrazione" che testano più di un oggetto specifico e mantenerli come test "unitari".

Quindi crea un'implementazione predefinita della tua interfaccia (che non fa nulla, restituisce valori spazzatura ma non genera eccezioni), collegala ai test per assicurarti che i test falliscano (questo verifica che i tuoi test funzionino!:)).Quindi scrivere la funzionalità ed eseguire nuovamente i test.Questo meccanismo non è perfetto ma coprirà molti semplici errori di codifica e ti offrirà l'opportunità di eseguire la tua nuova funzionalità senza doverla collegare all'intera applicazione.

Successivamente sarà necessario testarlo nell'applicazione principale con la combinazione delle funzionalità esistenti.È qui che i test sono più difficili e, se possibile, dovrebbero essere parzialmente affidati a un buon tester del controllo qualità poiché avranno l'abilità di rompere le cose.Anche se aiuta se hai anche queste abilità.Eseguire correttamente i test è un talento che devi acquisire a dire il vero.La mia esperienza deriva dalle mie ingenue implementazioni e dai successivi bug segnalati dagli utenti quando lo usavano con rabbia.

All'inizio, quando mi è successo, ho trovato irritante che l'utente stesse intenzionalmente tentando di rompere il mio software e volevo contrassegnare tutti i "bug" come "problemi di formazione".Tuttavia, dopo averci riflettuto, mi sono reso conto che è nostro ruolo (come sviluppatori) rendere l'applicazione il più semplice e affidabile possibile da usare anche da parte degli idioti.Il nostro ruolo è dare potere agli idioti ed è per questo che veniamo pagati tanto.Gestione idiota.

Per testare efficacemente in questo modo devi entrare nella mentalità di provare a rompere tutto.Assumi il ruolo di un utente che preme i pulsanti e generalmente tenta di distruggere la tua applicazione in modi strani e meravigliosi.Partite dal presupposto che se non trovate difetti, questi verranno scoperti nella produzione e la vostra azienda perderà seriamente la reputazione.Assumiti la piena responsabilità per tutti questi problemi e maledici te stesso quando un bug di cui sei responsabile (o anche parzialmente responsabile) viene scoperto in produzione.

Se esegui la maggior parte delle operazioni precedenti, dovresti iniziare a produrre un codice molto più robusto, tuttavia è un po' una forma d'arte e richiede molta esperienza per essere bravo.

Una buona chiave da ricordare è

"Testa presto, prova spesso e prova ancora, quando pensi di aver finito"

Quando fare il test?Quando è importante che il codice funzioni correttamente!

Quando creo qualcosa insieme per me, alla fine faccio un test.Cattiva pratica, ma di solito sono piccole cose che userò alcune volte e basta.

In un progetto più ampio, scrivo dei test prima di scrivere una classe ed eseguo i test dopo ogni modifica a quella classe.

Provo costantemente.Anche dopo aver terminato un ciclo all'interno di una funzione, eseguo il programma e raggiungo un punto di interruzione nella parte superiore del ciclo, quindi lo eseguo.Tutto questo è solo per assicurarmi che il processo stia facendo esattamente quello che voglio.

Quindi, una volta terminata una funzione, la si testa nella sua interezza.Probabilmente vorrai impostare un punto di interruzione appena prima che venga chiamata la funzione e controllare il debugger per assicurarti che funzioni perfettamente.

Immagino che direi:"Prova spesso."

Solo di recente ho aggiunto test unitari al mio flusso di lavoro regolare, ma scrivo test unitari:

  • per esprimere i requisiti per ogni nuovo modulo di codice (subito dopo aver scritto l'interfaccia ma prima di scrivere l'implementazione)
  • ogni volta che penso "era meglio..."quando avrò finito"
  • quando qualcosa si rompe, per quantificare il bug e dimostrare di averlo risolto
  • quando scrivo codice che alloca o dealloca esplicitamente la memoria, detesto andare a caccia di perdite di memoria...

Eseguo i test sulla maggior parte delle build e sempre prima di eseguire il codice.

Inizia con i test unitari.Nello specifico, dai un'occhiata a TDD, Test Driven Development.Il concetto alla base di TDD è che scrivi prima i test unitari, quindi scrivi il tuo codice.Se il test fallisce, torni indietro e rielabora il tuo codice.Se passa si passa a quello successivo.

Adotto un approccio ibrido al TDD.Non mi piace scrivere test contro il nulla, quindi di solito scrivo prima parte del codice e poi inserisco i test unitari.È un processo iterativo, con il quale non hai mai veramente finito.Cambia il codice, esegui i test.Se si verificano errori, correggi e ripeti.

L'altro tipo di test è il test di integrazione, che avviene più avanti nel processo e in genere potrebbe essere eseguito da un team di test QA.In ogni caso, il test di integrazione risponde alla necessità di testare i pezzi nel loro insieme.È il prodotto funzionante che ti interessa testare.Questo è più difficile da gestire perché di solito implica la presenza di strumenti di test automatizzati (come Robot, ad esempio).

Inoltre, dai un'occhiata a un prodotto come CruiseControl.NET per eseguire build continue.CC.NET è carino perché eseguirà i test unitari con ogni build, avvisandoti immediatamente di eventuali errori.

Non eseguiamo TDD qui (anche se alcuni lo hanno sostenuto), ma la nostra regola è che dovresti controllare i test unitari con le modifiche.Non succede sempre, ma è facile tornare indietro e guardare un changeset specifico e vedere se sono stati scritti o meno dei test.

Trovo che se aspetto fino alla fine della scrittura di qualche nuova funzionalità da testare, dimentico molti dei casi limite che pensavo potessero interrompere la funzionalità.Questo va bene se stai facendo cose per imparare da solo, ma in un ambiente professionale, trovo che il mio flusso sia la forma classica di:Rosso, Verde, Refactoring.

Rosso:Scrivi il tuo test in modo che fallisca.In questo modo sai che il test si sta affermando rispetto alla variabile corretta.

Verde:Supera il tuo nuovo test nel modo più semplice possibile.Se questo significa codificarlo, va bene.Questo è ottimo per coloro che vogliono semplicemente che qualcosa funzioni subito.

Refactoring:Ora che il test viene superato, puoi tornare indietro e modificare il codice in tutta sicurezza.La tua nuova modifica ha rotto il tuo test?Ottimo, il tuo cambiamento ha avuto un'implicazione di cui non ti rendevi conto, ora il tuo test te lo dice.

Questo ritmo mi ha fatto accelerare il mio sviluppo nel tempo perché fondamentalmente ho un compilatore di cronologia per tutte le cose che pensavo dovessero essere controllate affinché una funzionalità funzionasse!Questo, a sua volta, porta a molti altri vantaggi, di cui non parlerò qui...

Ci sono un sacco di ottime risposte qui!

Provo a testare al livello più basso che abbia senso:

  • Se un singolo calcolo o condizionale è difficile o complesso, aggiungi il codice di prova mentre lo scrivi e assicurati che ogni pezzo funzioni.Commenta il codice di test quando hai finito, ma lascialo lì per documentare come hai testato l'algoritmo.

  • Testare ogni funzione.

    • Esercita ogni ramo almeno una volta.
    • Esercita il condizioni al contorno -- valori di input in corrispondenza dei quali il codice cambia il suo comportamento -- per rilevare errori "fuori di uno".
    • Testare varie combinazioni di input validi e non validi.
    • Cerca situazioni che potrebbero infrangere il codice e testale.
  • Testare ogni modulo con la stessa strategia di cui sopra.

  • Testare il corpo del codice nel suo complesso, per garantire che i componenti interagiscano correttamente.Se sei stato diligente nei test di livello inferiore, questo è essenzialmente un "test di fiducia" per garantire che nulla si rompa durante l'assemblaggio.

Poiché la maggior parte del mio codice è per dispositivi incorporati, presto particolare attenzione alla robustezza, all'interazione tra vari thread, attività e componenti e all'uso imprevisto delle risorse:memoria, CPU, spazio nel file system, eccetera.

In generale, prima si riscontra un errore, più facile sarà isolarlo, identificarlo e correggerlo e più tempo si potrà dedicare alla creazione, invece che a rincorrersi.*

**Lo so, -1 per il riferimento gratuito al puntatore del buffer!*

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top