Eu tenho um teste de unidade (nUnit). Muitas camadas abaixo da pilha de chamadas, um método falhará se estiver sendo executado por meio de um teste de unidade.
Idealmente, você usaria algo como simulação para configurar o objeto do qual esse método depende, mas este é um código de terceiros e não posso fazer isso sem muito trabalho.
Não quero configurar métodos específicos do nUnit - há muitos níveis aqui e é uma maneira ruim de fazer o teste de unidade.
Em vez disso, o que eu gostaria de fazer é adicionar algo assim no fundo da pilha de chamadas
#IF DEBUG // Unit tests only included in debug build
if (IsRunningInUnitTest)
{
// Do some setup to avoid error
}
#endif
Então, alguma ideia sobre como escrever IsRunningInUnitTest?
PS: Estou totalmente ciente de que este não é um ótimo design, mas acho que é melhor do que as alternativas.
c#
reflection
nunit
Ryan
fonte
fonte
Respostas:
Já fiz isso antes - tive que segurar meu nariz enquanto fazia, mas consegui. O pragmatismo vence o dogmatismo todas as vezes. Claro, se não é uma boa maneira você pode refatorar para evitá-lo, isso seria ótimo.
Basicamente, eu tinha uma classe "UnitTestDetector" que verificava se o assembly da estrutura NUnit foi carregado no AppDomain atual. Ele só precisava fazer isso uma vez e, em seguida, armazenar em cache o resultado. Feio, mas simples e eficaz.
fonte
AppDomain.GetAssemblies
e verificaria o assembly relevante - para o MSTest, você precisaria verificar quais assemblies são carregados. Veja a resposta de Ryan como exemplo.Pegando a ideia de Jon, isso é o que eu tive -
Pule na parte de trás, somos todos meninos grandes o suficiente para reconhecer quando estamos fazendo algo que provavelmente não deveríamos;)
fonte
Adaptado da resposta de Ryan. Este é para a estrutura de teste de unidade MS.
O motivo pelo qual preciso disso é porque mostro uma MessageBox sobre erros. Mas meus testes de unidade também testam o código de tratamento de erros, e não quero que uma MessageBox apareça durante a execução de testes de unidade.
E aqui está um teste de unidade para isso:
fonte
Simplificando a solução de Ryan, você pode simplesmente adicionar a seguinte propriedade estática a qualquer classe:
fonte
Eu uso uma abordagem semelhante ao Tallseth
Este é o código básico que pode ser facilmente modificado para incluir o cache. Outra boa ideia seria adicionar um setter
IsRunningInUnitTest
e chamarUnitTestDetector.IsRunningInUnitTest = false
o ponto de entrada principal do seu projeto para evitar a execução do código.fonte
Pode ser útil, verificar o ProcessName atual:
E esta função também deve ser verificada por teste de unidade:
Referências:
Matthew Watson em http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/11e68468-c95e-4c43-b02b-7045a52b407e/
fonte
|| processName.StartsWith("testhost") // testhost.x86
para VS 2019Em modo de teste,
Assembly.GetEntryAssembly()
parece sernull
.Observe que se
Assembly.GetEntryAssembly()
énull
,Assembly.GetExecutingAssembly()
não é.A documentação diz: O
GetEntryAssembly
método pode retornarnull
quando um assembly gerenciado foi carregado de um aplicativo não gerenciado.fonte
Em algum lugar do projeto que está sendo testado:
Em algum lugar do seu projeto de teste de unidade:
Elegante, não. Mas direto e rápido.
AssemblyInitializer
é para MS Test. Eu esperaria que outras estruturas de teste tivessem equivalentes.fonte
IsRunningInUnitTest
não é definido como verdadeiro nesses AppDomains.Eu uso isso apenas para ignorar a lógica que desativa todos os TraceAppenders em log4net durante a inicialização quando nenhum depurador está conectado. Isso permite que os testes de unidade sejam registrados na janela de resultados do Resharper, mesmo quando executados no modo sem depuração.
O método que usa esta função é chamado na inicialização do aplicativo ou ao iniciar um dispositivo de teste.
É semelhante à postagem de Ryan, mas usa LINQ, elimina o requisito System.Reflection, não armazena em cache o resultado e é privado para evitar o uso incorreto (acidental).
fonte
Ter uma referência à estrutura nunit não significa que o teste está realmente em execução. Por exemplo, no Unity, quando você ativa os testes do modo de reprodução, as referências da nunidade são adicionadas ao projeto. E quando você executa um jogo, as referências existem, então UnitTestDetector não funcionaria corretamente.
Em vez de verificar o assembly do nunit, podemos pedir ao nunit api para verificar se o código está sendo executado no teste ou não.
Editar:
Esteja ciente de que o TestContext pode ser gerado automaticamente se for necessário.
fonte
Basta usar isto:
No modo de teste, ele retornará falso.
fonte
Fiquei infeliz por ter esse problema recentemente. Eu resolvi isso de uma maneira um pouco diferente. Primeiro, eu não estava disposto a supor que o framework nunit nunca seria carregado fora de um ambiente de teste; Eu estava particularmente preocupado com os desenvolvedores executando o aplicativo em suas máquinas. Então, em vez disso, percorri a pilha de chamadas. Em segundo lugar, fui capaz de presumir que o código de teste nunca seria executado em binários de lançamento, portanto, certifiquei-me de que esse código não existisse em um sistema de lançamento.
fonte
Funciona como um encanto
.
fonte
Os testes de unidade irão ignorar o ponto de entrada do aplicativo. Pelo menos para wpf, winforms e aplicativo de console
main()
não está sendo chamado.Se o método principal for chamado, então estamos em tempo de execução , caso contrário, estamos no modo de teste de unidade :
fonte
Considerando que seu código é normalmente executado no thread principal (gui) de um aplicativo do Windows Forms e você deseja que ele se comporte de forma diferente durante a execução de um teste, você pode verificar
Estou usando isso para o código que desejo
fire and forgot
em um aplicativo gui, mas nos testes de unidade, posso precisar do resultado calculado para uma declaração e não quero mexer com vários threads em execução.Funciona para MSTest. A vantagem é que meu código não precisa verificar a estrutura de teste em si e se eu realmente preciso do comportamento assíncrono em um determinado teste, posso definir meu próprio SynchronizationContext.
Esteja ciente de que este não é um método confiável para,
Determine if code is running as part of a unit test
conforme solicitado pelo OP, uma vez que o código pode estar sendo executado dentro de um thread, mas para certos cenários, esta pode ser uma boa solução (também: Se eu já estiver executando a partir de um thread de segundo plano, pode não ser necessário para iniciar um novo).fonte
Application.Current é nulo quando executado no testador de unidade. Pelo menos para o meu aplicativo WPF usando o testador de unidade MS. É um teste fácil de fazer, se necessário. Além disso, algo para se ter em mente ao usar Application.Current em seu código.
fonte
Usei o seguinte em VB em meu código para verificar se estamos em um teste de unidade. especificamente, eu não queria que o teste abrisse o Word
fonte
Que tal usar reflexão e algo assim:
var underTest = Assembly.GetCallingAssembly ()! = typeof (MainForm) .Assembly;
O assembly de chamada estará onde seus casos de teste estão e apenas substituirá o MainForm por algum tipo que está em seu código sendo testado.
fonte
Também há uma solução muito simples quando você está testando uma classe ...
Basta fornecer à classe que você está testando uma propriedade como esta:
Agora seu teste de unidade pode definir o booleano "thisIsUnitTest" como verdadeiro, portanto, no código que você deseja pular, adicione:
É mais fácil e rápido do que inspecionar as montagens. Lembra-me do Ruby On Rails, onde você olha para ver se está no ambiente de TESTE.
fonte