Codice pesante effetto collaterale test di unità


10

Sto iniziando a scrivere codice C ++ per eseguire un robot e non so come incorporare i test unitari, se davvero posso. Mi è stata fornita una libreria che consente la creazione di "comandi" per il robot, che vengono automaticamente programmati ed eseguiti. Il meccanismo per creare questi comandi è alla sottoclasse una classe base comando prevedono, e attuare virtuali void Initialize(), void Execute()e void End()metodi. Queste funzioni sono eseguite esclusivamente per i loro effetti collaterali, che fanno cose al robot (far funzionare i motori, estendere i pistoni, ecc.). Per questo motivo, in realtà non vedo da nessuna parte allegare test unitari al codice, a parte deridere l'intera libreria in modo da poter controllare gli stati virtuali prima e dopo del robot. C'è un modo per testare l'unità che non è eccessivamente oneroso?

modificare

Penso che potrei essere stato fuorviante sulla funzionalità della biblioteca. La libreria fornisce la maggior parte dell'interfaccia per il robot e il sistema di comando / pianificazione, quindi non è così semplice come deridere la classe base di comando, dovrei deridere l'intera interfaccia per l'hardware. Purtroppo non ho il tempo di farlo.


Presumo che tu possa annullare qualsiasi azione che fai fare al tuo robot, giusto? Non puoi annullare le azioni del tuo test?
Neil,

1
Peccato che la libreria non abbia usato la composizione invece dell'ereditarietà, perché in questo caso potresti prendere in giro la classe di comando.
Robert Harvey,

@Neil Non sono abbastanza sicuro di quello che stai chiedendo. Puoi riformulare la tua domanda?
Will Kunkel,

Risposte:


7

Quello che farei in questo caso sarebbe quello di introdurre la mia interfaccia RobotControl con metodi corrispondenti a quelli della vera libreria.

Dopo aver fatto questo, vorrei creare una classe RobotControlImpl che implementa questa interfaccia contro la vera lib robot.

I comandi che di conseguenza scrivo non estenderebbero la classe base, ma opererebbero invece sull'interfaccia che hai introdotto.

In questo modo puoi deridere RobotControl, passare la simulazione a qualsiasi comando e verificare che abbia chiamato i metodi giusti sull'interfaccia.

In questo modo passeresti il ​​vero impianto di RobotControl ai comandi che hai implementato.

Non sono sicuro se questo è ciò che avevi in ​​mente e considerato ingombrante?

Modifica: Oh, e se ti aspetti che i comandi dormano per attendere il completamento (incubo, ma a volte questo è quello che hai), avrei bisogno che i comandi chiamassero un metodo sleep su RobotControl. In questo modo è possibile disabilitare gli sleep durante il test e verificare semplicemente che il comando tenti di dormire.


2
+1. Non ti piace l'interfaccia? Crea il tuo.
Neil,

Sembra che tu mi stia suggerendo di deridere l'intera biblioteca. Quasi tutte le funzioni che i comandi chiameranno sono interne alla libreria.
Will Kunkel,

0

Penso che sia possibile rendere il codice testabile in modo minimamente invasivo. Con ciò intendo dire che è possibile scrivere i comandi esattamente come previsto dagli autori delle librerie di robot. Questo può essere vantaggioso se vuoi scambiare codice con altri che non usano il tuo livello intermedio.

Richiede una "build unit test" separata del codice.

Quello che fai è che in un file di intestazione centrale, controlli un tempo di compilazione definisci se questa è la build di unit test e, in tal caso, ridefinisce il nome della classe di base e forse alcune altre classi nella libreria di robot in nomi di classi dell'implementazione del test. È necessario definire le stesse funzioni virtuali della libreria robot e fornire gli stub per i metodi che si invocano nel robot.

Quindi hai comandi che puoi lanciare nel tuo framework di test che invoca gli stessi metodi che farebbe la libreria robot.

Ciò comporterà una certa quantità di mozziconi e derisioni, ma ciò è inevitabile in qualsiasi progetto di test unitario.

La modifica del nome della classe di base potrebbe essere eseguita con un #define o probabilmente preferito, un typedef.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.