• Share
  • ?
  • Profiles ▼
  • Communities ▼
  • Apps ▼

Blogs

  • My Blogs
  • Public Blogs
  • My Updates

This community can have members from outside your organization. iMasters

  • Log in to participate
fd26864d-cb41-49cf-b719-d89c6b072893 Blog

▼ Tags

▼ Similar Entries

How to Identify Clas...

Blog: Application I...
MicheleCalcavecchia 270000HCF1
Updated
0 people like thisLikes 0
No CommentsComments 0

How to ensure that a...

Blog: CSE-Sterling ...
Paul Barrie 270003JP87
Updated
0 people like thisLikes 0
No CommentsComments 0

z/TPF rules engine d...

Blog: TPF Blog
Chris Filachek 270007S5UM
Updated
0 people like thisLikes 0
No CommentsComments 0

Updates to z/TPF sup...

Blog: TPF Blog
lemie 060000M2N6
Updated
3 people like thisLikes 3
No CommentsComments 0

IBM ITSM Netcool Ope...

Blog: Network and S...
Murali-Pa 270002P65C
Updated
3 people like thisLikes 3
No CommentsComments 0

▼ Archive

  • January 2014
  • August 2013
  • July 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • April 2010

▼ Blog Authors

iMasters

View All Entries
Clicking the button causes a full page refresh. The user could go to the "Entry list" region to view the new content.) Entry list

Automatizando testes com JUnit, DBUnit e Spring

iMasters 27000343BF | | Tags:  junit automatização java desenvolvimento dbunit spring testes ‎ | 6,810 Views
Nós, desenvolvedores, deveríamos estar acostumados com a criação de testes automatizados, pois escrevê-los faz parte do processo de  metodologias ágeis.

Sem processos de desenvolvimento ágeis será que você é ágil mesmo?

Essa é um pergunta para refletirmos. O simples fato de utilizamos alguma metodologia como Scrum, Kamban, Lean, e continuarmos desenvolvendo da mesma maneira, acredito eu que seja um dos erros de equipes que se julgam ágeis.

Mas voltando ao nosso foco, que é conversar sobre testes automatizados, vamos falar um pouco mais sobre o framework DBUnit. Ele é uma extensão do JUnit para criação de testes de banco de dados, entre outras coisas. Escrever objetos Mocks para fazer testes em que há acesso a banco de dados é uma estratégia para resolver esse tipo de teste. Outra estratégia seria acessar uma base de dados de desenvolvimento e executar os testes nela, muitos frameworks fazem dessa forma.

Utilizando o DBUnit teremos algumas facilidades como:

  • Limpeza de registros após testes;
  • Comparação direta de registros;
  • Retorno de estado pós-teste;
  • Popular banco antes do teste.

O DBUnit irá funcionar como um facilitador para os nossos testes.

Criando nossos Teste com JUnit, DBUnit e Spring

Construiremos nossa aplicação baseado em JUnit 4.x, pois é muito mais confortável utilizar anotações de testes e o Spring para fazer a nossa injeção de dependência, assim podemos separar configurações de testes da de implementação real. Para fazer o nosso build e gerenciar as dependências, vamos utilizar do Maven 2 (Confira as novidades do Maven 3.0 aqui).

Adicionando as dependências no nosso pom.xml

Editaremos nosso pom.xml para que atenda às nossas necessidades, para isso vamos adicionar as dependências do JUnit 4.x, DBunit e ao Spring conforme abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
       
<modelVersion>4.0.0</modelVersion>
       
<groupId>brenooliveira</groupId>
       
<artifactId>testes-automatizados</artifactId>
       
<packaging>war</packaging>
       
<version>1.0.0-SNAPSHOT</version>
       
<name>Testes Automatizados com JUnit, DBUnit e Spring</name>
       
<url>http://www.brenooliveira.com.br/</url>

       
<dependencies>

               
<dependency>
                       
<groupId>junit</groupId>
                       
<artifactId>junit</artifactId>
                       
<version>4.8.2</version>
                       
<scope>test</scope>
               
</dependency>

               
<dependency>
                       
<groupId>org.dbunit</groupId>
                       
<artifactId>dbunit</artifactId>
                       
<version>2.4.8</version>
                       
<scope>test</scope>
               
</dependency>

               
<dependency>
                       
<groupId>org.springframework</groupId>
                       
<artifactId>spring</artifactId>
                       
<version>2.5.6</version>
               
</dependency>

               
<dependency>
                       
<groupId>org.springframework</groupId>
                       
<artifactId>spring-test</artifactId>
                       
<version>2.5.6</version>
               
</dependency>

               
<dependency>
                       
<groupId>mysql</groupId>
                       
<artifactId>mysql-connector-java</artifactId>
                       
<version>5.0.8</version>
               
</dependency>

       
</dependencies>
       
<build>
               
<plugins>
                       
<plugin>
                               
<artifactId>maven-compiler-plugin</artifactId>
                               
<configuration>
                                       
<compilerVersion>1.6</compilerVersion>
                                       
<source>1.6</source>
                                       
<target>1.6</target>
                               
</configuration>
                       
</plugin>
               
</plugins>
       
</build>
</project>

No  pom.xml acima apenas adicionamos os JARS do JUnit, DBUnit e dois JARS do spring um para testes.

O que iremos fazer nos testes

O exemplo será um simples update de tabela no MySQL, mas com o DBUnit você pode testar Querys mais elaboradas e inserções, entre outras coisas.

Configurando nosso DBUnit

Vamos preparar o ambiente para utilizar o DBUnit. Ele precisa de um arquivo XML, chamado dataset.xml, e na maior parte do tempo vamos trabalhar com XMLs, onde vamos definir onde nos colocamos as estruturas de nossas tabelas. No exemplo, teremos uma tabela Pessoas com a seguinte estrutura SQL:

CREATE TABLE pessoas(
        id
int not null auto_increment,
        nome varchar
(255) not null,
        aniversario date
not null,
        primary key
(id)
);

Agora vamos definir o arquivo dataset.xml conforme abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
   
<person id="1" nome="Breno Oliveira" aniversario="1985-12-26" />
</dataset>

Observe que o XML criado é muito parecido com o SQL. Os nomes dos campos do SQL se transformam propriedades da nossa tag.

Temos nosso primeiro dataset, mas o DBUnit ainda espera um dataset de retorno. Como mencionei, vamos fazer apenas um update na tabela. Então nosso dataset ficará da seguinte forma:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
   
<person id="1" nome="Breno Oliveira Alterado" aniversario="1985-12-26" />
</dataset>

Configurando nosso DataSource com o Spring

O Bean abaixo define o DataSource para a conexão com um banco de dados MySQL:

<beans xmlns="http://www.springframework.org/schema/beans"
       
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p">
 
<bean id="dataSource"
               
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
               
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/spronline"
               
p:username="root" p:password="123456" />

</beans>

Sem muitas novidades na definição deste bean, ele apenas faz uma conexão com um banco de dados MySQL.

Escrevendo nosso teste

O passos para nossos teste serão:

  1. Carregar os dados antes para nossos métodos de teste;
  2. Vamos carregar o banco de dados por JDBC para simular a aplicação;
  3. Realizar os testes propriamente ditos, nos quais vamos comparar se o valor alterado está conforme o nosso XML de resultado esperado;
  4. E, finalizando nossa classe, iremos limpar a base de dados.

Observe a nossa classe de teste:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
public class TestDBUnitWithSpring {

       
@Autowired
       
private DataSource dataSource;

       
@Before
       
public void init() throws Exception{
               
// Insere os dados no banco de dados
               
DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());
       
}

       
@After
       
public void after() throws Exception{
               
//Limpa a base de dados
               
DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet());
       
}

       
private IDatabaseConnection getConnection() throws Exception{
           
// Pega a conexão com o banco de dados
               
Connection con = dataSource.getConnection();
               
DatabaseMetaData  databaseMetaData = con.getMetaData();
               
IDatabaseConnection connection = new DatabaseConnection(con,databaseMetaData.getUserName().toUpperCase());
               
return connection;
       
}

       
private IDataSet getDataSet() throws Exception{
               
// Pega o arquivo de para inserir
               
File file = new File("src/test/resources/dataset.xml");
               
return new FlatXmlDataSet(file);
       
}

       
@Test
       
public void testSQLUpdate() throws Exception{
               
Connection con = dataSource.getConnection();
               
Statement stmt = con.createStatement();
               
// Pega o valor atual
               
ResultSet rst = stmt.executeQuery("select * from pessoas where id = 1");
               
if(rst.next()){
                       
// compara a partir de dataset.xml
                        assertEquals
("Breno Oliveira", rst.getString("nome"));
                        rst
.close();

                       
// atualiza via SQL
                       
int count = stmt.executeUpdate("update pessoas set nome='Breno Oliveira Alterado' where id=1");

                        stmt
.close();
                        con
.close();

                       
// expera somente 1 linha de alteração
                        assertEquals
("one row should be updated", 1, count);

                       
// Fetch database data after executing the code
                       
QueryDataSet databaseSet = new QueryDataSet(getConnection());
                       
// filtra os dados
                        databaseSet
.addTable("pessoas", "select * from pessoas where id = 1");
                       
ITable actualTable = databaseSet.getTables()[0];

                       
// Carrega os dados esperados a partir do XML
                       
IDataSet expectedDataSet = new FlatXmlDataSet(new File("src/test/resources/expectedDataSet.xml"));
                       
ITable expectedTable = expectedDataSet.getTable("pessoas");

                       
// Filtra colunas desnessarias dos dados atuais definidos pelo XML
                        actualTable
= DefaultColumnFilter.includedColumnsTable(actualTable, expectedTable.getTableMetaData().getColumns());

                       
// Assert da base de dados atual com os dados esperados
                        assertEquals
(1,expectedTable.getRowCount());
                        assertEquals
(expectedTable.getRowCount(), actualTable.getRowCount());
                        assertEquals
(expectedTable.getValue(0, "nome"), actualTable.getValue(0, "nome"));

               
} else {
                        fail
("no rows");
                        rst
.close();
                        stmt
.close();
                        con
.close();
               
}

       
}
}

Anotamos a classe com @RunWith(SpringJUnit4ClassRunner.class) para o JUnit rodar os testes com o Spring Test. E também anotamos a classe com o @ContextConfiguration(locations={"classpath:applicationContext.xml"}), que define o nosso arquivos de XML onde estão nossas configurações, mas você poderia criar um arquivo somente para os testes. As demais observações deixei no código. 

Para o Spring realizar a injeção de dependência, adicionamos @TestExecutionListeners({DependencyInjectionTestExecutionListener.class}), assim podemos usar o nosso @Autowired para nosso Bean de DataSource.

As demais partes do teste são detalhes. Como o foco aqui era exibir como fazer a integração, deixarei somente nos comentários do código.

Comentem!


artigo publicado originalmente no iMasters, por Breno Oliveira

  • Add a Comment Add a Comment
  • Edit
  • More Actions v
  • Quarantine this Entry
Notify Other People
notification_ex

Send Email Notification

Quarantine this entry

deleteEntry
duplicateEntry

Mark as Duplicate

  • Previous Entry
  • Main
  • Next Entry
Feed for Blog Entries | Feed for Blog Comments | Feed for Comments for this Entry