Posso scrivere nella console in un unit test? Se sì, perché la finestra della console non si apre?


148

Ho un progetto di test in Visual Studio. Uso Microsoft.VisualStudio.TestTools.UnitTesting .

Aggiungo questa riga in uno dei miei test unitari:

Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();

Quando eseguo il test, il test passa, ma la finestra della console non si apre affatto.

Esiste un modo per rendere la finestra della console disponibile per l'interazione tramite un unit test?


1
Dipende molto dal corridore. È possibile utilizzare TestDriven.Net (un ottimo, gratuito per uso personale, test runner) - Console.WriteLine scriverà nel riquadro di output VS.
seldary,

1
Grazie per spargere la voce su TestDriven.Net
GrayFox374,

NCrunch ha anche questa funzione, che da sola vale il prezzo IMO. Ho un Dumpmetodo di estensione che genera i contenuti dell'oggetto nella console, rendendo le cose molto più facili da eseguire il debug. i.imgur.com/MEZwy7X.png
DharmaTurtle,

Risposte:


125

NOTA: la risposta originale di seguito dovrebbe funzionare per qualsiasi versione di Visual Studio fino a Visual Studio 2012. Visual Studio 2013 non sembra più avere una finestra Risultati test. Invece, se hai bisogno di un output specifico del test, puoi usare il suggerimento di @ Stretch di Trace.Write()scrivere l'output nella finestra Output.


Il Console.Writemetodo non scrive sulla "console", ma scrive su tutto ciò che è collegato all'handle di output standard per il processo in esecuzione. Allo stesso modo, Console.Readlegge l'input da qualsiasi cosa sia collegata all'input standard.

Quando si esegue un unit test tramite Visual Studio 2010, l'output standard viene reindirizzato dal cablaggio del test e memorizzato come parte dell'output del test. Puoi vederlo facendo clic con il pulsante destro del mouse sulla finestra Risultati test e aggiungendo la colonna "Output (StdOut)" al display. Questo mostrerà tutto ciò che è stato scritto nell'output standard.

È possibile aprire manualmente una finestra della console, usando P / Invoke come dice sinni800 . Dalla lettura della AllocConsoledocumentazione, sembra che la funzione verrà ripristinata stdine verrà stdoutgestita per puntare alla nuova finestra della console. (Non ne sono sicuro al 100%; mi sembra un po 'sbagliato se ho già reindirizzato stdoutper Windows per rubarmelo, ma non ci ho provato.)

In generale, però, penso che sia una cattiva idea; se tutto ciò per cui vuoi usare la console è scaricare maggiori informazioni sul tuo test unitario, l'output è lì per te. Continua a utilizzare Console.WriteLinecome sei e controlla i risultati dell'output nella finestra Risultati del test al termine.


Prova ad aprire una nuova applicazione Windows, usando AllocConsole per allocare una console e scriverà lì. Non so cosa faccia davvero, ma potrebbe non funzionare in un ambiente di unit test. Sarebbe davvero bello sapere ...
sinni800,

hrm. rileggendo la AllocConsoledocumentazione, potrei non essere corretto, ma dovrei provarlo.
Michael Edenfield,

2
Per me questo commento di Michael diceva tutto ciò di cui avevo bisogno: "Quando si esegue un test unitario attraverso VS2010, l'output standard viene reindirizzato dal cablaggio di test e memorizzato come parte dell'output di test".
Robert Patterson,

5
in VS2013, se si scrive sulla console, ci sarà un'etichetta di collegamento [Output] su TestExplorer / Test / Riepilogo. Cliccaci sopra e otterrai l'output desiderato. Aspettare? Vuoi anche chiamare Console.ReadLine () ??
Visar,

3
In V2017 (Community), vai su "test explorer", seleziona l'elemento del risultato del test nell'elenco, quindi fai clic sul link "output" nell'altra finestra (finestra del risultato del test?). Dato che probabilmente verrà troncato, usa il "copia tutto" e passa altrove.
Heringer

180

Qualcuno ha commentato questa funzionalità apparentemente nuova in Visual Studio 2013. Non ero sicuro di cosa intendesse inizialmente, ma ora che lo faccio, penso che meriti una sua risposta.

Possiamo usare Console.WriteLine normalmente e l'output viene visualizzato, non solo nella finestra Output, ma in una nuova finestra dopo aver fatto clic su "Output" nei dettagli del test.

Inserisci qui la descrizione dell'immagine


2
Soluzione eccellente Conferma che funziona in VS2015 Enterprise.
Garfbradaz,

6
Sfortunatamente, non è possibile selezionare alcun testo nell'area di output per il copia e incolla :( Cosa stavano pensando ?!
OR Mapper

3
@ORMapper, fai clic con il pulsante destro del mouse sull'area "Output standard" e scegli copia tutto
bychance

2
@ Ovi-WanKenobi prova a produrre qualcosa con Console.Write
Tiago Duarte,

5
In vs 2017 devi selezionare OGNI test che viene eseguito, quindi fare clic su output - non molto utile quando hai molti test. Voglio vedere tutti gli output insieme, non in finestre separate.
inliner49er,

37

È possibile utilizzare questa riga per scrivere nella finestra di output di Visual Studio:

System.Diagnostics.Debug.WriteLine("Matrix has you...");

Deve essere eseguito in modalità debug.


7
Non scrive sul mio VS
Luis Filipe il

1
controlla questa discussione per i dettagli - stackoverflow.com/questions/1159755/…
Dmitry Pavlov

1
Questo ha funzionato benissimo per me usando MSTest e R # per visualizzare l'output. Grazie!
Isaac Baker,

2
@William si presenta se esegui il debug di un test, ma non se lo esegui semplicemente senza debug.
yoyo

29

Come detto, i test unitari sono progettati per essere eseguiti senza interazione.

Tuttavia, è possibile eseguire il debug di unit test, proprio come qualsiasi altro codice. Il modo più semplice è utilizzare il Debugpulsante nella scheda Risultati del test.

Essere in grado di eseguire il debug significa essere in grado di utilizzare i punti di interruzione. Essere in grado di usare i punti di interruzione, quindi, significa essere in grado di usare i Tracepoints , che trovo estremamente utili nel debug di tutti i giorni.

In sostanza, i Tracepoints consentono di scrivere nella finestra Output (o, più precisamente, nell'output standard). Facoltativamente, puoi continuare a correre o puoi fermarti come un normale punto di interruzione. Questo ti dà la "funzionalità" che stai chiedendo, senza la necessità di ricostruire il tuo codice o riempirlo con informazioni di debug.

Aggiungi semplicemente un punto di interruzione, quindi fai clic con il pulsante destro del mouse su quel punto di interruzione. Seleziona l'opzione "When Hit ...":

Quando si colpisce l'opzione

Il che fa apparire la finestra di dialogo:

Quando viene raggiunto un breakpoint

Alcune cose da notare:

  1. Si noti che il punto di interruzione ora viene mostrato come un diamante, anziché come una sfera, che indica un punto di traccia
  2. Puoi generare il valore di una variabile racchiudendola come {this}.
  3. Deseleziona la casella di controllo "Continua esecuzione" per interrompere il codice su questa riga, come qualsiasi punto di interruzione normale
  4. Hai la possibilità di eseguire una macro. Fai attenzione: potresti causare effetti collaterali dannosi.

Vedi la documentazione per maggiori dettagli.


24

Esistono diversi modi per scrivere l'output da un test di unità di Visual Studio in C #:

  • Console.Write: il cablaggio di test di Visual Studio acquisirà questo e lo mostrerà quando si seleziona il test in Esplora test e si fa clic sul collegamento Output. Non viene visualizzato nella finestra di output di Visual Studio durante l'esecuzione o il debug di un unit test (probabilmente questo è un bug).
  • Debug.Write: il cablaggio di test di Visual Studio lo acquisirà e lo mostrerà nell'output del test. Viene visualizzato nella finestra di output di Visual Studio durante il debug di un test unitario, a meno che le opzioni di debug di Visual Studio non siano configurate per reindirizzare l'output alla finestra immediata. Nulla verrà visualizzato nella finestra Output (o immediato) se si esegue semplicemente il test senza debug. Per impostazione predefinita, è disponibile solo in una build di debug (ovvero quando viene definita la costante DEBUG).
  • Trace.Write: il cablaggio di test di Visual Studio acquisirà questo e lo mostrerà nell'output del test. Viene visualizzato nella finestra Output (o immediato) di Visual Studio durante il debug di un unit test (ma non quando si esegue semplicemente il test senza debug). Per impostazione predefinita, disponibile nelle build Debug e Release (ovvero quando viene definita la costante TRACE).

Confermato in Visual Studio 2013 Professional.


1
Si noti che le regole sono leggermente diverse se si utilizza NUnit e l'estensione NUnit Test Adapter per Visual Studio anziché il framework di test Microsoft incorporato.
yoyo

9

Puoi usare

Trace.WriteLine()

per scrivere nella finestra Output quando si esegue il debug di un unit test.


5

In Visual Studio 2017, "TestContext" non mostra il collegamento Output in Test Explorer.

Tuttavia, Trace.Writeline () mostra il collegamento Output.


Solo un FYI, la sua Trace.WriteLine
TroySteven

4

Innanzitutto, i test unitari dovrebbero , in base alla progettazione , essere eseguiti completamente senza interazione.

A parte questo, non penso che ci sia una possibilità a cui si è pensato.

Potresti provare a hackerare con AllocConsole P / Invoke che aprirà una console anche quando l'applicazione corrente è un'applicazione GUI. La Consoleclasse verrà quindi inviata alla console ora aperta.


1
Hmm .. Il mio motivo principale è quello di scrivere alcuni dati extra sulla console per vedere alcuni dettagli più profondi. Sarà una cosa ad hoc di cui potrei non aver bisogno in seguito.
pencilCake


2

IMHO, i messaggi di output sono rilevanti solo per casi di test falliti nella maggior parte dei casi. Ho creato il formato seguente e puoi crearne uno tuo. Questo viene visualizzato nella stessa finestra di Esplora test di Visual Studio.

Come possiamo lanciare questo messaggio nella finestra Esplora test di Visual Studio?

Codice di esempio come questo dovrebbe funzionare:

if(test_condition_fails)
    Assert.Fail(@"Test Type: Positive/Negative.
                Mock Properties: someclass.propertyOne: True
                someclass.propertyTwo: True
                Test Properties: someclass.testPropertyOne: True
                someclass.testPropertyOne: False
                Reason for Failure: The Mail was not sent on Success Task completion.");

Puoi avere una classe separata dedicata a questo per te.


Ho deciso di aggiungere anche questo. In Visual Studio 2019 utilizzando XUNIT è possibile effettuare le seguenti operazioni: Assert.True (esito positivo, "ELIMINA REGISTRAZIONE NON RIUSCITA"); DELETE RECORD FAILED verrà quindi visualizzato in VS 2019 Test Explorer. Ancora una volta, come la risposta sopra, questo funziona solo quando il test dell'unità non ha superato la condizione prevista.
TroySteven,

1

Ho una soluzione più semplice (che ho usato di recente, per una serie di motivi pigri). Aggiungi questo metodo alla classe in cui stai lavorando:

public static void DumbDebug(string message)
{
    File.WriteAllText(@"C:\AdHocConsole\" + message + ".txt", "this is really dumb. I wish Microsoft had more obvious solutions to its solutions problems.");
}

Quindi ... apri la directory AdHocConsole e ordina per ora creata. Assicurati di aggiungere le "dichiarazioni di stampa". Sono distinti però, altrimenti ci saranno giocoleria.


0

Visual Studio per Mac

Nessuna delle altre soluzioni ha funzionato su Visual Studio per Mac

Se si utilizza NUnit , è possibile aggiungere un piccolo .NET progetto console alla soluzione e quindi fare riferimento al progetto che si desidera verificare nei riferimenti di quel nuovo progetto console .

Qualunque cosa tu [Test()]stia facendo con i tuoi metodi, puoi farlo nell'applicazione Mainconsole in questo modo:

class MainClass
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Console");

        // Reproduce the unit test
        var classToTest = new ClassToTest();
        var expected = 42;
        var actual = classToTest.MeaningOfLife();
        Console.WriteLine($"Pass: {expected.Equals(actual)}, expected={expected}, actual={actual}");
    }
}

Sei libero di usare Console.Writee Console.WriteLinenel tuo codice in queste circostanze.

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.