Posso gravar no console em um teste de unidade? Se sim, por que a janela do console não abre?

148

Eu tenho um projeto de teste no Visual Studio. Eu uso o Microsoft.VisualStudio.TestTools.UnitTesting .

Eu adiciono esta linha em um dos meus testes de unidade:

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

Quando executo o teste, o teste passa, mas a janela do console não é aberta.

Existe uma maneira de disponibilizar a janela do console para interagir através de um teste de unidade?

pencilCake
fonte
1
Realmente depende do corredor. Você pode usar o TestDriven.Net (um ótimo, gratuito para uso pessoal, executor de testes) - o Console.WriteLine gravará no painel de saída do VS.
seldary
1
Obrigado por espalhar a palavra sobre TestDriven.Net
GrayFox374
O NCrunch também possui esse recurso, que por si só faz valer o preço da IMO. Eu tenho um Dumpmétodo de extensão que gera o conteúdo do objeto no console, facilitando muito a depuração. i.imgur.com/MEZwy7X.png
DharmaTurtle

Respostas:

125

NOTA: A resposta original abaixo deve funcionar para qualquer versão do Visual Studio até o Visual Studio 2012. O Visual Studio 2013 não parece mais ter uma janela Resultados do Teste. Em vez disso, se você precisar de uma saída específica de teste, use a sugestão do @ Stretch de Trace.Write()gravar a saída na janela Saída.


O Console.Writemétodo não grava no "console" - ele grava no que estiver conectado ao identificador de saída padrão do processo em execução. Da mesma forma, Console.Readlê a entrada do que estiver conectado à entrada padrão.

Quando você executa um teste de unidade no Visual Studio 2010, a saída padrão é redirecionada pelo equipamento de teste e armazenada como parte da saída de teste. Você pode ver isso clicando com o botão direito do mouse na janela Resultados do teste e adicionando a coluna denominada "Saída (StdOut)" à exibição. Isso mostrará tudo o que foi gravado na saída padrão.

Você pode abrir manualmente uma janela do console, usando P / Invoke, como sinni800 diz . Ao ler a AllocConsoledocumentação, parece que a função será redefinida stdine stdoutmanipulada para apontar para a nova janela do console. (Não tenho 100% de certeza disso; me parece meio errado se eu já redirecionei o stdoutWindows para roubá-lo de mim, mas ainda não tentei.)

Em geral, porém, acho que é uma má ideia; se tudo o que você deseja usar no console é despejar mais informações sobre o seu teste de unidade, a saída existe para você. Continue usando Console.WriteLinedo jeito que está e verifique os resultados de saída na janela Resultados do Teste quando terminar.

Michael Edenfield
fonte
Tente abrir um novo WindowsApplication, usando AllocConsole para alocar um console e ele gravará nele. Não sei o que realmente faz, mas pode não funcionar em um ambiente de teste de unidade. Seria realmente bom saber ...
sinni800
hrm. relendo a AllocConsoledocumentação, posso estar incorreto, mas precisaria testá-lo.
22812 Michael Edenfield
2
Para mim, esse comentário de Michael disse tudo o que eu precisava pensar: "Quando você executa um teste de unidade através do VS2010, a saída padrão é redirecionada pelo equipamento de teste e armazenada como parte da saída de teste".
Robert Patterson
5
no VS2013, se você escrever no console, haverá um rótulo de link [Saída] no TestExplorer / Test / Summary. Clique nele e você obtém a saída desejada. Esperar? Você também deseja chamar Console.ReadLine () ??
Visar
3
No V2017 (Comunidade), vá para "test explorer", selecione o item de resultado do teste na lista e clique no link "output" na outra janela (janela de resultado do teste?). Como provavelmente será truncado, use o "copiar tudo" e passe para outro lugar.
heringer
180

Alguém comentou sobre essa funcionalidade aparentemente nova no Visual Studio 2013. Não sabia ao certo o que ele quis dizer no início, mas agora o faço, acho que merece sua própria resposta.

Podemos usar o Console.WriteLine normalmente e a saída é exibida, não apenas na janela Saída, mas em uma nova janela após clicarmos em "Saída" nos detalhes do teste.

Digite a descrição da imagem aqui

Tiago Duarte
fonte
2
Excelente solução. Confirme se funciona no VS2015 Enterprise.
22417 garfbradaz
6
Infelizmente, não se pode selecionar qualquer texto nessa área de saída para copiar-e-colar :( O que eles estavam pensando ?!
OU Mapper
3
@ORMapper, clique com o botão direito do mouse na área "Saída padrão" e escolha copiar tudo
bychance
2
@ Ovi-WanKenobi tentar produzir algo com Console.Write
Tiago Duarte
5
No vs 2017, você deve selecionar CADA teste executado e clicar na saída - não é muito útil quando você tem muitos testes. Eu quero ver toda a saída juntos - não em janelas separadas.
inliner49er
37

Você pode usar esta linha para gravar na janela Output do Visual Studio:

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

Deve ser executado no modo de depuração.

Dmitry Pavlov
fonte
7
Não escreve no meu VS
Luis Filipe
1
verifique esta discussão para obter detalhes - stackoverflow.com/questions/1159755/… #
Dmitry Pavlov
1
Isso funcionou muito bem para mim usando o MSTest e o R # para visualizar a saída. Obrigado!
Isaac Baker
2
@ William aparece se você depurar um teste, mas não se você simplesmente executá-lo sem depurar.
yoyo
29

Conforme declarado, os testes de unidade são projetados para serem executados sem interação.

No entanto, você pode depurar testes de unidade, como qualquer outro código. A maneira mais fácil é usar o Debugbotão na guia Resultados do teste.

Ser capaz de depurar significa ser capaz de usar pontos de interrupção. Ser capaz de usar pontos de interrupção, portanto, significa poder usar pontos de rastreamento , que acho extremamente úteis na depuração diária.

Essencialmente, os Tracepoints permitem gravar na janela Saída (ou, mais precisamente, na saída padrão). Opcionalmente, você pode continuar executando ou pode parar como um ponto de interrupção regular. Isso fornece a "funcionalidade" que você está solicitando, sem a necessidade de reconstruir seu código ou preenchê-lo com informações de depuração.

Simplesmente adicione um ponto de interrupção e clique com o botão direito do mouse nesse ponto de interrupção. Selecione a opção "When Hit ...":

Ao acertar a opção

O que abre o diálogo:

Quando um ponto de interrupção é atingido

Algumas coisas a serem observadas:

  1. Observe que o ponto de interrupção agora é mostrado como um diamante, em vez de uma esfera, indicando um ponto de rastreamento
  2. Você pode gerar o valor de uma variável colocando-a como {this}.
  3. Desmarque a caixa de seleção "Continuar execução" para que o código seja quebrado nesta linha, como qualquer ponto de interrupção regular
  4. Você tem a opção de executar uma macro. Tenha cuidado - você pode causar efeitos colaterais prejudiciais.

Veja a documentação para mais detalhes.

Wonko, o são
fonte
24

Existem várias maneiras de gravar a saída de um teste de unidade do Visual Studio em C #:

  • Console.Write - O equipamento de teste do Visual Studio captura e mostra quando você seleciona o teste no Gerenciador de Testes e clica no link Saída. Será que não aparecem na janela de saída Visual Studio quando em execução ou depurar um teste de unidade (sem dúvida este é um bug).
  • Debug.Write - O equipamento de teste do Visual Studio captura isso e mostra na saída de teste. Será que aparecem na janela de saída Visual Studio ao depurar um teste de unidade, a menos que opções o Visual Studio depuração são configurados para saída de redirecionamento para a janela imediata. Nada aparecerá na janela Saída (ou Imediato) se você simplesmente executar o teste sem depurar. Por padrão, disponível apenas em uma compilação Debug (ou seja, quando a constante DEBUG está definida).
  • Trace.Write - O equipamento de teste do Visual Studio captura e mostra na saída de teste. Será que aparecem na janela Visual Studio Output (ou Imediata) ao depurar um teste de unidade (mas não quando simplesmente executando o teste sem depuração). Por padrão, disponível nas versões Debug e Release (ou seja, quando a constante TRACE é definida).

Confirmado no Visual Studio 2013 Professional.

yoyo
fonte
1
Observe que as regras são ligeiramente diferentes se você usar a extensão NUnit e o adaptador de teste NUnit para o Visual Studio, em vez da estrutura de teste interna da Microsoft.
yoyo 13/05
9

Você pode usar

Trace.WriteLine()

para gravar na janela Saída ao depurar um teste de unidade.

Sturla
fonte
5

No Visual Studio 2017, "TestContext" não mostra o link Saída no Test Explorer.

No entanto, Trace.Writeline () mostra o link de saída.

naz hassan
fonte
Apenas um FYI, sua Trace.WriteLine
TroySteven
4

Antes de tudo, os testes de unidade devem, por design , executar completamente sem interação.

Com isso de lado, não acho que haja uma possibilidade que tenha sido pensada.

Você pode tentar invadir o AllocConsole P / Invoke, que abrirá um console, mesmo quando seu aplicativo atual for um aplicativo de GUI. A Consoleclasse será postada no console agora aberto.

sinni800
fonte
1
Hmm .. Meu principal motivo é escrever alguns dados extras no console para ver alguns detalhes mais profundos. Será uma coisa adhoc que talvez eu não precise mais tarde.
pencilCake
3

Debug.WriteLine () também pode ser usado.

Jackie
fonte
1
ou Debug.Print ()
Mohamed Selim
2

IMHO, mensagens de saída são relevantes apenas para casos de teste com falha na maioria dos casos. Criei o formato abaixo e você também pode criar o seu. Isso é exibido na própria janela do Visual Studio Test Explorer.

Como podemos lançar essa mensagem na janela do Visual Studio Test Explorer?

Um código de exemplo como este deve funcionar:

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.");

Você pode ter uma aula separada dedicada a isso para você.

DevCod
fonte
Eu brincava que eu adicionaria isso também. No Visual Studio 2019 usando XUNIT, você pode fazer o seguinte: Assert.True (sucesso, "DELETE RECORD FAILED"); DELETE RECORD FAILED será exibido no VS 2019 Test Explorer. Novamente, como a resposta acima, isso só funciona quando seu teste de unidade falha na condição esperada.
TroySteven
1

Eu tenho uma solução mais fácil (que eu me usei recentemente, por uma série de razões preguiçosas). Adicione este método à classe em que você está trabalhando:

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.");
}

Então ... abra o diretório AdHocConsole e faça o pedido por hora criada. Certifique-se de adicionar suas 'instruções de impressão'. Eles são distintos, porém, haverá malabarismo.

John
fonte
0

Visual Studio para Mac

Nenhuma das outras soluções funcionou no Visual Studio para Mac

Se você estiver usando o NUnit , poderá adicionar um pequeno .NET projeto de console à sua solução e, em seguida, referenciar o projeto que deseja testar nas referências desse novo projeto de console .

O que você estava fazendo em seus [Test()]métodos pode ser feito no Mainaplicativo de console desta maneira:

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}");
    }
}

Você é livre para usar Console.Writee Console.WriteLineem seu código nessas circunstâncias.

SwiftArchitect
fonte