Come utilizzeresti TDD per ottenere il processo corrispondente di un servizio Windows in esecuzione?

6

Scopo

Nell'ultimo anno o più ho imparato i test unitari tramite libri che ho letto di recente come The Art of Unit Testing , Funzionante in modo efficace con il codice legacy , e altri. Ho anche utilizzato test unitari, strutture di simulazione e simili, periodicamente al lavoro e sicuramente ne vedo il valore.

Tuttavia, sto ancora avendo difficoltà a ricomporre la mia mente su TDD (al contrario di TAD) quando la situazione richiede il codice che utilizza principalmente le chiamate API esterne.

Problema da risolvere

Ottieni il processo associato a un servizio di Windows utilizzando il nome del servizio.

esempio: Function GetProcess(ByVal serviceName As String) As Process

Regole

  • Mostra le principali iterazioni in produzione e amp; codice di prova con TDD
    • Non c'è bisogno di vedere nessun altro codice o configurazione necessaria per far funzionare le cose. Solo curiosità sulle interfacce, sulle classi concrete e sui metodi di test.
  • C # o VB.NET
  • Deve usare la struttura .Net per servizi / processi (cioè System.Diagnostics.Process )
  • Framework di test:
    • Nunit o MSTest
  • Quadri di isolamento:
    • Moq, Rhino Mock o Microsoft Moles
  • Deve scrivere test di unità reali (nessun test di integrazione)

Note aggiuntive

Per quanto posso dire, ci sono due approcci di design saggio.

  1. Utilizzare un approccio di Inversion of Control insieme all'utilizzo dei modelli Adapter e / o Facade per avvolgere gli oggetti framework .net sottostanti che trattano processi e servizi.
  2. Mantenere il codice .net framework nella classe contenente il metodo Get Process e utilizzare il code detouring (intercettazione) tramite Microsoft Moles per isolare le dipendenze dal metodo in prova.
posta Matt 10.02.2011 - 21:01
fonte

2 risposte

5

Non sono sicuro di capire perché vuoi farlo (a parte affrontare una sfida intellettuale). Questo tipo di codice, in cui si lavora direttamente con alcune API a livello di sistema, è molto difficile da testare in unità, stile TDD o meno, e per essere sincero, non trovo molto prezioso provarlo in un progetto reale.

Gran parte dell'attività che descrivi chiama il giusto metodo API di basso livello con il parametro giusto. E il resto del codice può essere così banale, non necessariamente garantire l'introduzione di un'interfaccia dedicata, oggetti fittizi, ecc. Sarei contento di avere un test di integrazione per verificare a un livello più alto che tutto funzioni. Ma questo è solo il mio 2 centesimi.

Il test delle unità per me non riguarda il seguire libri di regole o definizioni rigorose. Nella vita reale, non mi interessa davvero che i miei test siano test di unità "reali" o meno; Finché il mio codice è coperto da test automatici e ripetibili, sto bene. Preferisco l'approccio pragmatico.

    
risposta data 10.02.2011 - 21:14
fonte
2

Arriva un certo livello in cui non è possibile separare l'unità da una risorsa di sistema. Quando sviluppi un sistema che usa TDD, manterrai quella quantità di codice più piccola e contenuta possibile. In questo caso, potresti iniziare con un concetto chiamato IProcessManager . Questo concetto non è altro che un'interfaccia che definirà il GetProcess e altri metodi relativi ai processi necessari.

interface IProcessManager {
    Process GetProcess(string processName);
}

"Perché un'interfaccia?", chiedi. Perché le interfacce sono più facili da deridere delle funzioni globali. Lo scopo di prendere in giro il gestore dei processi è quello di garantire che tutto il codice che utilizza questa funzione si comporti correttamente nelle diverse condizioni di errore che possono verificarsi. Cosa succede quando non c'è nessun processo con il nome fornito? Cosa succede quando processName è null ? La tua finta implementazione di IProcessManager può facilmente ricreare queste condizioni per te.

L'altro lato della medaglia, il vero processo di implementazione del comportamento che ti aspetti è ora molto ben definito e il tuo problema è ben contenuto. È possibile scrivere l'implementazione senza test o almeno scrivere test per le condizioni che è possibile prevedere e controllare. Ad esempio, se è possibile rilevare il nome del processo attualmente in esecuzione in fase di esecuzione, è possibile scrivere un test per scoprire che Process con il nome. Inoltre, dovresti riuscire a trovare un nome di processo illegale e uno che non esisterà mai.

Comprendi che ci saranno alcune parti che semplicemente non possono essere testate correttamente. Puoi solo fare ciò che puoi per limitare la possibilità che le cose vadano storte.

    
risposta data 10.02.2011 - 21:32
fonte

Leggi altre domande sui tag