Devo testare il ramo di debug del mio codice in un test unitario?

2

Diciamo che ho una funzione che ottiene un elenco di quali file inviare che verranno successivamente inviati su un altro PC. Ora di solito tengo traccia di quali file sono stati inviati e non invio di nuovo questi file. Per semplificare la codifica e il debug, ho questo:

if debug:
   files_to_send = os.listdir()
   files_to_send.remove(files_sent_log)

altrimenti dovrei cancellare il log ogni volta che voglio rieseguire il programma.

Un altro esempio: di solito vorrei che i file vengano cancellati dopo che sono stati ricevuti. Ma per il debug voglio che restino sul mittente, per questo io uso:

if not debug:
   os.remove(file)

Ora la mia domanda dovrebbe essere verificata? La mia intuizione è no, dal momento che è utilizzata solo per aiutarmi ma non utilizzata in seguito quando il cliente utilizza il codice.

Sto usando python e questo codice rimane nella versione di produzione e può essere attivato con un flag in un file di configurazione. In parte è anche l'idea di avere solo messaggi importanti nel log quando il debug è disattivato e molti messaggi di debug quando è attivo.

    
posta Hakaishin 20.06.2018 - 11:58
fonte

3 risposte

5

Se capisci correttamente, stai facendo qualcosa del genere:

public void SendFiles()
{
   var files = _sendDirectory.ListFiles();

   #IF DEBUG
     RemoveTempTextFile();
     CreateFileListingFileNamesToTempTextFile(files);
   #END DEBUG

   foreach(var file in files)
   {
      SendFile(file);
   }
}

Vedo un paio di problemi con questo approccio.

  • La compilazione condizionale è uno strumento potente ma, non appena lo inserisci, c'è una differenza tra ciò che stai lavorando e ciò che stai offrendo ai tuoi clienti. In questo caso non dovrebbe fare molta differenza, ma quando stai sviluppando dovresti sempre pensare di mantenere il tuo codice il più gestibile possibile.
  • Se tutti gli sviluppatori rilasciano file di debug casuali su tutta la soluzione, finirai con un casino quando si tratta di estrarre tutte queste informazioni. È meglio avere un processo standard seguito da tutti.
  • I test delle unità di scrittura (come hai menzionato nei test nella tua domanda) saranno molto difficili. Questo codice non sarà nelle build provenienti dal tuo server di build (che è il posto più prezioso dove eseguire i test di unità) quindi a meno che non stai per fare test di unità di compilazione condizionali ... schifo, sto fermando quell'idea lì!
  • Se questa informazione ti è utile per lo sviluppo potrebbe essere utile per qualcuno che diagnostica i problemi nella produzione. Perché privarli di dati che renderebbero la vita più facile?

Il mio suggerimento sarebbe fare qualcosa del genere:

public void SendFiles()
{
   var files = _sendDirectory.ListFiles();
   foreach(var file in files)
   {
      try
      {
        _logging.Info($"Sending {file} from {_sendDirectory} to remote server"};
        SendFile(file);
      }
      catch(Exception ex)
      {
        _logging.Error(ex, $"There was an error sending {file} from {_sendDirectory} to remote server"};
      }
   }
}

Questo non solo rimuove la compilazione condizionale ma fornisce maggiori informazioni che potrebbero essere utilizzate per diagnosticare potenziali problemi nella produzione. Per rispondere alla tua domanda originale (sui test) se _log è una specie di oggetto ILog (in .NET io userei NLog o Log4Net), allora è molto facile da DI e unit test che i messaggi (e forse ancora più importante) errori) sono registrati.

    
risposta data 20.06.2018 - 12:44
fonte
1

L'idea è giusta, ma la configurazione (o meglio, la denominazione nella configurazione) è errata. Avere un'opzione per consentire ai file di essere conservati sulla macchina di invio potrebbe essere vista come una funzionalità, e non solo come aiuto durante il debug. Quindi, cambia il tuo codice in:

if not configuration.keep_files:
   os.remove(file)

Funzionalmente, il codice è lo stesso poiché hai detto che il tuo valore debug era una parte della configurazione. Ma l'intento è più chiaro e hai aggiunto valore per i tuoi utenti.

Puoi fare una modifica simile per l'altro bit di codice per escludere l'invio di file che sono già stati inviati:

if not configuration.send_log:
   files_to_send.remove(files_sent_log)

Questo disaccoppia i due pezzi di codice in modo che possano essere configurati separatamente, e può quindi essere facilmente ampliato. Ad esempio, potresti voler escludere anche altri file o tipi di file - aggiungi semplicemente un altro parametro (o parametri) alla tua configurazione e il tuo codice si espande facilmente:

if not configuration.send_log:
   files_to_send.remove(files_sent_log)
if not configuration.send_txt_files:
   files_to_send.remove(all_txt_files)
if not configuration.send_dll_files:
   files_to_send.remove(all_dll_files)

Ora puoi testare liberamente ognuna di queste configurazioni poiché queste sono configurazioni che verranno fornite con il prodotto e che gli utenti potrebbero effettivamente utilizzare. Non preoccuparti delle differenze tra il codice testato e il codice di rilascio.

    
risposta data 20.06.2018 - 17:41
fonte
1

Quindi c'è una funzionalità nel tuo codice che è esclusivamente per te, nessun altro, e solo tu puoi attivarla (sì, è una funzione di "debug", ma penso che aiuti a non focalizzarti su quel termine e guardare come una caratteristica normale per un utente). Se vuoi decidere se vale la pena di essere testato (automaticamente), devi chiedere quale sia il più grande rischio se la funzione ha un bug:

  • se il bug crea un evidente malfunzionamento, potresti essere costretto a correggerlo prima di poterlo utilizzare. Ma dal momento che hai tutto sotto il tuo controllo, questo non dovrebbe infastidirti, puoi sistemarlo proprio nel momento in cui ne hai bisogno.

  • se il bug crea un problema non ovvio, direi che dipende molto dai dettagli su cosa succede e quanto è importante che ciò non si verifichi

Per l'esempio dato di una funzione per la gestione di alcuni log di debug, è IMHO abbastanza improbabile che un malfunzionamento non venga rilevato, e anche se è così, immagino che il potenziale impatto sia piuttosto basso. Per altre caratteristiche simili, la situazione potrebbe essere diversa.

Si noti inoltre che se si aggiunge una funzione di debug di questo tipo, la funzionalità stessa potrebbe non valere la pena di creare un test automatico, ma potrebbe essere utile verificare che la funzione rimanga correttamente invisibile quando è configurata per la disattivazione. Quindi potrebbe valere la pena testare che in modalità non-debug i file di log siano veramente cancellati.

    
risposta data 20.06.2018 - 19:51
fonte

Leggi altre domande sui tag