Eu tive uma discussão com alguém sobre testes de unidade / integração com aplicativos da web e tenho uma discordância sobre uma ideia central. O problema é que a pessoa com quem estou conversando acha que o banco de dados no qual o teste de unidade trabalha deve ter dados pré-preenchidos e acho que deve estar completamente vazio antes e depois da execução dos testes.
Minha preocupação com dados pré-preenchidos no banco de dados é que não há como garantir que os dados sejam mantidos em bom estado. Os testes em si vão criar, excluir e modificar dados no banco de dados, então não vejo como ter dados no banco de dados antes de iniciar os testes é uma coisa boa.
Parece que a melhor maneira de testar a funcionalidade do banco de dados seria ter as seguintes configurações:
- Em uma fase de "configuração" antes da execução do teste, você primeiro trunca todas as tabelas no banco de dados
- Em seguida, insira todos os dados necessários para os casos de teste que você está prestes a executar
- Então você executa e valida os casos de teste
- Em uma fase de "desmontagem", você trunca mais uma vez todas as tabelas no banco de dados
Não vejo outra maneira melhor de garantir que os dados contra os quais você está testando sejam um bom teste testável.
Estou faltando alguma coisa aqui? Essa não é a melhor maneira de testar a funcionalidade relacionada ao banco de dados? Existe algum benefício em ter um banco de dados pré-preenchido que sempre exista no banco de dados (mesmo antes de iniciar os testes ou após a conclusão dos testes)? Qualquer ajuda em idéias para explicar meu processo de maneira diferente, para melhor entender meu ponto de vista, também seria ótima (isto é, se meu argumento tiver mérito).
Respostas:
Para mim, os testes de unidade não devem lidar com o banco de dados, os testes de integração lidam com o banco de dados.
Os testes de integração que lidam com o banco de dados devem, na prática, ter um banco de dados vazio com uma abordagem de desmontagem e desmontagem, o uso de uma abordagem baseada em transações é um bom caminho a percorrer (por exemplo, criar uma transação na configuração e reversão na desmontagem).
O que seu amigo parece querer fazer é testar do ponto de vista da "regressão", ou seja, ter dados reais lá e ver como o sistema reage, afinal, nenhum sistema é perfeito e geralmente pode haver dados ruins espalhados por algum lugar que forneçam algumas peculiaridades do seu modelo de domínio.
Suas práticas recomendadas são o caminho a seguir, e o que eu costumo fazer é encontrar um cenário para dados incorretos, escrever um teste de integração com uma configuração e desmontar esse cenário exato.
fonte
integration tests
- O que você quer dizer? Como mencionei, os módulos que usam banco de dados podem e devem ser testados com testes de unidade. Banco de Dados me pode zombou manualmente ou substituída por na memória implementaçãoSe seus testes dependem do banco de dados, acho que é mais importante que os dados de seu interesse estejam em um estado conhecido para seus testes, em vez de o banco de dados estar vazio. Uma das medidas dos bons testes é que cada teste deve falhar por um motivo e nenhum outro teste deve falhar pelo mesmo motivo.
Portanto, se seus testes se preocupam com o estado dos dados, coloque-os no estado conhecido e retorne os dados para esse estado após a execução dos testes, para que seus testes sejam reproduzíveis.
Se você pode dissociar seus testes do estado dos dados, zombando, isso também seria uma coisa boa. Você mencionou que está fazendo testes de unidade / integração, mas é claro que essas duas coisas devem ser consideradas separadamente. Seus testes de unidade devem ser desassociados do banco de dados, se possível, e seus testes de integração devem ser testados com o banco de dados em um estado conhecido.
fonte
Bem, vejo um benefício em ter um banco de dados pré-preenchido: você não precisa escrever o código que irá inserir os dados necessários, pois ele existe. Caso contrário, existem apenas desvantagens. Talvez alguém tenha modificado os dados de teste no banco de dados? Talvez alguém tenha tentado atualizar os dados? Mas o pior é ter um caso de teste bagunçando o banco de dados ... Você acaba recriando o banco de dados inteiro manualmente várias vezes.
Você está certo em como os testes devem ser escritos, exceto que eu não truncaria nada:
Agora, esse cenário é ótimo para testes de unidade. Quando precisamos de dados para testes de unidade e integração, descobri que uma grande fase de configuração comum a todos os casos de teste (reagrupamos todas as "inserções" em um método estático) também pode funcionar muito bem. É como um meio termo entre a sua ideia e a do seu amigo. A única desvantagem é que você deve ter muito cuidado ao adicionar alguns dados novos para não quebrar os casos de teste existentes (mas se você adicionar duas ou três linhas por tabela, como fizemos, isso não deve ser um problema)
fonte
Eu acho que você precisa refinar um exemplo com seu colega e descobrir exatamente o que eles significam. Vocês dois podem estar na mesma página.
Exemplo: tabela de transações da conta corrente
Se você conseguir isso executando as etapas 1 e 2 ou iniciando com um banco de dados já nesse estado (restaurar um backup?), Não sei se isso importa. Sua idéia de criar scripts para mim facilita o gerenciamento de quaisquer alterações necessárias (como se você se esquecesse de criar uma conta de administrador e precisasse dela para um novo usuário). Os arquivos de script são mais fáceis de colocar no controle de origem do que algum arquivo de backup. Isso também é afetado pela distribuição ou não deste aplicativo.
fonte
Para desenhar aspectos de algumas respostas juntos e adicionar meu 2p ...
Nota: meus comentários se referem principalmente ao teste do banco de dados , e não ao teste da interface do usuário (embora se aplique obviamente semelhante).
Os bancos de dados precisam tanto de teste quanto os aplicativos de front-end, mas tendem a ser testados com base em 'funciona com o front-end?' ou 'os relatórios produzem o resultado correto?', que na minha opinião está sendo testado muito tarde no processo de desenvolvimento do banco de dados e não é muito robusto.
Temos vários clientes que utilizam testes de unidade / integração / sistema para o banco de dados do data warehouse, além do UAT / performance / et al. testes. Eles descobrem que, com uma integração contínua e testes automatizados, enfrentam muitos problemas antes de chegar ao UAT tradicional, economizando tempo no UAT e aumentando as chances de sucesso do UAT.
Tenho certeza que a maioria concorda que um rigor semelhante deve ser aplicado aos testes de banco de dados e aos testes de front-end ou de relatório.
O principal com o teste é testar pequenas entidades simples, garantindo sua correção, antes de prosseguir para combinações complexas de entidades, garantindo sua correção antes de expandir para o sistema mais amplo.
Então, dando algum contexto à minha resposta ...
Teste de Unidade
As vantagens de fazer isso são que você está removendo todas as dependências externas no teste e executando a menor quantidade de testes para provar a correção. Obviamente, esses testes não podem ser executados no banco de dados de produção. Pode ser que haja vários tipos de testes que você fará, dependendo do tipo de unidade, incluindo:
Teste de Integração (Unidade)
Achei este post do SE útil ao falar sobre vários tipos de teste.
Ao passar de testes de unidade para esses testes de integração, geralmente haverá um pouco mais de dados, para testar uma variedade maior de casos de teste. Obviamente, esses testes não podem ser executados no banco de dados de produção.
Em seguida, ele passa para o Teste do Sistema , Teste de Integração do Sistema (também conhecido como teste de ponta a ponta), com volumes de dados e escopo cada vez maiores. Todos esses testes devem se tornar parte de uma estrutura de teste de regressão. Alguns desses testes podem ser escolhidos pelos usuários para serem executados como parte do UAT, mas UAT são os testes definidos pelos usuários , não como definidos pela TI - um problema comum!
Então agora que eu dei algum contexto, para responder às suas perguntas reais
fonte
Francamente, acho que se você fizer testes de unidade sem um banco de dados aproximadamente do mesmo tamanho do banco de dados de produção existente, terá muitas coisas que passam nos testes e falham na produção para obter desempenho. É claro que sou contra as pessoas que desenvolvem um pequeno banco de dados local por esse motivo também.
E se o código é específico de dados, como você pode testá-lo efetivamente sem dados? Você sentirá falta de ver se as consultas retornaram os resultados corretos. Por que você gostaria de considerar o teste em um banco de dados vazio, tudo o que indica é se a sintaxe está correta e não se a consulta está correta. Isso parece míope para mim. Já vi muitas coisas que são executadas e passam em testes categoricamente errados. Você não quer encontrar isso em testes de unidade? Eu faço.
fonte