Me pediram para fazer um pequeno projeto paralelo para fornecer um aplicativo simples a um de nossos clientes. Normalmente, eu trabalhava no código de back-end em que todas as minhas necessidades de teste foram descobertas e ainda não tive o prazer duvidoso de escrever testes para a GUI, por isso não é claro para mim como devo configurar o código de teste e as ferramentas para um EXE.
Meu primeiro instinto foi simplesmente incluir os testes com o código do aplicativo, no entanto, isso exigiria o fornecimento de várias dependências específicas do teste, as quais fui instruído a não enviar especificamente para o cliente. Também não consigo extrair dinheiro para uma ferramenta de teste criada para fins específicos, por isso preciso usar as ferramentas que tenho em mãos ( StoryQ , RhinoMocks e NUnit), que realmente deve ser mais do que suficiente para testar o comportamento de um aplicativo GUI simples. Até onde eu posso ver, isso me deixa tentando encontrar um bom equilíbrio entre manter o design realmente simples, ou fazer uma engenharia de propósito intencional em prol dos testes. Parece que estou construindo o aplicativo com a lógica de negócios em uma biblioteca separada e testando-a como normalmente, ou encontrando algum outro mecanismo para permitir o executável sem quebrar módulos adicionais que o design do aplicativo não faz realmente preciso.
Edit:
Observe que esta pergunta é sobre como estruturar o relacionamento entre o NUnit e o meu executável - em oposição a uma DLL - e não sobre como separar a apresentação e a lógica de negócios.
/Editar
Então, minha pergunta é:
- Existe um método específico / recomendado para configurar um aplicativo GUI simples com testes de unidade para me permitir verificar adequadamente o estado e o comportamento, usando as ferramentas que tenho à mão e sem recorrer à engenharia em excesso?
- Perdi algo fundamental sobre a maneira como o NUnit deve ser chamado / configurado ao testar um EXE (em vez de uma DLL)?
- Você pode me fornecer ou apontar exemplos de como conseguir tudo isso?
Sei que pode haver mais de uma maneira de fazer isso, por isso estou procurando diretrizes de implementação específicas com base na sua experiência.
Respostas:
Mencionei em um de meus comentários à resposta de simoraman que havia pensado em algumas maneiras de fazer isso. Uma das minhas opções era semelhante à sugestão na resposta de Jalayn de criar um projeto duplicado e gerar uma DLL, enquanto minha outra idéia era simplesmente vincular os arquivos no projeto em que havia o código que eu queria testar. Embora seja possível que ambas as opções funcionem, elas são inferiores ao ideal.
No segundo caso, eu teria uma confusão de dependências de unidade para gerenciar, a menos que eu pudesse separar a arquitetura para minimizar as dependências. Isso é bom para projetos menores, mas os maiores podem facilmente se tornar uma bagunça real de gerenciar. Minha maior resistência a essa opção, porém, é a pura deselegância dela. Claro que eu poderiafazê-lo funcionar, mas, ao fazer isso, eu preciso efetivamente quebrar o encapsulamento para testar os internos de um assembly diretamente via fonte, em vez de testar as interfaces públicas, o que, na minha opinião, é um grande não-não. Da mesma forma, ter um arquivo de projeto adicional significaria duplicar esforços em dois projetos por vez ou encontrar uma maneira de adicionar configurações de arquivo de projeto automaticamente a dois arquivos por vez ou lembrar-se de copiar e renomear o campo do projeto toda vez que eu criar. Talvez isso possa ser automatizado no servidor de compilação, mas seria uma tarefa difícil de gerenciar no IDE. Mais uma vez, pode funcionar, mas na melhor das hipóteses é um incômodo e, se você entender errado, é um incômodo.
A melhor maneira parece ser fazer o que está comentado na minha pergunta e simplesmente incluir o EXE como uma referência no projeto de teste. Acontece que um EXE é efetivamente tratado da mesma maneira que uma DLL nesse caso, e eu posso acessar todas as minhas classes em camadas para testar o que flutua no meu barco.
fonte
Eu penso isso:
Estas são as regras que eu gosto de seguir, seja Java ou C # (exceto que não há nenhum problema de EXE no Java, é claro :-))
Quanto a como configurar seu ambiente de teste, parece-me que você tem pelo menos essas duas opções:
Usando o MSBuild
Crie um clone do seu arquivo .proj (por exemplo, myproject-as-dll.proj ). Altere o
OutputType
arquivo clonado de "EXE
" para "Library
". Agora, usando o comando MSBuild, você pode produzir uma biblioteca que pode ser definida como referência em seu projeto, contendo casos de teste do NUnit.Parece-me possível, mas nunca o usei com tanta honestidade, por isso não tenho certeza. Além disso, você pode não ter o MSBuild no servidor de teste de integração e não sei se ele pode ser separado do Visual Studio ...
Usando NAnt
Se você não estiver familiarizado com o NAnt, precisará pesquisar no Google como configurar o seu projeto. Talvez verifique isso , é um pouco antigo, mas o autor comentou os arquivos NAnt e, se achar auto-explicativo ( Editar: examinando seu arquivo com mais detalhes, acho seu arquivo de configuração extremamente reutilizável ). Ele também faz muito mais do que apenas construir, pois executa casos de teste e lança ferramentas de cobertura de código. Agora, admito que nunca usei o NAnt, ao contrário do pai e do pai "Ant" de Java, que usei muito, mas vejo que é exatamente a mesma coisa e não acho difícil aprender isso.
Com essa ferramenta, você pode criar uma configuração que permita:
Com um pouco mais de código, você pode até:
Tudo é feito sem alterar nada nos arquivos do Visual Studio. E, na verdade, para mim não me parece excesso de engenharia, é apenas um arquivo. Pode levar um, talvez dois dias para fazer tudo funcionar, mas você terá, em minha opinião, uma boa configuração.
Por fim, daria ao cliente tudo o que é necessário para construir, testar e executar os projetos. Costumo pensar que isso mostra o seu profissionalismo e o fato de você escrever código com qualidade em sua mente (o que me parece que você faz desde que procura soluções elegantes)
fonte
Só porque o projeto é pequeno (inicialmente) não significa que a arquitetura adequada exagere na engenharia. O fato de você querer escrever testes informa que seu projeto não é um hack único e trivial.
Você não mencionou qual GUI-Framework você está usando. O WPF MVVM (Model-View-ViewModel) é bom e permite que você escreva testes para toda a lógica com bastante facilidade. Com o WinForms, ouvi coisas boas sobre o MVP (Model-View-Presenter)
fonte
Dê uma olhada na minha resposta nesta pergunta: Como configurar o MVP para uma solução WinForms?
Na verdade, escrevi um aplicativo de exemplo que mostra como eu estrato e como testo minha GUI.
lendo sua edição: use um executor de teste que se integre ao seu ambiente de desenvolvimento. Eu uso o ReSharper.
fonte
Eu havia escrito o Nunit WinForms há alguns anos (acho que há 6 anos). Uma coisa que me lembro especificamente é que, embora seja um caso de teste de unidade, ele também atua como um caso de teste de ponta a ponta. Às vezes, não há muito o que testar em um front end (um formulário simples). Portanto, mesmo que você esteja tentando testar uma caixa de mensagem aparecendo com o clique de um botão, você está involuntariamente testando vários outros métodos de outras camadas. Existem algumas coisas que você não pode automatizar também. A aparência, a sensação e a usabilidade não podem ser automatizadas usando o teste de unidade automatizado. Você precisará executar alguns testes manuais antes de liberar.
fonte