2009-06-16 7 views
7

Esiste un modo per mostrare lo stato di avanzamento di un singolo TestMethod in Visual Studio 2008?È possibile visualizzare i progressi durante l'esecuzione di un TestMethod di Visual Studio?

All'interno di un set di test di unità, ho un singolo TestMethod che viene eseguito per un tempo molto, molto lungo - normalmente ci vorranno tra 30 e 60 minuti. Ho impostato il timeout usando l'attributo [Timeout], nessun problema lì. Ma mi piacerebbe essere in grado di ottenere un'indicazione visiva del progresso del test.

So che la finestra Risultati del test fornisce un aggiornamento visivo di tutti i metodi di test. Quello che voglio è un aggiornamento visivo di un singolo metodo. In un'app WinForms vorrei aprire un controllo ProgressBar. In un'app console, posizionerei il cursore e visualizzerei un messaggio di stato. Ma questo è un test unitario. Posso scrivere su TestContext, ma quella finestra non è visualizzabile fino al completamento del test.


EDIT: so che c'è un modo per farlo; è tutto solo software, quindi c'è sempre un modo. Ma cos'è un modo semplice e pratico?

Un modo per farlo è creare un'applicazione TestMethodProgressMonitor.exe, che legge da una named pipe, e aggiorna una barra di avanzamento in base ai messaggi che arrivano attraverso la pipe. Il TestMethod può shellExec il TestMethodProgressMonitor.exe, quindi scrivere nella named pipe. Al termine, forse c'è un noto comando shutdown che TestMethod invia all'app TestMethodProgressMonitor.exe.

Un'altra opzione è la costruzione di TestMethodProgressMonitor.exe come server COM e TestMethod può utilizzare COM (DCOM) per aggiornare una barra di avanzamento ospitata all'interno dell'app.

Un'altra opzione consiste nell'utilizzare il metodo sendMessage() user32.dll per inviare un messaggio WM_COPYDATA all'app monitor. A volte ciò viene fatto per il controllo remoto delle app.

Queste sono alcune delle possibilità. Prima di iniziare a costruirne uno, mi piacerebbe sapere se esiste un modo più semplice.

+0

un test di unità che richiede tanto tempo, non è un test di unità per definizione. Che cosa ci mette a prendere così tanto tempo? –

+2

È un test per la creazione di un file ZIP64; Il test crittografa un insieme di file che risultano in un file zip superiore a 4 GB. Quindi il file zip viene aggiornato e salvato nuovamente (due volte). Il codice è di circa 5 righe circondate da un ciclo. Ma c'è un sacco e un sacco di I/O e un sacco di DEFLATE. Stai davvero dicendo che la definizione di unit test include un limite di tempo? Qual è il limite di tempo? – Cheeso

risposta

5

ho solo avviare un thread GUI con una finestra che ha il ProgressBar.

Ecco uno snippet per iniziare. Si apre semplicemente MyProgressWindow in un altro thread (piuttosto che in un altro processo).

[ClassInitialize()] 
static public void MyClassInitialize(TestContext testContext) 
{ 
    start_app_in_gui_thread(); 
} 

static Thread t; 

private static void start_app_in_gui_thread() 
{ 
    t = new Thread(() => { 
     var w = new MyProgressWindow(); 
     var app = new App(); 
     app.ShutdownMode = ShutdownMode.OnMainWindowClose; 
     app.Run(w); 
    }); 
    t.SetApartmentState(ApartmentState.STA); 
    t.Start(); 
} 
+0

Doh! Cosa significa? Whadaya significa "avviare un thread GUI"? – Cheeso

+0

Mi dispiace per il gergo. Ecco un codice. Godere. – Ray

-1

no, ma mi piacerebbe che ci fosse

1

Per le mie lunghe prove di corsa ho utilizzare le API Trace per allegare un listener di analisi (DbgView o qualcosa di personalizzato).

Fa sembrare semplice vedere cosa sta succedendo senza dover passare attraverso nessun anello.

Questo non ti darà un'esperienza di progresso (anche se potresti scriverne una abbastanza facilmente).

+1

Ottimo! A proposito, usando System.Diagnostics.Debug puoi persino vedere l'output nella finestra Output – sinelaw

0

Non sicuro che questo sia il modo più semplice, ma questo è quello che ho fatto. Ho hackerato una classe che WM_COPYDATA invia e riceve. È un ricetrasmettitore. Ciò consente a un'app di Windows di comunicare con un'altra, sullo stesso computer, con una latenza abbastanza bassa. L'ho confezionato come un assemblaggio.

Quindi ho creato un'app winforms (UnitTestProgressMonitor.exe) che crea uno di questi ricetrasmettitori e aggiorna l'interfaccia utente in base ai messaggi ricevuti. I messaggi sono solo stringhe.Questo è quello che fanno:

  • bar 3 - L'interfaccia utente crea e visualizza 3 barre di avanzamento
  • pb 0 max 100 - imposta il massimo per la barra di avanzamento # 0 a 100
  • pb 0 valore 28 - set il valore per la barra di avanzamento da 0 a 28
  • stop - exit.

Quindi, all'interno del [TestMethod], ho shellexec il UnitTestProgressMonitor.exe, quindi creare un ricetrasmettitore e inviare i messaggi dell'app.

Il codice di prova invia "barre 3" all'app del monitor di avanzamento, per dirgli di creare 3 barre di avanzamento. Il primo traccia i 7 passaggi del test. La seconda barra di progresso misura i progressi nel file zip; ogni voce nel file è un passo lungo la barra. La 3a barra rappresenta il progresso per una singola voce. Alcuni di questi sono file multi-gigabyte, quindi comprimerli può richiedere del tempo. Durante l'esecuzione del test, il test invia un "pb 0 step" o qualsiasi altra cosa, nei momenti appropriati. Questi messaggi fanno sì che le barre di avanzamento si aggiornino. Alla fine del test, il codice di test invia un "stop" all'app monitor. In risposta a ciò, l'app del monitor di avanzamento scompare. Il test finisce.

Unit Test Progress Monitor http://www.freeimagehosting.net/uploads/45b4979b92.jpg

1

Ho incontrato lo stesso requisito, ma ogni nuovo file o eseguibile suoni troppo per me: sto scrivendo unit test, non è una domanda. Il seguente codice scrive i progressi nella finestra Debug Output:

[TestMethod] 
    public void ProgressTest() 
    { 
     int nLastWritten = -1, nTotal = 10000; 

     for (int i = 0; i < nTotal; i++) 
     { 
      int nProgress = 100 * i/nTotal; 
      if (nProgress > nLastWritten) 
      { 
       System.Diagnostics.Trace.WriteLine("Progress: " + nProgress + "%"); 
       nLastWritten = nProgress; 
      } 
     } 
    } 
Problemi correlati