É má prática para testes executados em um banco de dados em vez de falsos repositórios?

StackOverflow https://stackoverflow.com/questions/607620

Pergunta

Eu sei o que as vantagens são e eu usar dados falsos quando eu estou trabalhando com sistemas mais complexos.

E se eu estou desenvolvendo algo simples e que pode facilmente configurar meu ambiente em um banco de dados real e os dados que estão sendo acessados ??é tão pequena que o tempo de acesso não é um fator, e eu só estou executando alguns testes.

É ainda importante criar dados falsos ou posso esquecer o extra de codificação e pular para a coisa real?

Quando eu disse banco de dados real Eu não quero dizer um banco de dados de produção, quer dizer, um banco de dados de teste, mas usando um real DBMS ao vivo e o mesmo esquema como o banco de dados real.

Foi útil?

Solução

As razões para usar dados falsos em vez de uma verdadeira DB são:

  1. Velocidade. Se os testes são lentos você não está indo para executá-los. Zombando da DB pode fazer seus testes de correr muito mais rápido do que de outra forma poderiam.
  2. Controle. Seus testes devem ser a única fonte de seus dados de teste. Quando você usar dados falsos, seus testes de escolher qual finge que você estará usando. Portanto, não há chance de que seus testes são estragadas porque alguém deixou a DB em um estado desconhecido.
  3. Order Independência. Queremos que os nossos testes para ser executável em qualquer ordem em tudo. A entrada de um teste não deve depender da saída do outro. Quando os testes de controlar os dados de teste, os testes podem ser independentes uns dos outros.
  4. Ambiente Independência. Os testes devem ser executável em qualquer ambiente. Você deve ser capaz de executá-los quando no trem ou em um avião, ou em casa, ou no trabalho. Eles não devem depender de serviços externos. Quando você usar dados falsos, você não precisa de um DB externo.

Agora, se você está construindo uma pequena aplicação pouco, e usando uma verdadeira DB (como MySQL), você pode atingir os objetivos acima, em seguida, por todos os meios usar o DB. Eu faço. Mas não se enganem, como o aplicativo cresce, você acabará por ser confrontado com a necessidade de zombar o DB. Isso é ok, fazê-lo quando for necessário. YAGNI. Apenas certifique-se de fazê-lo quando você precisa. Se você deixá-lo ir, você vai pagar.

Outras dicas

É uma espécie de depende do que você deseja testar. Muitas vezes você quiser testar a lógica real em seu código não os dados no banco de dados, por isso a criação de um banco de dados completo apenas para executar os testes é um desperdício de tempo.

Considere também a quantidade de trabalho que vai para a manutenção de seus testes e testdatabase. Teste seu código com um banco de dados, muitas vezes significa que o seu estão testando a sua aplicação como um todo, em vez das diferentes partes em isolamento. Isso muitas vezes resultar em um monte de manutenção de trabalho, tanto o banco de dados e os testes em sincronia.

E o último problema é que o teste deve ser executado em isolamento para que cada teste deve ser executada em sua própria versão do banco de dados ou deixá-lo exatamente no mesmo estado em que estava antes da RAN teste. Isto inclui o estado depois de um teste falhado.

Dito isto, se você realmente quer teste em seu banco de dados você pode. Existem ferramentas que ajuda para configurar e derrubando um banco de dados, como dbunit .

Eu vi pessoas tentando criar teste de unidade como esta, mas quase sempre acaba por ser muito mais trabalho, então é realmente valha a pena. Mais abandonados pela metade durante o projeto, a maioria abandonando TTD completamente durante o projeto, pensando que a transferência de experiência para o teste de unidade em geral.

Então, eu recomendaria manter testes simples e isolado e encapsular o código de bom o suficiente torna-se possível testar seu código em isolamento.

Eu acho que depende de suas consultas são fixos dentro do repositório (a opção melhor, IMO), ou se os expõe repositório consultas componíveis; por exemplo - se você tiver um método de repositório:

IQueryable<Customer> GetCustomers() {...}

Em seguida, o UI pode solicitar:

var foo = GetCustomers().Where(x=>SomeUnmappedFunction(x));

bool SomeUnmappedFunction(Customer customer) {
   return customer.RegionId == 12345 && customer.Name.StartsWith("foo");
}

Isso vai passar para um falso repo baseada em objetos, mas falhará para implementações db reais. Claro, você pode anular isso por ter a alça repositório de todas as consultas internamente (sem composição externo); por exemplo:

Customer[] GetCustomers(int? regionId, string nameStartsWith, ...) {...}

Uma vez que este não pode ser composto, você pode verificar o banco de dados e interface do usuário de forma independente. Com consultas componíveis, você é forçado a testes de integração uso durante todo se você quer que ele seja útil.

É algo que depende se o DB é automaticamente criada pelo teste, também se o banco de dados é isolado de outros desenvolvedores.

No momento pode não ser um problema (por exemplo, apenas um desenvolvedor). No entanto (para a configuração do banco de dados manual) a criação do banco de dados é um impedimento extra para a execução de testes, e isso é uma coisa muito ruim.

Se você está apenas escrevendo uma simples one-off aplicativo que você absolutamente sabe que não vai crescer, eu acho que um monte de "melhores práticas" apenas vá para a direita para fora da janela.

Você não necessidade usar DI / IOC ou ter testes de unidade ou zombar de seu acesso db se tudo que você está escrevendo é uma forma simples "Fale Conosco". No entanto, onde traçar a linha entre um app "simples" e um "complexo" é difícil.

Em outras palavras, use o bom senso como não há uma resposta dura e pronto para isso.

É ok fazer isso para o cenário, contanto que você não vê-los como testes "Unidade". Esses seriam os testes de integração. Você também pode querer considerar se você será testar manualmente através da interface do usuário e outra vez, como você pode apenas automatizado seus testes de fumo em seu lugar. Dado que, você pode até considerar não fazer os testes de integração em tudo, e apenas trabalho no funcional / ui testa nível (como eles já estará cobrindo a integração).

Como os outros como fora pontas, é difícil traçar a linha no complexo / não complexa, e você normalmente seria agora, quando já é tarde demais :(. Se você já está acostumado a fazer-los, eu tenho certeza que você ganhou' . t ficar muito em cima Se isso não fosse o caso, você pode aprender com ele:)

Quanto ao real DB não entrar em seu caminho, e você pode ir mais rápido dessa forma, eu seria pragmática e ir para ele.

Na unidade-teste, o "teste" é mais importante do que a "unidade".

Supondo que você deseja automatizar isso, a coisa mais importante é que você pode programaticamente gerar sua condição inicial. Parece que esse é o caso, e ainda melhor que você está testando dados do mundo real.

No entanto, existem algumas desvantagens:

Seu banco de dados real não pode cobrir certas condições em seu código. Se você tiver dados falsos, você causar esse comportamento acontecer.

E como você aponta, você tem uma aplicação simples; quando se torna menos simples, você vai querer ter testes que você pode categorizar como testes unitários e testes do sistema. Os testes de unidade devem visar um simples pedaço de funcionalidade, o que será muito mais fácil fazer com os dados falsos.

Uma das vantagens de falsos repositórios é que seu teste de regressão / unidade é consistente, pois você pode esperar os mesmos resultados para as mesmas consultas. Isto torna mais fácil para construir certos testes de unidade.

Existem várias desvantagens se o seu código (-query ler se não só) de dados modifica: - Se você tem um erro no seu código (que é provavelmente porque você está testando), você pode acabar quebrando o banco de dados de produção. Mesmo se você não quebrá-lo. - se o banco de dados de produção muda ao longo do tempo e, especialmente, enquanto seu código está em execução, você pode perder o controle dos materiais de teste que você adicionou e ter um tempo difícil depois de limpá-lo fora do banco de dados. - consultas de Produção de outros sistemas que acessam o banco de dados pode tratar os seus dados de teste como dados reais e isso pode resultados corruptos de importantes processos de negócio em algum lugar abaixo da estrada. Por exemplo, mesmo se você marcou os seus dados com uma certa bandeira ou prefixo, você pode garantir que qualquer pessoa que acessar o banco de dados irá aderir a este esquema?

Além disso, alguns bancos de dados são regulados por leis de privacidade, assim, dependendo de seu contrato e que possui o principal DB, você pode ou não ser legalmente autorizados a real acesso de dados.

Se você precisa para ser executado em um banco de dados de produção, eu recomendaria em execução em uma cópia que você pode facilmente criar durante o horário de pico.

É uma aplicação muito simples, e você não pode vê-lo crescer, eu não vejo nenhum problema executar seus testes em um DB real. Se, no entanto, você acha que esta aplicação vai crescer, é importante que você conta para que em seus testes.

Mantenha tudo o mais simples possível, e se você exigir testes mais flexível, mais tarde, torná-lo assim. Planeje com antecedência embora, porque você não quer ter um enorme aplicação em 3 anos que se baseia em testes antigos e hacky (para um aplicativo grande).

As desvantagens para a execução de testes contra seu banco de dados é a falta de velocidade e a complexidade para a criação de seu estado de banco de dados antes de executar testes.

Se você tem controle sobre isso, não há problema em executar os testes diretamente no banco de dados; é realmente uma abordagem bom porque ele simula o seu produto final melhor do que correr contra dados falsos. A chave é ter uma abordagem pragmática e ver melhor prática como diretrizes e não regras.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top