Quais são algumas das práticas recomendadas para preencher e usar um banco de dados de teste?

8

Então, estou desenvolvendo alguns serviços web RESTful Java orientados a banco de dados, usando Hibernate e MySQL. Para fins de teste, estou usando o banco de dados de memória H2. H2 é agradável e rápido, então isso funcionou muito bem. O único problema é que preencher as tabelas do banco de dados antes dos meus testes é meio entediante. Basicamente, crio e persisto à mão um monte de objetos. Estou me perguntando se talvez eu esteja seguindo o caminho errado.

Diga-me, quais são as melhores práticas para fazer o que estou tentando fazer? Alguma ferramenta que poderia me ajudar? Alguma estratégia ou dica geral?

sangfroid
fonte

Respostas:

4

Suponho que você tenha projetado sua API para poder identificar os detalhes do seu banco de dados; caso contrário, poderemos ajudá-lo.

Em termos de terminologia, você deseja usar um Fake Test Double . Nesse caso específico, eu recomendaria usar o mesmo DB (H2) na memória, mas use o DBUnit para trabalhar com o JUnit para criar suas tabelas, preenchê-las antes de cada teste, truncar os dados após cada teste e, finalmente, desmontar as tabelas assim que seu TestSuite estiver concluído.

Existem outras soluções, como Grails e Spring Roo, que criam alguns dados de teste para você, mas o DBUnit funcionará como um deleite para você agora.

Martijn Verburg
fonte
+1 para DBUnit. Torna o código do banco de dados de teste da unidade muito mais agradável.
TMN
Legal - eu definitivamente vou verificar isso. No momento, estou dizendo ao Hibernate para criar automaticamente as tabelas, usando a propriedade hibernate.hbm2ddl.auto = create-drop. Isso funcionará com o DBUnit ou devo parar de fazer isso?
Sangfroid
Ele vai trabalhar com ele sim - na verdade, uma das maneiras para DBUnit mímico é simplesmente inserir dados como POJOs através Hibernate
Martijn Verburg
Impressionante! Ok, eu vou verificar isso.
precisa
Além disso, é necessário usar o DI para isso? No momento, tenho um persistance.xml na minha pasta / main / resources / META-INF que especifica meu servidor de banco de dados acutal e um persistance.xml na minha pasta / test / resources / META-INF que especifica H2. Isso parece funcionar muito bem. Em geral, estou super-ultra-100% confuso sobre o Spring - nunca o usei antes e não entendo como isso poderia me ajudar aqui, mesmo que todo mundo diga que devo usá-lo.
precisa
1

Talvez você se beneficie da utilização de uma estrutura de simulação nos seus testes de unidade automatizados?

Há um número de diferentes para você escolher:

maple_shaft
fonte
Sim, eu já uso o Mockito para testes de unidade. Mas também quero fazer testes (integração?) Que cheguem ao DB.
Sangfroid
+1 por sugerir estruturas de simulação sobre soluções de banco de dados. A abordagem do banco de dados introduz complexidade frequentemente desnecessária, que acaba testando o Hibernate em vez de seus DAOs. Além disso, eu adicionaria o JMockit nessa lista - ele faz tudo . String imutável? Acho que não.
Gary Rowe
1
Bem, devo mencionar que sou novo no Hibernate. Portanto, é realmente importante para mim testar se fiz todas as minhas coisas de hibernação corretamente. Além disso, parece que muitas operações não puderam ser testadas com uma estrutura de simulação. Por exemplo, você tem um método que retorna vários registros. Como você pode testar esse método realmente retorna um monte de registros se você não possui um banco de dados para executar?
precisa
@angelroid, este é um bom argumento e algo de que também posso me beneficiar. A lógica de hibernação e as consultas HQL especificamente não testam bem a unidade no sentido tradicional. No passado, dependia de testes de unidade de integração para verificar a funcionalidade, mas estes eram quase sempre específicos do ambiente e frágeis. DBUnit foi mencionado em uma resposta anterior e parece que merece uma segunda olhada.
Maple_shaft
1

Tudo o que você realmente pode fazer é persistir objetos manualmente ou ter um banco de dados pré-construído carregado. Você também precisa garantir que o banco de dados seja redefinido após cada teste.

Em um projeto em que estou trabalhando, sou novo no Hibernate, por isso tenho vários testes para relacionamento básico e operações em cascata. Usando TestNG, tenho uma GenericHbTestclasse da qual todos os testes do Hibernate se estendem. Ele possui um @BeforeMethodmétodo que reexporta o esquema db e alguns métodos utilitários para gerar vários objetos DAO. Isso me permite personalizar um ambiente para cada teste.

A única desvantagem de reexportar o esquema a cada teste é que leva muito tempo para concluir a execução dos testes. Mas eu só preciso ter certeza de que tudo está separado e limpo. Se você tem mais experiência com o Hibernate e tem um esquema mais estável, então a reexportação antes de cada teste provavelmente é desnecessária. Pelo menos, limpe todas as tabelas de antemão

TheLQ
fonte
1

Você já considerou a serialização de objetos? Este é o método mais rápido e fácil que eu usei.

Consiste em criar o estado desejado, serializá-lo em disco. Você usa esses arquivos para preencher o banco de dados na memória usado para seus testes.

Uma das vantagens é que você pode editar os arquivos manualmente posteriormente.

Como alternativa, se você estiver bem organizado em seus testes de unidade, poderá criar geradores de objetos. Quando os testes são iniciados, o banco de dados é instanciado e o esquema é exportado (usando o nHibernate). Objetos são gerados e preenchidos no banco de dados.

Este método tem uma vantagem sobre o primeiro: seus geradores de objetos evoluem com o seu código, para que você não precise se preocupar com seus arquivos, como na sugestão anterior.


fonte
+1 para uma abordagem interessante, mas pode ser um pouco frágil.
Gary Rowe