Por que usar o banco de dados na memória para teste de integração?


18

Estou realmente confuso quando vejo muita implementação de banco de dados na memória usada para teste, porque também ouvi muitas práticas recomendadas de teste de integração de que o ambiente que executa o teste deve se parecer o mais próximo possível do ambiente de produção, incluindo o sistema operacional , biblioteca, mecanismo de banco de dados etc.

O que estou perdendo aqui?


Eu já vi muito isso, porque você pode garantir programaticamente a consistência dos dados e eles geralmente são razoavelmente rápidos. Especialmente se o seu teste for um teste de unidade, você deseja que seja um sistema fechado. Você deseja que seus testes sejam completamente incluídos no teste.
Rig

É bom para um desenvolvedor poder obter o mais recente de todo o código e executar os testes, sem precisar configurar um banco de dados externo previamente.
Jason Evans

1
Os aspectos que exigem uma grande semelhança com o ambiente de produção pertencem aos testes de carga e de estresse, que devem ser executados separadamente dos testes de unidade (que como um código confirmam os critérios de porta) na minha opinião.
Rwong 9/10

Respostas:


19

Em uma situação típica de desenvolvimento de software, os testes são usados ​​em dois pontos: durante o desenvolvimento e antes de mover o produto ao longo da cadeia de desenvolvimento.

A primeira situação, executar testes durante o desenvolvimento, atende a objetivos de curto prazo: definir tarefas (como no TDD: escrever um teste com falha e depois passar), impedir regressões, garantir que suas alterações não quebrem mais nada, etc. os testes precisam ser extremamente rápidos: idealmente, todo o seu conjunto de testes é executado em menos de 5 segundos e você pode executá-lo em um loop próximo ao seu IDE ou editor de texto enquanto codifica. Qualquer regressão que você introduzir será exibida em segundos. Testes rápidos são mais importantes nesta fase do que capturar 100% de regressões e bugs, e como é impraticável (ou impossível) desenvolver cópias exatas dos sistemas de produção, o esforço necessário para obter testes perfeitos aqui não vale a pena. isto. O uso de bancos de dados na memória é uma troca: eles não são cópias exatas do sistema de produção, mas eles ajudam a manter os testes abaixo do limite de 5 segundos; se a escolha for entre uma configuração de banco de dados ligeiramente diferente para meus testes relacionados ao banco de dados e nenhum teste, eu sei o que escolho.

A segunda situação, movendo o código ao longo da cadeia de desenvolvimento, no entanto, faz exigir testes extensivos. Como podemos (e devemos) automatizar essa parte do processo de desenvolvimento, podemos permitir testes muito mais lentos - mesmo que uma execução de teste completa leve horas, o agendamento de uma construção noturna ainda significa que sempre temos uma imagem precisa da base de código de ontem. Agora é importante simular o ambiente de produção com a maior precisão possível, mas podemos pagar. Portanto, não fazemos a troca no banco de dados de memória: instalamos exatamente a mesma versão do mesmo DBMS que os sistemas de produção e, se possível, preenchemos com dados reais de produção antes do início do teste.


6

Eu acho que é uma velocidade de troca / correspondência com o ambiente. Os testes devem ser executados com frequência, e isso significa que precisam ser rápidos. Especialmente testes de unidade, que não devem demorar mais que alguns segundos.

Os testes de integração serão mais lentos, mas quando forem rápidos, você poderá executá-los com mais frequência. Por exemplo, antes de cada confirmação. Obviamente, não é tão completo quanto um ambiente completo, mas pelo menos você está testando a camada de mapeamento, o SQL gerado, como a parte se comunica etc. etc. No caso de um banco de dados caro, você também garante que não Não é necessário comprar uma licença para todos. Você pode pegar mais erros ao cobrir 90% do código com os testes executados uma vez por hora do que com 100% do teste de código uma vez por dia ou pior semana.

Dito isto, é claro que você precisa testar com o banco de dados real e um ambiente totalmente integrado. Você pode não executar esses testes com tanta frequência, mas, como o teste anterior já lhe deu confiança, tudo o que resta é um bug específico da plataforma.


3

Para fazer testes simples, zombar da camada de acesso ao banco de dados é perfeitamente aceitável. Você chama getName(), chama o DAO que foi ridicularizado e retorna "John" para o primeiro nome e "Smith" para o sobrenome, os reúne e tudo é perfeito. Não há necessidade de testar um banco de dados na unidade.

As coisas se tornam um pouco mais quando a lógica se torna um pouco mais complexa. E se você tivesse um método "createOrUpdateUser (...)". Se você zombou do banco de dados, pode verificar se um determinado método foi chamado uma vez com um determinado parâmetro quando o zombador não retorna objetos e um método diferente é chamado no banco de dados quando retorna um objeto existente. Isso começa a chegar a essa linha difusa, onde pode ser mais fácil (especialmente se já estiver lá) criar um banco de dados especializado em memória e testar esse código com dados pré-configurados.

Em algum código real em que trabalhei (ponto de vendas), tínhamos um resumeSuspededTransaction(...)método. Isso puxaria a transação do banco de dados para um objeto (e seus componentes) e atualizaria o banco de dados. Tínhamos zombado e um bug espreitava o código em algum lugar com a serialização e desserialização dos dados indo para o banco de dados (alteramos um tipo que era serializado de maneira diferente no banco de dados).

O mock não nos mostrou o bug porque estava retornando seu caminho feliz - serialize a transação, armazene-o no mock, desserialize-o do mock, teste se eles são iguais. No entanto, quando você serializa um objeto com um zero à esquerda no banco de dados, ele é descartado e, em seguida, recombinado de volta a uma sequência sem os zeros. Detectamos o bug sem o banco de dados através da solução de problemas (não foi tão difícil de detectar quando soubemos que ele estava lá).

Posteriormente, colocamos um banco de dados e percebemos que o bug nunca teria passado por esse teste de junção se estivéssemos indo para um banco de dados na memória.


Na memória, os bancos de dados têm as vantagens:

  • eles podem ser acelerados rapidamente (sem a necessidade de um DBA para configurar contas, tabelas e outros) para teste
  • os dados podem ser pré-configurados para esse teste
  • o teste não precisa se preocupar em reverter o teste quando terminar
  • cada teste possui seu próprio banco de dados de memória, para que você não precise se preocupar se dois testes estiverem sendo executados simultaneamente
  • eles podem ser executados em sistemas que não têm conectividade com os bancos de dados reais

1

Isso depende muito do sistema de banco de dados que você está usando. Quando o sistema db fornece uma alternativa na memória que é quase 100% API e comportamento compatível com uma configuração de banco de dados baseada em disco (exceto velocidade e segurança contra falhas, é claro), o uso da variante na memória é obviamente bom .

Se, no entanto, seu sistema de banco de dados tiver diferenças significativas entre a configuração na memória e o uso que não está na memória, você está certo: nesse caso, os testes de integração têm um risco maior de ocultar um bug. Mas, mesmo assim, você poderá "abstrair essas diferenças" sozinho, desde que conheça bem o seu sistema de banco de dados e as diferenças.


1

Nas palavras dos leigos:

A zombaria de partes importantes da arquitetura é boa (e indispensável) para testes de unidade .

Mas para testes de integração, concordo plenamente com você. A zombaria não deve ser feita e um ambiente o mais semelhante possível possível.

Afinal, os testes de integração são para testar como as diferentes partes da arquitetura se comportam juntas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.