2009-02-25 23 views
9

Tutti i progetti su cui lavoro si interfacciano con un componente hardware e questo è spesso lo scopo principale del software. Esistono modi efficaci per applicare TDD al codice che funziona con l'hardware?Come fare TDD con l'hardware

Aggiornamento: Mi dispiace per non essere più chiaro con la mia domanda.

L'hardware che utilizzo è un frame grabber che cattura le immagini da una telecamera. Elaborare quindi queste immagini, visualizzarle e salvarle sul disco. Posso simulare tutte le elaborazioni che avvengono dopo che le immagini sono state acquisite utilizzando immagini precedentemente acquisite che sono memorizzate su disco.

Ma è l'effettiva interazione con l'hardware che voglio testare. Ad esempio, il mio software fa fronte correttamente quando non c'è una telecamera collegata, inizia correttamente e smette di afferrare ecc. Ma questo è così legato all'hardware che non so come testarlo quando l'hardware non è presente o se dovessi anche provare a farlo?

2 ° Aggiornamento: Sto anche cercando alcuni esempi concreti di come le persone hanno affrontato questa situazione.

+0

La tua domanda riguarda solo la verifica del codice che si interfaccia con l'hardware o anche di testare l'hardware in questo modo? – OregonGhost

+0

Entrambi credo, ma il mio codice che interagisce con l'hardware è piuttosto sottile. Fa semplicemente chiamate nella libreria di terze parti che controlla effettivamente l'hardware. –

+0

Il vero nodo di questo problema è che se l'hardware in questione poteva essere completamente descritto nel software, non sarebbe necessario l'hardware. : P – meawoppl

risposta

3

Split vostra suite di test in due parti:

  1. La prima parte esegue test contro l'hardware reale. Questa parte è usata per costruire i prototipi. Scrivendo test automatici per questo, puoi eseguirli di nuovo se hai qualche dubbio che i tuoi prototipi funzionino correttamente.

  2. La seconda parte va contro i prototipi. Questa parte viene eseguita automaticamente.

La parte 1 viene eseguita manualmente dopo aver verificato che l'hardware sia cablato correttamente, ecc.Una buona idea è quella di creare una serie di test che corrano contro qualcosa restituito dalla fabbrica ed eseguire questi test due volte: una volta con una fabbrica che restituisce il vero "driver" e una volta contro la fabbrica dei tuoi oggetti finti. In questo modo, si può essere sicuri che i vostri deride funzionano esattamente come la cosa reale:

class YourTests extends TestCase { 
    public IDriver getDriver() { return new MockDriver(); } 
    public boolean shouldRun() { return true; } 
    public void testSomeMethod() throws Exception { 
     if (!shouldRun()) return; // Allows to disable all tests 
     assertEquals ("1", getDriver().someMethod()); 
    } 
} 

Nel mio codice, io di solito uso una proprietà di sistema (-Dmanual = yes) per alternare i test manuali:

class HardwareTests extends YourTests { 
    public IDriver getDriver() { return new HardwareDriver(); } 
    public boolean shouldRun() { return "yes".equals (System.getProperty("manual")); } 
} 
0

Se si dispone di un simulatore, è possibile scrivere test sul simulatore ed eseguire questi test sull'hardware.

E 'difficile rispondere alle domande con così poco dettaglio :-)

+0

Scusate per quello, ero un po 'vago. Ho messo qualche informazione in più nella domanda, è di questo aiuto? –

1

Mock abilmente.

+0

+1 Quando stavo lavorando su dispositivi embedded questa è la strada che abbiamo intrapreso. –

+3

Hai qualche esempio di come faccio questo? Ad esempio, come faccio a prendere in giro ciò che è fondamentalmente un driver di periferica, posso scrivere il mio simulatore che produce gli eventi/errori che potrebbero verificarsi? –

4

Se si sta scrivendo software per manipolare dati provenienti da un hardware specializzato, è possibile creare ragionevolmente supporti per l'hardware per testare il software.

Se l'interfaccia hardware è qualcosa di semplice come una porta seriale, è possibile utilizzare facilmente un cavo loop-back per far dialogare il programma con l'hardware di simulazione. Ho usato questo approccio alcuni anni fa quando scrivevo un software per parlare con un elaboratore di crediti. La mia app di test è stata data per pensare che il mio simulatore fosse un modem e un processore di back-end.

Se si stanno scrivendo driver di periferica PCI o software di livello equivalente, probabilmente non è possibile creare un supporto software.

L'unico buon modo per applicare TDD a tali problemi è se si è in grado di falsificare l'I/O dell'hardware con un altro programma. Ad esempio, lavoro con la gestione delle carte di credito per le stazioni di servizio. Sul mio attuale progetto abbiamo un simulatore che è l'elettronica della pompa agganciata ad alcuni interruttori in modo tale che sia possibile simulare il funzionamento di una pompa (maniglia di sollevamento, grilletto, flusso di carburante). È abbastanza immaginabile che potremmo avere un simulatore costruito controllabile via software.

In alternativa, a seconda del dispositivo, è possibile utilizzare apparecchiature di prova standard (generatori di segnale, ecc.) Per alimentare gli "ingressi noti".

Si noti che questo ha il problema che si sta testando sia l'hardware sia i driver di dispositivo. Sfortunatamente, questa è davvero l'unica buona scelta che hai in questa fase - Qualsiasi hardware simulato sarà probabilmente abbastanza diverso dall'apparecchiatura reale che sarà inutile da testare.

+0

Grazie per le informazioni, sì, con l'ultima parte. Ho faticato con il TDD contro l'hardware, dal momento che prendere in giro sembra inutile perché non stai davvero testando l'hardware. –

2

Probabilmente non è una buona idea includere test che accedono all'hardware nella vostra suite di test. Uno dei problemi con questo approccio è che i test potranno essere eseguiti solo su una macchina collegata a questo particolare componente hardware, il che rende difficile l'esecuzione dei test come parte di un processo di compilazione automatica (notturno).

Una soluzione potrebbe essere quella di scrivere alcuni moduli software che si comportano come i moduli hardware mancanti, almeno dal punto di vista dell'interfaccia. Quando si esegue la suite di test, accedere a questi moduli software anziché all'hardware reale.

Mi piace anche l'idea di dividere la suite di test in due parti:

  • uno che accede l'hardware reale, che si esegue manualmente
  • uno che accede ai moduli software, che viene eseguito come parte di il test automatico

In base alla mia esperienza, i test che coinvolgono l'hardware reale richiedono quasi sempre una certa quantità di interazione manuale (ad es. collegare qualcosa dentro e fuori per vedere se viene rilevato correttamente), il che rende molto difficile automatizzare. I benefici spesso non valgono la pena.

+0

Già, non sarò in grado di configurare l'hardware sul computer di costruzione. Ma la parte con cui lotto è che se prendevo in giro troppo l'hardware cosa sto testando davvero? come lo gestisci? –

7

Creare un sottile strato per il controllo dell'hardware e utilizzare i test di sistema (manuali o automatici) con l'hardware completo per assicurarsi che il livello di controllo funzioni come previsto. Quindi crea un'implementazione finta/simulata del livello di controllo, che si comporta esternamente come l'interfaccia con l'hardware reale e la usa quando si esegue TDD per il resto del programma.


Anni fa stavo scrivendo software per eseguire misurazioni con un magnetometro SQUID. L'hardware era grande, inamovibile e costoso (video), quindi non era possibile avere sempre accesso all'hardware. Avevamo documentazione sul protocollo di comunicazione con i dispositivi (attraverso le porte seriali), ma la documentazione non era precisa al 100%.

Ciò che ci ha aiutato molto è stato creare un software che ascolta i dati provenienti da una porta seriale, lo registra e lo reindirizza su un'altra porta seriale. Poi siamo stati in grado di scoprire come il vecchio programma (che stavamo sostituendo) comunicava con l'hardware e invertire il protocollo. Sono stati incatenati in questo modo: Vecchio programma < -> Porta seriale loopback virtuale < -> Il nostro registratore di dati < -> Porta seriale reale < -> Hardware.

Allora non abbiamo utilizzato TDD. Abbiamo preso in considerazione la possibilità di scrivere un emulatore per l'hardware, in modo da poter testare il programma da solo, ma dal momento che non sapevamo esattamente come avrebbe funzionato l'hardware, era difficile scrivere un emulatore accurato, quindi alla fine non fallo. Se avessimo conosciuto meglio l'hardware, avremmo potuto creare un emulatore per questo, e avrebbe reso lo sviluppo del programma molto più semplice. Il collaudo con l'hardware reale è stato molto prezioso, e con il senno di poi avremmo dovuto impiegare ancora più tempo per testare l'hardware.

+0

+1, è simile ad altre risposte, ma molto ben messo. – mghie

1

Quando stavo lavorando a set-top box, avevamo uno strumento che generava mock da qualsiasi API C con commenti doxygen.

Abbiamo quindi innescato i mock con quello che volevamo restituire l'hardware per testare i nostri componenti.

Quindi nell'esempio sopra avresti impostato il risultato di FrameGrabber_API_IsDeviceAttached per essere falso, e quando il tuo codice chiama quella funzione restituisce false e puoi testarlo.

Quanto sarà facile eseguire il test dipende da come è strutturato il codice attualmente.

Lo strumento che abbiamo usato per generare i mock era in casa, quindi non posso aiutarti con quello. Ma ci sono alcuni di speranza successo google: (Disclaimer - ho usato uno di questi, ma si spera che possano essere di aiuto a voi)

Solo controllo - hai qualcosa come chiamate ioctl dirette nel tuo codice o qualcosa del genere? Sono sempre difficili da prendere in giro. Avevamo un layer wrapper per OS che potevamo scrivere facilmente mock, quindi per noi era abbastanza facile.