Domanda

Come testate un'unità di una grande interfaccia utente MFC?

Abbiamo alcune applicazioni MFC di grandi dimensioni che sono in fase di sviluppo da molti anni, utilizziamo alcuni strumenti standard di controllo qualità automatizzati per eseguire script di base per controllare i fondamenti, aprire i file ecc. Questi sono gestiti dal gruppo QA dopo la compilazione giornaliera.

Ma vorremmo introdurre procedure in modo tale che i singoli sviluppatori possano creare ed eseguire test su finestre di dialogo, menu e altri elementi visivi dell'applicazione prima di inviare il codice alla build giornaliera.

Ho sentito parlare di tecniche come pulsanti di test nascosti nelle finestre di dialogo che compaiono solo nelle build di debug, esistono dei toolkit standard per questo.

L'ambiente è C ++ / C / FORTRAN, MSVC 2005, Intel FORTRAN 9.1, Windows XP / Vista x86 e amp; x64.

È stato utile?

Soluzione

Dipende da come è strutturata l'app. Se la logica e il codice GUI sono separati (MVC), testare la logica è semplice. Dai un'occhiata a Michael Feathers " Humble Dialog Box " (PDF).

MODIFICA: se ci pensi: dovresti fare molto attentamente il refactoring se l'app non è strutturata in questo modo. Non esiste altra tecnica per testare la logica. Gli script che simulano i clic stanno solo graffiando la superficie.

In realtà è abbastanza semplice:

Supponi che il tuo controllo / finestra / qualunque cosa cambi il contenuto di una casella di riepilogo quando l'utente fa clic su un pulsante e vuoi assicurarti che la casella di riepilogo contenga le cose giuste dopo il clic.

  1. Refactor in modo che sia presente un elenco separato con gli elementi che la casella di riepilogo deve mostrare. Gli elementi sono memorizzati nell'elenco e non vengono estratti da dove provengono i tuoi dati. Il codice che rende le cose dell'elenco della lista conosce solo il nuovo elenco.
  2. Quindi si crea un nuovo oggetto controller che conterrà il codice logico. Il metodo che gestisce il clic sul pulsante chiama solo mycontroller- > ButtonWasClicked (). Non conosce la casella di riepilogo o altro.
  3. MyController :: ButtonWasClicked () fa quello che deve essere fatto per la logica desiderata, prepara l'elenco degli elementi e dice al controllo di aggiornarsi. Perché funzioni, devi disaccoppiare il controller e il controllo creando un'interfaccia (pura classe virtuale) per il controllo. Il controller conosce solo un oggetto di quel tipo, non il controllo.

Questo è tutto. Il controller contiene il codice logico e conosce il controllo solo tramite l'interfaccia. Ora puoi scrivere test unitari regolari per MyController :: ButtonWasClicked () deridendo il controllo. Se non hai idea di cosa sto parlando, leggi l'articolo di Michaels. Due volte. E ancora dopo.
(Nota per sé: deve imparare a non blaterare così tanto)

Altri suggerimenti

Dato che hai menzionato MFC, ho pensato che avessi un'applicazione che sarebbe difficile ottenere sotto un cablaggio di test automatizzato. Osserverai i migliori vantaggi dei framework di unit test quando compili test mentre scrivi il codice .. Ma provare ad aggiungere una nuova funzionalità in modo testato a un'applicazione che non è progettata per essere testabile .. può essere un duro lavoro e ben frustrante.

Ora quello che sto per proporre è sicuramente duro lavoro .. ma con un po 'di disciplina e perseveranza vedrai i benefici abbastanza presto.

  • Per prima cosa avrai bisogno di un po 'di supporto gestionale perché le nuove correzioni richiedano un po' più di tempo. Assicurati che tutti capiscano perché.
  • Successivamente acquista una copia del libro WELC . Leggi copertina per copertina se hai il tempo O se hai difficoltà, scansiona l'indice per trovare il sintomo che l'app sta esibendo. Questo libro contiene molti buoni consigli ed è proprio ciò di cui hai bisogno quando cerchi di rendere testabile il codice esistente. alt text
  • Quindi, per ogni nuova correzione / modifica, dedica un po 'di tempo e comprendi l'area su cui lavorerai. Scrivi alcuni test in una variante xUnit a tua scelta (disponibile gratuitamente) per esercitare il comportamento attuale.
  • Assicurati che tutti i test abbiano superato. Scrivi un nuovo test che eserciti il ??comportamento necessario o il bug.
  • Scrivi il codice per completare l'ultimo test.
  • Rifattorizza senza pietà nell'area sotto test per migliorare il design.
  • Ripeti per ogni nuova modifica che devi apportare al sistema da qui in poi. Nessuna eccezione a questa regola.
  • Ora la terra promessa : presto emergeranno isole sempre più numerose di codice ben collaudato. Sempre più codice rientrerebbe nella suite di test automatizzata e le modifiche diventeranno progressivamente più facili da effettuare. E questo perché lentamente e sicuramente il design sottostante diventa più testabile.

L'uscita facile era la mia risposta precedente. Questa è la via d'uscita difficile ma giusta.

Mi rendo conto che questa è una domanda datata, ma per quelli di noi che lavorano ancora con MFC, il framework di test di unità Microsoft C ++ in VS2012 funziona bene.

La procedura generale:

  1. Compila il tuo progetto MFC come libreria statica
  2. Aggiungi un nuovo progetto nativo di unit test alla tua soluzione.
  3. Nel progetto di test, aggiungere il progetto MFC come riferimento.
  4. Nelle proprietà di configurazione del progetto di test, aggiungere le directory Includi per i file di intestazione.
  5. Nel Linker, le opzioni di input aggiungono il tuo MFC.lib; nafxcwd.lib; libcmtd.lib;
  6. In "Ignora librerie predefinite specifiche" aggiungi nafxcwd.lib; libcmtd.lib;
  7. In Generale aggiungi la posizione del tuo file lib esportato MFC.

La https: // stackoverflow. com / questions / 1146338 / error-lnk2005-new-and-delete-già-definito-in-libcmtd-libnew-obj ha una buona descrizione del motivo per cui hai bisogno di nafxcwd.lib e libcmtd.lib.

L'altra cosa importante da verificare nei progetti legacy. In Proprietà di configurazione generali, assicurarsi che entrambi i progetti utilizzino lo stesso 'Set di caratteri'. Se l'MFC utilizza un set di caratteri a più byte, è necessario eseguire anche il test MS.

Anche se non perfetto, il migliore che ho trovato per questo è AutoIt http://www.autoitscript.com/ autoit3

" AutoIt v3 è un linguaggio di scripting di tipo BASIC freeware progettato per automatizzare la GUI di Windows e gli script generali. Utilizza una combinazione di tasti simulati, spostamento del mouse e manipolazione di finestre / controlli per automatizzare le attività in modo impossibile o affidabile con altre lingue (ad esempio VBScript e SendKeys). AutoIt è anche molto piccolo, autonomo e funzionerà su tutte le versioni di Windows immediatamente senza fastidiosi "runtime". richiesta "

Funziona bene quando si ha accesso al codice sorgente dell'applicazione guidata, poiché è possibile utilizzare il numero ID risorsa dei controlli che si desidera guidare. In questo modo non devi preoccuparti di clic del mouse simulati su pixel particolari. Sfortunatamente, in un'applicazione legacy, potresti scoprire che l'ID risorsa non è univoco, il che potrebbe causare problemi. Però. è molto semplice modificare gli ID in modo che siano univoci e ricostruiti.

L'altro problema è che si verificano problemi di temporizzazione. Non ho una soluzione provata e vera per questi. Prova ed errore sono ciò che ho usato, ma questo chiaramente non è scalabile. Il problema è che lo script AutoIT deve attendere che l'applicazione di test risponda a un comando prima che lo script emetta il comando successivo o verifica la risposta corretta. A volte non è facile trovare un evento conveniente da aspettare e guardare.

La mia sensazione è che, nello sviluppo di una nuova applicazione, insisterei su un modo coerente di segnalare "READY". Ciò sarebbe utile per gli utenti umani e per gli script di test! Questa potrebbe essere una sfida per un'applicazione legacy, ma forse puoi introdurla in punti problematici e diffonderla lentamente all'intera applicazione man mano che la manutenzione continua.

Sebbene non sia in grado di gestire il lato UI, I test del codice MFC utilizzando la libreria Boost Test. C'è un articolo di Code Project su come iniziare:

Progettazione di oggetti robusti con boost

Bene, abbiamo una di queste enormi app MFC sul posto di lavoro. È un dolore gigantesco da mantenere o estendere ... è un'enorme palla di fango ora ma rastrella nella moolah. Comunque

  • Utilizziamo Rational Robot per fare test del fumo e simili.
  • Un altro approccio che ha avuto un certo successo è quello di creare un linguaggio specifico del prodotto e test di script che utilizzano VBScript e alcuni controlli per gestire la magia dello spionaggio. Trasforma le azioni comuni in comandi ... ad es. OpenDatabase sarebbe un comando che a sua volta inietterà i blocchi di script richiesti per fare clic sul menu principale > File > & Quot; Apri ... " ;. Quindi creare fogli Excel che sono una serie di tali comandi. Anche questi comandi possono accettare parametri. Qualcosa come un test FIT .. ma più lavoro. Una volta identificati la maggior parte dei comandi comuni e pronti gli script. È scegliere e assemblare script (etichettati da CommandIDs) per scrivere nuovi test. Un test-runner analizza questi fogli di Excel, combina tutti i piccoli blocchi di script in uno script di test ed esegue.

    1. OpenDatabase " C: \ tests \ MyDB "
    2. OpenDialog " Aggiungi modello "
    3. AddModel " M0001 " ;, " MyModel " ;, 2.5, 100
    4. PressOK
    5. SaveDatabase

HTH

In realtà abbiamo usato Rational Team Test, poi Robot, ma nelle recenti discussioni con Rational abbiamo scoperto che non avevano in programma di supportare applicazioni x64 native focalizzate maggiormente su .NET, quindi abbiamo deciso di cambiare gli strumenti di QA automatizzato. Questo è fantastico ma i costi di licenza non ci consentono di abilitarlo per tutti gli sviluppatori.

Tutte le nostre applicazioni supportano un'API COM per gli script, che testiamo la regressione tramite VB, ma questa verifica l'API e non l'applicazione in quanto tale.

Idealmente sarei interessato a come le persone integrano cppunit e framework di test unitari simili nell'applicazione a livello di sviluppatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top