olá Pessoal,
No post de hoje vamos ver como rodar unit tests usando o DBUnit com MySql. O DBUnit é uma API para fazermos testes unitários usando um banco de dados.
Starting…
Para rodar os testes automatizados é muito simples: precisamos apenas escolher o banco que vamos rodar e de um (ou mais) arquivos .xml que vai representar os dados a serem testados.
***Crie um projeto Java.
1. Primeiro passo é criar o arquivo hibernate.cfg.xml com as configurações do banco onde os testes serão executados.
<hibernate-configuration>
<session-factory >
<property name=“hibernate.connection.driver_class”>org.gjt.mm.mysql.Driver</property>
<property name=“hibernate.connection.password”>camilo</property>
<property name=“hibernate.connection.url”>jdbc:mysql://localhost/test</property>
<property name=“hibernate.connection.username”>root</property>
<property name=“hibernate.dialect”>org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name=“hibernate.show_sql”>true</property>
</session-factory>
</hibernate-configuration>
2. Criar uma classe que obtém a SessionFactory com base nas informações do arquivo hibernate.cfg.xml
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
sessionFactory = new Configuration().configure().buildSessionFactory();
return sessionFactory;
}
}
3. Criaremos um arquivo .xml (chame como quiser, chamarei de datalogin.xml. Ele deve tá no src do seu projeto)que representa a tabela do banco, conforme abaixo:
<?xml version=“1.0” encoding=“UTF-8”?>
<dataset>
<login id=“1” login=“camilo” senha=“124”/>
<login id=“2” login=“neto” senha=“234”/>
</dataset>
4. Agora vamos criar a nossa classe de Teste. Para questão apenas de explicação, subscrevi alguns métodos da classe do DBunit para explicar como as coisas funcionam, porém em outros é necessário implementarmos para que o DBunit saiba onde ele terá que conectar e pegar os dados:
public class DBunitTest extends DatabaseTestCase{
private Session session;
private IDatabaseConnection conn;
private IDataSet dataSet;
private FileInputStream loadFile;
public DBunitTest() {
try {
session = HibernateUtil.getSessionFactory().openSession();
} catch (Exception e) {
e.getMessage();
}
}
@Before
public void setUp() throws Exception {
// a cada execução dos testes ele limpa e insere
getSetUpOperation();
}
// limpa tudo que tem nas tabelas e faz um insert
@Override
protected DatabaseOperation getSetUpOperation() throws Exception {
return DatabaseOperation.CLEAN_INSERT;
}
/* aqui que tá o pulo do gato
* (non-Javadoc)
* @see org.dbunit.DatabaseTestCase#getConnection()
* fornecemos a forma de conexão ao banco, estou usando o Hibernate
* não usar o método session.getConnection() ele está deprecated e vai sumir na versão 4.0
*/
@Override
protected IDatabaseConnection getConnection() throws Exception {
conn = new DatabaseConnection(new Configuration().configure().buildSettings().getConnectionProvider().getConnection());
return conn;
}
/*
* (non-Javadoc)
* @see org.dbunit.DatabaseTestCase#getDataSet()
*
* fazer o load dos dados que serão testados
*/
@Override
protected IDataSet getDataSet() throws Exception {
loadFile = new FileInputStream(“src/datalogin.xml”);
dataSet = new FlatXmlDataSet(loadFile);
return dataSet;
}
}
Para facilitar o entendimento, a explicação está nos comentários in line, assim você lê, olha e aprende direto no código.
Testando
Agora vamos testar. Para isso, certifique-se que o MySql foi inicializado e adicione no final da classe DBunitTest o seguinte teste:
@Test
public void testCheckLoginDataLoaded() throws Exception{
assertNotNull(getDataSet());
int rowCount = getDataSet().getTable(“login”).getRowCount();
assertTrue(rowCount!=0); }
O teste é muito simples, apenas quero garantir que estamos conectados ao BD com os dados do dataset (observe que temos assert que verifica isso). O resultado será:
Simples, não? Agora é apenas adicionar os cenários de testes no seu dataset, fazer as devidas implementações do DAO e chamar através dos seus testes.
Vou ficando por aqui.
See ya!!
Camilo,
Você chega a utilizar com frequência testes com os DAO’s e dados do banco de dados? Já havia pensando em usar o DBUnit, porém não achei tanta vantagem em operações triviais, como CRUD, por exemplo.
Não sei na sua opinião, mas os testes com banco não ficam mais convenientes com testes de integração?
Uma sugestão de post e até para estudo seria do framework Arquilian (http://www.jboss.org/arquillian.html) que faz alguns testes integrados com o servidor rodando, ou seja, os testes são feitos “à quente”.
De todo jeito, parabéns pelo post.
Olá Lindomar,
Sim uso bastante. Para operações triviais vc não ver tanto ganho, mas do contrário usar o dbunit, é realmente uma mão nada roda, dar para fazer vários cenários de maneira fácil e com bons testes.
No projeto que estou atuamente fazendo testes de integração tb, que roda com o banco real, é disparado pelo jenkins, após o commit. Mas, no dia-dia do desenvolvimento ninguem vai querer conectar a um banco real, para rodar os testes, vão demorar por vários motivos, então rodamos em memoria localmente, conseguimos ter um espelho do que vai para o banco real e depois do commit deixamos o jenkins cuidar de rodar os testes de integração.
abracos,