Come strutturare i test unitari per un'applicazione GUI utilizzando C # e NUnit

16

Mi è stato chiesto di realizzare un piccolo progetto parallelo per fornire una semplice applicazione a uno dei nostri clienti. Normalmente lavorerei su un codice back-end in cui ho trovato tutte le mie esigenze di test e non ho ancora avuto il dubbio piacere di scrivere test per la GUI, quindi non mi è chiaro come dovrei impostare il codice di test e gli strumenti per un EXE.

Il mio primo istinto era semplicemente includere i test con il codice dell'applicazione, tuttavia ciò avrebbe richiesto la fornitura di un certo numero di dipendenze specifiche del test, che mi è stato detto di non spedire specificamente al cliente. Non riesco nemmeno a spremere soldi per uno strumento di test appositamente creato, quindi ho bisogno di usare gli strumenti che ho a disposizione ( StoryQ , RhinoMocks e NUnit ), che in realtà dovrebbero essere più che sufficienti per testare il comportamento di una semplice app GUI. Quindi, per quanto posso vedere, questo mi lascia tentare di trovare un buon equilibrio tra mantenere il design davvero semplice, o sovra-ingegnerizzare in modo mirato per i test. Sembra che sto costruendo l'app con la business logic in una libreria separata e testando la libreria come faccio di solito, o trovando qualche altro meccanismo che mi consenta di eseguire l'eseguibile senza scomporre moduli aggiuntivi che la progettazione dell'applicazione non davvero bisogno.

Modifica
Si noti che questa domanda riguarda il modo in cui strutturare la relazione tra NUnit e il mio eseguibile - al contrario di una DLL - e non su come separare la presentazione e la logica di business.
/ Modifica

Quindi la mia domanda è:

  1. Esiste un metodo specifico / consigliato per configurare un'applicazione GUI semplice con test unitari per permettermi di verificare adeguatamente lo stato e il comportamento, utilizzando gli strumenti che ho a disposizione e senza ricorrere all'ingegnerizzazione?
  2. Ho perso qualcosa di fondamentale nel modo in cui NUnit dovrebbe essere invocato / configurato durante il test di un EXE (al contrario di una DLL)?
  3. Puoi fornire o indicarmi la direzione di esempi su come ottenere tutto questo?

Mi rendo conto che potrebbe esserci più di un modo per farlo, quindi sono alla ricerca di linee guida di implementazione specifiche in base alla tua esperienza.

    
posta S.Robins 25.01.2012 - 05:16
fonte

5 risposte

2

Ho menzionato in uno dei miei commenti alla risposta del simoraman che avevo pensato ad un paio di modi per fare Questo. Una delle mie opzioni era simile al suggerimento nella risposta di Jalayn per creare un progetto duplicato e generare una DLL, mentre il mio l'altra idea era semplicemente collegarsi ai file del progetto in cui c'era il codice che volevo testare. Mentre entrambe le opzioni potrebbero essere fatte funzionare, sono tutt'altro che ideali.

Nel secondo caso, dovrei avere un casino di dipendenze delle unità da gestire a meno che non riesca davvero a mettere a parte l'architettura per minimizzare le dipendenze. Questo va bene per i progetti più piccoli, ma quelli più grandi potrebbero facilmente diventare un vero casino da gestire. La mia più grande resistenza a questa opzione è la pura ineleganza di questa opzione. Certo che potrei riuscire a farlo funzionare, ma in tal modo ho effettivamente bisogno di interrompere l'incapsulamento per testare i componenti interni di un assembly direttamente tramite l'origine, piuttosto che testare tramite le interfacce pubbliche, che nella mia mente è un grande no-no. Allo stesso modo, avere un file di progetto aggiuntivo significherebbe duplicare gli sforzi in due progetti alla volta, o trovare un modo per aggiungere automaticamente le impostazioni del file di progetto a due file alla volta, o ricordare di copiare e rinominare il campo del progetto ogni volta che costruisco. Questo può essere automatizzato sul server di build, forse, ma sarebbe un problema da gestire nell'IDE. Di nuovo, può funzionare, ma nel migliore dei casi è un kludge, e una seccatura in peggio se ti sbagli.

Il modo migliore sembra essere quello di fare quanto whatsisname ha commentato alla mia domanda, e di includere semplicemente l'EXE come riferimento nel progetto di test. Si scopre che un EXE viene effettivamente trattato allo stesso modo come una DLL in questo caso, e sono in grado di accedere a tutte le mie classi piacevolmente stratificate per testare qualsiasi cosa faccia galleggiare la mia barca.

    
risposta data 27.01.2012 - 05:58
fonte
2

Penso che:

  • Il codice del test aziendale dovrebbe essere in un progetto separato, testando la libreria del codice aziendale.
  • Il codice di test della GUI dovrebbe essere in un progetto separato, testando la libreria della GUI. Ora, come creare una libreria GUI invece di un eseguibile, cercherò di rispondere più tardi.
  • Se hai un my.namespace.biz.MyClass, la tua classe di test dovrebbe essere my.namespace.biz.MyClassTest (o MyClassTestCase).
  • Se vuoi testare il codice trovato nella tua destinazione eseguibile, allora dovresti avere una configurazione che costruisca un EXE e un'altra configurazione che costruisca una libreria (DLL) che è quella su cui lanci i tuoi test.

Queste sono le regole che mi piace seguire, sia che si tratti di Java o C # (eccetto che non ci sono problemi EXE con Java ovviamente :-))

Per quanto riguarda la configurazione del tuo ambiente di test, mi sembra che tu abbia almeno queste due scelte:

Uso di MSBuild

Crea un clone del tuo file .proj (ad esempio myproject-as-dll.proj ). Modifica OutputType nel file clonato da " EXE " a " Library ". Usando il comando MSBuild ora sei in grado di produrre una libreria che puoi impostare come riferimento nel tuo progetto contenente casi di test NUnit.

Mi sembra possibile, ma non l'ho mai usato così onestamente, quindi non ne sono sicuro. Inoltre, potresti non avere MSBuild sul tuo server di test di integrazione e non so se può essere separato da Visual Studio ...

Uso di NAnt

Se non hai familiarità con NAnt, dovrai risalire su google come configurare le build del tuo progetto con esso. Forse dai un'occhiata a questo , è un po 'vecchio ma l'autore ha commentato i file NAnt e Se lo trova auto esplicativo. ( Modifica: esaminando il suo file più in dettaglio, trovo il suo file di configurazione estremamente riutilizzabile ). Inoltre, fa molto di più che costruire, dal momento che esegue test case e lancia strumenti di copertura del codice. Ora, ammetto di non aver mai usato NAnt, contrariamente alla sua controparte Java e padre "Ant" che ho usato molto ma vedo che è praticamente la stessa cosa e non penso che sia così difficile da imparare.

Con questo strumento puoi creare una configurazione che ti permetterà di:

  • crea tutti i tuoi progetti (business logic, GUI, ecc.) in librerie separate
  • crea i tuoi progetti di test
  • avvia i test (quella parte specifica viene eseguita con l'attività NUnit2 ).
  • esamina la copertura del tuo codice con l'attività NCover .

Con un po 'di codice in più, potresti anche:

  • eseguire le distribuzioni notturne nel server di integrazione
  • se NAnt è disponibile nel server di integrazione, avviare i test di integrazione notturni con l'aiuto delle attività pianificate

Tutto è fatto senza modificare nulla nei file di Visual Studio. E, in realtà, non mi sembra un over-engineering, è solo un file. Potrebbero volerci uno, forse due giorni per far funzionare tutto, ma a mio parere avremo una buona impostazione.

Infine, darei al cliente tutto ciò che è necessario per costruire, testare ed eseguire i progetti. Tendo a pensare che mostri la tua professionalità e il fatto che tu scriva codice con qualità nella tua mente (che a me sembra che tu faccia da quando cerchi soluzioni eleganti)

    
risposta data 26.01.2012 - 08:52
fonte
0

Solo perché il progetto è piccolo (inizialmente) non significa che l'architettura corretta sia sovra-ingegneristica. Il fatto che tu voglia scrivere test dice che il tuo progetto non è un trucco un po 'banale.

Non hai menzionato quale GUI-Framework stai usando. WPF MVVM (Model-View-ViewModel) è buono e consente di scrivere test per tutti i logica abbastanza facilmente. Con WinForms ho sentito cose positive su MVP (Model-View-Presenter)

    
risposta data 25.01.2012 - 06:47
fonte
0

Dai un'occhiata alla mia risposta a questa domanda: Come posso configurare MVP per una soluzione Winforms?

In realtà ho scritto un'applicazione di esempio che mostra come ho strato e come collaudo la mia interfaccia grafica.

leggi la tua modifica: usa un test runner che si integra con il tuo ambiente di sviluppo. Io uso ReSharper.

    
risposta data 25.01.2012 - 23:45
fonte
0

Ho scritto Nunit WinForms alcuni anni fa (6 anni credo). Una cosa che ricordo in particolare è che, sebbene sia un caso di test unitario, funge anche da test end-to-end. A volte non c'è molto da testare su un front end (una forma semplice). Quindi, anche se stai provando a testare la visualizzazione di una finestra di messaggio su un pulsante, stai provando involontariamente vari altri metodi da altri livelli. Ci sono alcune cose che non puoi automatizzare. L'aspetto, la sensazione e l'usabilità non possono essere automatizzati utilizzando test automatici delle unità. Dovrai eseguire alcuni test manuali prima del rilascio.

    
risposta data 26.01.2012 - 10:03
fonte

Leggi altre domande sui tag