Come si scrivono i test unitari per i robot (e altri dispositivi meccanici)?

20

Sono un membro del club di robotica della mia scuola superiore e sono responsabile della programmazione del robot. Un suggerimento che continuo a sentire da vari adulti è che dovrei scrivere dei test unitari per aiutare a convalidare il mio codice. La base di codice sta diventando un po 'grande e sono d'accordo che i test di unità sarebbero davvero utili per aiutarmi a cogliere gli errori più rapidamente.

Tuttavia, non sono del tutto sicuro di come potrei realizzare questo. Per quanto ne so, il test delle unità viene eseguito prendendo una funzione (o un sottosistema del codice) e inserendola in un set di input per assicurarsi che esca ogni volta con lo stesso output. Il codice attualmente disponibile non esegue alcun pesante scricchiolio dei dati, ma piuttosto manipola direttamente i componenti hardware sul robot. La maggior parte della complessità deriva dall'assicurare che l'elettronica sia sana, che il codice al momento corrisponda all'hardware reale sul robot, ecc. Spesso, posso solo vedere se c'è un problema caricando il codice nel robot stesso, e tentando di eseguirlo.

Per estensione, come possono essere scritti i test unitari per il codice destinato a far funzionare qualsiasi dispositivo meccanico? Mi sembra che si possano rilevare errori solo osservando fisicamente il funzionamento della macchina.

O sto semplicemente fraintendendo il modo in cui i test unitari dovrebbero funzionare?

( Se è importante, ecco il codice , è scritto in C ++ e sto partecipando a FRC )

    
posta Michael0x2a 25.04.2012 - 08:29
fonte

4 risposte

20

Avrai bisogno di simulare il livello hardware per eseguire questo test. L'idea è che anziché il tuo codice che parla all'hardware reale, parli con una versione falsa dell'hardware che puoi controllare e quindi utilizzi per verificare che il tuo codice funzioni correttamente.

Purtroppo ci sono alcuni problemi che devi superare:

  • Mocking things in relatively low-level languages is more difficult (and thus, a lot more work)
  • Mocking hardware-level stuff is more difficult (and thus, a lot more work)

Inoltre, la maggior parte del valore dei test unitari automatizzati deriva dall'essere in grado di eseguire i test in qualsiasi momento per rilevare i bug di regressione per lunghi periodi di tempo dopo aver scritto il codice originale. Con questo tipo di competizioni, il tuo codice non verrà utilizzato affatto dopo la fine del concorso, quindi non otterrai gran parte del valore dei test. E considerando quanto sarebbe difficile aggiungere test al tuo caso particolare, potrebbe essere meglio usare il tuo tempo per fare solo test manuali e concentrarti sulle funzionalità del contest.

    
risposta data 25.04.2012 - 09:04
fonte
8

Posso pensare a un paio di cose che dovrai considerare. Il primo è quello di rendere il tuo livello di accesso all'hardware il più sottile possibile, anche se ciò significa creare un tipo base di wrapper per esso. Questo ti offre un paio di vantaggi. Il primo è che ti permette di isolare i comportamenti specifici dell'hardware del tuo codice dall'accesso hardware stesso, il che significa che puoi testare tutto fino in fondo alle comunicazioni hardware senza dover accedere all'hardware stesso.

Ad esempio, se è necessario progettare un protocollo di segnalazione basato su I2C, è possibile verificare che il codice stia generando i segnali I2C corretti senza dover agganciare l'hardware nei test.

Per le chiamate all'hardware reale, puoi verificare che si comportino correttamente prendendo in giro il tuo livello hardware, ed è qui che tenere veramente a bada un livello hardware molto sottile, perché puoi ridurre la tua simulazione a dover gestire solo il minimo funzioni necessarie per indirizzare effettivamente l'hardware, ma non è necessario testare i singoli segnali, poiché tutti i segnali dovrebbero essere testabili a un livello più alto. Ciò significa che utilizzi la tua simulazione per verificare che le chiamate siano fatte su metodi hardware specifici che causano l'invio dei segnali all'hardware. Se hai bisogno di eseguire il polling del tuo hardware, la tua simulazione deve essere in grado di attivare solo eventi o metodi nel tuo codice, perché di nuovo, la segnalazione di ritorno dovrebbe essere gestita in un livello superiore.

Questo si adatta fondamentalmente a ciò che Oleksi ha detto nella sua risposta , in quanto di solito è più lavoro per deridere l'hardware -le cose di livello, tuttavia non è così difficile se si mantiene il più semplice livello di codice / chiamata più basso possibile per l'hardware.

Quando hai codice che supera tutti i test, dovrai comunque eseguire una serie di test manuali per essere sicuro di aver inserito tutto correttamente nel tuo livello hardware.

L'altra cosa che viene in mente oltre al deridere e al layering, è usare una pratica di sviluppo test-first. In sostanza, si codificano i requisiti come criteri di test e si basa l'implementazione sui test. Ciò ti aiuterà a mantenere il codice di implementazione al minimo, assicurando che tutti i tuoi casi di test stiano guidando i tuoi sforzi di sviluppo. Non sprecando troppo tempo su un altro codice potenzialmente non critico che potresti essere tentato di fare "solo perché", il primo test ti aiuta a rimanere concentrato e renderà più facile cambiare il codice mentre esegui il debug, così come l'uso delle tue unit test e mock. Il debugging dei bug del software attraverso l'hardware è notoriamente complicato e risucchia grandi quantità di tempo che sarebbe meglio spendere per altre attività.

    
risposta data 25.04.2012 - 10:16
fonte
2

Posso dirti come lo fanno sui simulatori di volo

In primo luogo, riceverai solo metà della risposta se poni questa domanda solo ai programmatori, quindi dovresti probabilmente postare questo messaggio su link mentre ci sei.

Non ho mai lavorato con i robot, ma ho passato 5 anni a fare hardware sui simulatori di volo, quindi posso dirti come funziona la loro architettura.

Il livello hardware è stupido

Contiene un'interfaccia di base in cui è possibile regolare i valori di input / output e impostare i punti di interruzione dell'interpolazione per i segnali analogici. Quando lavori con hardware "fresco", tutto funziona come previsto con poca o nessuna calibrazione, ma nel tempo le parti subiranno usura meccanica e dovranno essere regolate.

La calibrazione è una tabella semplice che contiene sezioni disposte tra i valori min / max. Per misurare l'input su questi, viene tipicamente utilizzato un servo (ex potenziometro lineare, trasduttore, accelerometri, ecc.). O nel caso della strumentazione, giudichi visivamente la precisione e regola fino alla calibrazione.

Il livello software è l'opposto

Tutto è complesso e interconnesso, quindi è importante isolare alcune variabili per testare la funzionalità. Non è necessario darsi un mal di testa pensando agli scenari perché è molto più facile eseguire alcuni scenari realistici in cui è possibile raccogliere dati. Quando esegui i test, stai praticamente misurando i dati memorizzati rispetto all'output corrente.

Su un simulatore di volo si parla di QTG (Qualification Test Guide). Nel suo nucleo, traccia i dati su una griglia 2D in cui una dimensione è il tempo e l'altra è l'output.

Che ci crediate o no, questa è l'essenza di come sviluppano i modelli. Un vero aereo è equipaggiato con una tonnellata di sensori e viene pilotato facendo scenari controllati. Poiché tutti i controlli possono essere guidati senza l'interazione umana, i test vengono eseguiti (cioè la sim si vola) dal computer e i dati vengono confrontati.

Anche se la robotica è creata su una scala molto diversa, i principi sono gli stessi. L'approccio tradizionale consiste nel separare completamente i livelli hardware e software in modo che entrambi possano essere testati individualmente. L'input hardware viene raccolto tramite i servo e impostato tramite un'interfaccia indipendente. L'input di Sofware può essere impostato / letto misurando e confrontando in modo indipendente la segnalazione che altrimenti andrebbe all'hardware e tracciandola contro dati "buoni" noti.

Gli stessi test non devono necessariamente essere complessi a patto che i risultati siano prevedibili, misurabili e riproducibili.

    
risposta data 27.04.2012 - 11:50
fonte
1

Come detto in precedenza, prendi in giro e metti a nudo le parti hardware. Ad esempio, se si dispone di un'interfaccia per il robot, è possibile ereditare da tale interfaccia e quindi effettuare semplici implementazioni di stub. Quindi è possibile verificare che l'implementazione stub sia stata chiamata come previsto. Se è previsto funzioni o parametri attesi.

    
risposta data 27.04.2012 - 12:55
fonte

Leggi altre domande sui tag