Estou escrevendo testes para um projeto que consiste em vários submódulos. Cada caso de teste que escrevi é executado independentemente um do outro e eu limpo todos os dados entre os testes.
Embora os testes sejam executados de forma independente, estou pensando em impor uma ordem de execução, pois alguns casos exigem mais de um submódulo. Por exemplo, um submódulo está gerando dados e outro está executando consultas nos dados. Se o submódulo que gera os dados contiver um erro, o teste para o submódulo de consulta também falhará, mesmo que o próprio submódulo funcione bem.
Não posso trabalhar com dados fictícios, pois a principal funcionalidade que estou testando é a conexão com um servidor remoto de caixa preta, que obtém apenas os dados do primeiro submódulo.
Nesse caso, não há problema em impor uma ordem de execução para os testes ou é uma má prática? Sinto que há um cheiro nessa configuração, mas não consigo encontrar uma maneira melhor de contornar.
edit: a pergunta é de Como estruturar testes onde um teste é a configuração de outro teste? como o teste "anterior" não é uma instalação, mas testa o código que executa a instalação.
fonte
Respostas:
Esta é a parte chave para mim. Você pode falar sobre "testes de unidade" e eles "executando independentemente um do outro", mas todos parecem que dependem desse servidor remoto e do "primeiro submódulo". Então, tudo soa bem acoplado e depende do estado externo. Como tal, você está de fato escrevendo testes de integração. A execução desses testes em uma ordem específica é bastante normal, pois são altamente dependentes de fatores externos. Uma execução de teste ordenada, com a opção de sair antecipadamente da execução de teste, se algo der errado, é perfeitamente aceitável para testes de integração.
Mas também vale a pena dar uma nova olhada na estrutura do seu aplicativo. Ser capaz de simular o primeiro submódulo e o servidor externo permitiria que você escrevesse testes de unidade verdadeiros para todos os outros submódulos.
fonte
Sim, é uma prática ruim.
Geralmente, um teste de unidade destina-se a testar uma única unidade de código (por exemplo, uma única função baseada em um estado conhecido).
Quando você deseja testar uma cadeia de eventos que podem ocorrer na natureza, deseja um estilo de teste diferente, como um teste de integração. Isso é ainda mais verdadeiro se você estiver dependendo de um serviço de terceiros.
Para fazer testes unitários como esse, é necessário descobrir uma maneira de injetar os dados fictícios, por exemplo, implementar uma interface de serviço de dados que espelha a solicitação da Web, mas retorna dados conhecidos de um arquivo de dados fictício local.
fonte
A ordem de execução imposta que você propõe apenas faz sentido se você também interromper a execução de teste após a primeira falha.
Interromper a execução do teste na primeira falha significa que cada execução pode descobrir apenas um único problema e não pode encontrar novos problemas até que todos os problemas anteriores tenham sido corrigidos. Se o primeiro teste a ser executado encontrar um problema que leva um mês para ser corrigido, durante esse mês efetivamente nenhum teste será executado.
Se você não interromper a execução do teste na primeira falha, a ordem de execução forçada não comprará nada, porque cada teste com falha precisa ser investigado de qualquer maneira. Mesmo que apenas para confirmar que o teste no submódulo de consulta está falhando devido à falha que também foi identificada no submódulo de geração de dados.
O melhor conselho que posso dar é escrever os testes de maneira que seja fácil identificar quando uma falha em uma dependência está causando a falha do teste.
fonte
O cheiro a que você está se referindo é a aplicação do conjunto errado de restrições e regras aos seus testes.
Os testes de unidade geralmente são confundidos com "testes automatizados" ou "testes automatizados por um programador".
Os testes de unidade devem ser pequenos, independentes e rápidos.
Algumas pessoas leem incorretamente isso como "testes automatizados escritos por um programador devem ser pequenos independentes e rápidos" . Mas isso significa simplesmente que, se seus testes não são pequenos, independentes e rápidos, eles não são testes de unidade e, portanto, algumas das regras para testes de unidade não devem, não podem ou não devem ser aplicadas para seus testes. Um exemplo trivial: você deve executar seus testes de unidade após cada compilação, o que não deve ser feito para testes automatizados que não são rápidos.
Embora seus testes não sejam testes de unidade, você pode pular uma regra e ter alguma interdependência entre os testes, mas também descobriu que existem outras regras que você pode ter perdido e precisará reintroduzir - algo para o escopo de outra pergunta .
fonte
Como observado acima, o que você está executando parece ser um teste de integração, mas você afirma que:
E este pode ser um bom lugar para começar a refatoração. O módulo que executa consultas nos dados não deve depender de uma implementação concreta do primeiro módulo (geração de dados). Em vez disso, seria melhor injetar uma interface contendo os métodos para acessar esses dados e isso pode ser zombado para testar as consultas.
por exemplo
Se você tem:
Em vez disso, prefira:
Isso remove a dependência das consultas na fonte de dados e permite que você configure testes de unidade facilmente repetíveis para cenários específicos.
fonte
As outras respostas mencionam que a ordem dos testes é ruim (o que é verdade na maioria das vezes), mas há uma boa razão para impor a ordem na execução do teste: garantir que seus testes lentos (por exemplo, testes de integração) sejam executados após os testes mais rápidos (testes que não dependem de outros recursos externos). Isso garante que você execute mais testes mais rapidamente, o que pode acelerar o ciclo de feedback.
fonte