È necessario mantenere i test per funzioni semplici (autonome)?

36

Considera questo:

public function polynominal($a, $b, $c, $d)
{
    return  $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}

Supponi di scrivere vari test per la funzione sopra descritta e dimostrare a te stesso e agli altri che "funziona".

Perché allora non rimuovere quei test e vivere felici e contenti? Il mio punto è che alcune funzioni non hanno bisogno di essere continuamente testate dopo che hanno dimostrato di funzionare. Sto cercando contatori che affermano, sì, queste funzioni devono ancora essere testate, perché: ... O che sì, questi non hanno bisogno di essere testati ...

    
posta Dennis 18.08.2015 - 00:04
fonte

7 risposte

78

Test di regressione

Si tratta di test di regressione .

Immagina il prossimo sviluppatore che osserva il tuo metodo e nota che stai usando numeri magici. Gli è stato detto che i numeri magici sono malvagi, quindi crea due costanti, una per il numero due, l'altra per il numero tre: non c'è nulla di sbagliato nel fare questo cambiamento; non è come se stesse modificando la tua implementazione già corretta.

Essendo distratto, inverte due costanti.

Esegue il commit del codice e tutto sembra funzionare correttamente, perché non ci sono test di regressione in esecuzione dopo ogni commit.

Un giorno (potrebbe essere settimane dopo), qualcosa si rompe altrove. E altrove, voglio dire nella posizione completamente opposta del codice di base, che sembra non avere nulla a che fare con la funzione polynominal . Le ore di debugging doloroso portano al colpevole. Durante questo periodo, l'applicazione continua a fallire nella produzione, causando molti problemi ai tuoi clienti.

Mantenere i test originali che hai scritto potrebbe prevenire questo tipo di dolore. Lo sviluppatore distratto avrebbe impegnato il codice e quasi immediatamente avrebbe visto che aveva rotto qualcosa; tale codice non raggiungerà nemmeno la produzione. I test unitari saranno inoltre molto precisi sulla posizione dell'errore . Risolvere il problema non sarebbe difficile.

Un effetto collaterale ...

In realtà, la maggior parte del refactoring è strongmente basata sui test di regressione. Fai un piccolo cambiamento. Test. Se passa, va tutto bene.

L'effetto collaterale è che se non hai test, praticamente qualsiasi refactoring diventa un enorme rischio di rompere il codice. Dato che sono molti i casi, è già difficile spiegare alla direzione che il refactoring dovrebbe essere fatto, sarebbe ancora più difficile farlo dopo che i precedenti tentativi di refactoring hanno introdotto più bug.

Avendo una suite completa di test, sei incoraggiante nel rifattorizzare, e quindi in un codice migliore. Senza rischi, diventa molto allettante per il refactoring di più, su base regolare.

Modifiche ai requisiti

Un altro aspetto essenziale è che i requisiti cambiano. Potrebbe essere richiesto per gestire numeri complessi e, improvvisamente, devi cercare il registro di controllo della versione per trovare i test precedenti, ripristinarli e iniziare ad aggiungere nuovi test.

Perché tutto questo fastidio? Perché rimuovere i test per aggiungerli in seguito? Potresti averli tenuti al primo posto.

    
risposta data 18.08.2015 - 00:31
fonte
45

Perché nulla è così semplice da non poter essere bug.

Il tuo codice, mentre a prima vista sembra privo di bug. È in effetti una semplice rappresentazione programmatica di una funzione polinomiale.

Tranne che ha un bug ...

public function polynominal($a, $b, $c, $d)
{
    return  $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}

$x non è definito come input per il tuo codice e, a seconda della lingua o del runtime, o dell'ambito, la tua funzione potrebbe non funzionare, potrebbe causare risultati non validi o può causare l'arresto anomalo di un'astronave .

Addendum:

Sebbene tu possa considerare il tuo codice privo di bug per ora, quanto a lungo rimane difficile da dire. Mentre si potrebbe obiettare che scrivere un test per un pezzo di codice così banale non vale la pena, avendo già scritto il test il lavoro è stato fatto e l'eliminazione sta cancellando una guardia sicura tangibile.

Di ulteriore nota sono i servizi di copertura del codice (come coveralls.io) che forniscono una buona indicazione della copertura fornita da una suite di test. Coprendo ogni riga di codice si fornisce una metrica decente della quantità (se non la qualità) dei test eseguiti. In combinazione con molti piccoli test, questi servizi ti dicono almeno dove non cercare un bug quando succede.

In definitiva, se hai già un test scritto, tienilo . Poiché lo spazio o il tempo impiegato per eliminarlo sarà probabilmente molto inferiore rispetto al debito tecnico in seguito, se si presentasse un errore.

    
risposta data 18.08.2015 - 07:41
fonte
21

Sì. Se potessimo dire con sicurezza al 100%, con certezza: questa funzione non verrà mai modificata e non verrà mai eseguita in un contesto che potrebbe causarne il fallimento - se potessimo dire che potremmo abbandonare i test e salvare qualche millisecondo su ogni Build CI.

Ma non possiamo. Oppure, non possiamo con molte funzioni. Ed è più semplice avere una regola per eseguire tutti i test tutto il tempo che per mettere alla prova esattamente quale soglia di confidenza ci soddisfa, e esattamente quanta fiducia abbiamo nell'immutabilità e infallibilità di ogni funzione data.

E il tempo di elaborazione è economico. Quei millisecondi risparmiati, anche moltiplicati molte volte, non si sommano quasi per giustificare il tempo necessario per ogni funzione da chiedere: abbiamo sufficiente fiducia che non è necessario testarlo di nuovo?

    
risposta data 18.08.2015 - 00:29
fonte
12

Tutto ciò che è stato detto nelle altre risposte è corretto, ma ne aggiungerò un altro.

Documentazione

I test unitari, se ben scritti, possono spiegare a uno sviluppatore esattamente cosa fa una funzione, quali sono le sue aspettative di input / output e, cosa ancora più importante, quale comportamento ci si può aspettare da esso.

Può rendere più facile individuare un bug e ridurre la confusione.

Non tutti ricordano polinomi, geometria o persino algebra :) Ma un buon test unitario registrato per il controllo della versione si ricorderà per me.

Per un esempio di quanto possa essere utile come documentazione, guarda l'introduzione di Jasmine: link Dagli alcuni secondi per caricare, quindi scorrere verso il basso. Vedrai l'intera API Jasmine documentata come output di test unitario.

[Aggiornamento basato sul feedback di @Warbo] I test sono garantiti come aggiornati, poiché se non lo sono, falliranno, il che generalmente causerà un errore di compilazione se viene utilizzato l'elemento della configurazione. La documentazione esterna cambia indipendentemente dal codice e pertanto non è necessariamente aggiornata.

    
risposta data 18.08.2015 - 04:04
fonte
2

Controllo di realtà

Sono stato in ambienti difficili in cui il testing è "una perdita di tempo" durante la pianificazione e il budget, e quindi "una parte fondamentale dell'assicurazione qualità" una volta che il cliente ha a che fare con bug, quindi la mia opinione è più fluida di altre essere.

Hai un budget. Il tuo compito è ottenere il miglior prodotto possibile su quel budget, per qualunque definizione di "migliore" che puoi racimolare (non è una parola facile da definire). Fine della storia.

Il test è uno strumento nel tuo inventario. Dovresti usarlo, perché è uno strumento utile , con una lunga storia di risparmio di milioni, o forse addirittura di miliardi di dollari. Se viene data una possibilità, è necessario aggiungere test a queste semplici funzioni. Potrebbe salvarti la pelle un giorno.

Ma nel mondo reale, con limiti di budget e di pianificazione, potrebbe non succedere. Non farti schiavo della procedura. Le funzioni di test sono buone, ma a un certo punto, le ore lavorative potrebbero essere meglio impiegate a scrivere la documentazione per sviluppatori in parole, piuttosto che in codice, quindi il prossimo sviluppatore non ha più bisogno dei test. Oppure potrebbe essere meglio spendere refactoring della base di codice in modo da non dover mantenere come difficile di una bestia. O forse è meglio spendere quel tempo per parlare con il tuo capo del budget e degli orari in modo che lui o lei capisca meglio cosa stanno chiedendo quando il prossimo round di finanziamenti arriverà.

Lo sviluppo del software è un equilibrio. Conta sempre il costo opportunità di qualsiasi cosa tu stia facendo per assicurarti che non ci fosse un modo migliore per passare il tuo tempo.

    
risposta data 18.08.2015 - 17:50
fonte
0

Sì, mantieni i test, mantienili in esecuzione e mantienili passare.

I test unitari sono lì per proteggere te (e gli altri) da te stesso (e loro stessi).

Perché mantenere i test una buona idea

  • Convalidare la funzionalità dei requisiti precedenti in base ai nuovi requisiti e alle funzionalità aggiuntive
  • Verifica che gli esercizi di refactoring siano corretti
  • Documentazione interna - questo è il modo in cui il codice dovrebbe essere usato
  • Test di regressione, le cose cambiano
    • Le modifiche interrompono il vecchio codice?
    • Le modifiche richiedono ulteriori richieste di modifica o aggiornamenti alle funzioni o al codice corrente?
  • Dato che i test sono già stati scritti, conservali; è tempo e denaro già speso che ridurrà i costi di manutenzione più avanti sulla linea
risposta data 18.08.2015 - 11:19
fonte
-1

Documentazione per gli sviluppatori

  • Come faccio a sapere (come un altro sviluppatore) che questo è stato testato?
  • Se voglio correggere un bug nella funzione self contained , come faccio a sapere che non sto introducendo un bug che avevi già preso in considerazione?
  • Indicatore di complessità: il numero di test può essere una buona misura di quanto sia complesso qualcosa. Questo potrebbe indicare che non dovresti toccarlo perché è maturo e stabile o gonfiato e accoppiato.

Documentazione utente

  • In attesa di un documento scarso, posso controllare se {zero, valori negativi, set vuoti, ecc.} sono accettati e quale è il valore restituito previsto.
  • Fornisce anche un buon esempio di come dovrei usare l'oggetto / funzione
risposta data 18.08.2015 - 23:17
fonte

Leggi altre domande sui tag