GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

43
GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS

Transcript of GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Page 1: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

GRUPO

DATADavid, André, Thiago e Alexandre

WEBCOMPONENTS

Page 2: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conteúdo:

Antes de começar Visão Geral Principais Dependências Externas JAR - Acesso a Dados

Pacote dao Pacote memory_dao Pacote jdbc_dao

Conexão com JDBC Conexão com JDBC e Spring

WAR – Acesso a Dados Log4J Junit DbUnitSeleniumPontos a melhorar no projeto

Page 3: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Antes de começar

Informações Úteis

• No repositório do projeto há uma pasta DOC com o presente slide e um passo-a-passo para criar o banco de dados do projeto.

• O script do banco de dados se encontra dentro do pacote jdbc_dao, no projeto JAR. Seu nome é academicNetDB.sql.

• Os testes com o Selenium estão configurados para executar (por padrão) com o navegador Google Chrome ( http://www.google.com/chrome )

• Algumas explicações no final do slide, em “Pontos a Melhorar no Projeto” podem auxiliar a entender alguns pontos do projeto.

• Esta apresentação possui alguns pontos com explicação evolutiva. Por exemplo, é mostrada a estrutura antes do uso de Spring e depois.

Page 4: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Visão Geral

Page 5: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Principais Dependências Externas

Page 6: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

JARAcesso a Dados

Page 7: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Acesso a Dados - Pacote dao

IDAOFactory

Page 8: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Acesso a dados – IDAOFactoryAbstract Factory (GoF)

Page 9: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Acesso a dados - IDAOFactory

Page 10: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Acesso a dados - JdbcDAOFactory

Conexão com o Bando de Dados

Page 11: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conexão com JDBC - JdbcPostgreConnectionFactory

public class JdbcPostgreConnectionFactory{

public static final String LOCAL_PADRAO = "jdbc:postgresql://localhost:5432/academicNetDB";public static final String DRIVER_PADRAO = "org.postgresql.Driver";private static final String USUARIO = "postgres";private static final String SENHA = "post";

public Connection Create(){

Connection conexao = null;

try{

Class.forName( DRIVER_PADRAO );

conexao = DriverManager.getConnection( LOCAL_PADRAO, USUARIO, SENHA );}catch (final Exception e){

e.printStackTrace();return null;

}

return conexao;}

}

Page 12: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

public class SingletonDAOFactory {

public static IDAOFactory Get(){

return Instance()._daoFactory;}

public Object clone() throws CloneNotSupportedException{

throw new CloneNotSupportedException();}

private static SingletonDAOFactory Instance(){

if ( null == _instance ){

_instance = new SingletonDAOFactory();}

return _instance;}

private SingletonDAOFactory(){

// Substituir por outro DAO Factory caso desejado//_daoFactory = new MemoryDAOFactory();daoFactory = new JdbcDAOFactory(( new JdbcPostgreeConnectionFactory() ).Create());

}

Privat static SingletonDAOFactory _instance;private IDAOFactory _daoFactory;

}

Escolha do acesso a dados - SingletonDAOFactory

Instancia a fábrica desejada

Cria a conexão com o BD

Page 13: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Parametrizando a conexão JDBC usando Spring

Refatorando JdbcPostgreConnection Factory

Page 14: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conexão JDBC e Spring – RefactoringReplace Type Code with Class em JdbcPostgreConnectionFactory criando ParametrosConexao

1

Page 15: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conexão JDBC e Spring – Refactoring

2Replace Type Code with Class em JdbcPostgreConnectionFactory criando ParametrosConexao

Após, Rename em JdbcPostgreConnectionFactory para ConnectionFactory

Page 16: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conexão JDBC e Spring - applicationContext.xmlServirá para instanciar ParametrosConexao com os valores desejados

...

<bean id="paramConexao" class="br.com.senac.DATA.dao.ParametrosConexao" ><constructor-arg index="0" value ="jdbc:postgresql://localhost:5432/academicNetDB" /><constructor-arg index="1" value ="org.postgresql.Driver" /><constructor-arg index="2" value ="postgres" /><constructor-arg index="3" value ="post" />

</bean>

<bean id="daoFactoryCreator" class="br.com.senac.DATA.jdbc_dao.JdbcDAOFactoryCreator" ></bean>

...

Page 17: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conexão JDBC e Spring – IDAOFactoryCreatorFactoryMethod (GoF)

public interface IDAOFactoryCreator {

IDAOFactory create(ParametrosConexao parametros);

}

public class JdbcDAOFactoryCreator implements IDAOFactoryCreator {

public IDAOFactory create(ParametrosConexao parametros) {

ConnectionFactory connectionFactory = new ConnectionFactory( parametros );JdbcDAOFactory daoFactory = new JdbcDAOFactory( connectionFactory.create() );

return ( daoFactory );}

}

Page 18: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Conexão JDBC e Spring – Carregando os parâmetrosAlteração em SingletonDAOFactory

public class SingletonDAOFactory {

...

private SingletonDAOFactory()

{ApplicationContext appC =

new ClassPathXmlApplicationContext( "applicationContext.xml" );

IDAOFactoryCreator daoFactoryCreator =(IDAOFactoryCreator) appC.getBean( "daoFactoryCreator" );

ParametrosConexao parametros = (ParametrosConexao) appC.getBean( "paramConexao" );

_daoFactory = daoFactoryCreator.create( parametros );

}

...

}

Page 19: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

WARAcesso a Dados

Page 20: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Escolhendo a fábrica de DAOs com SpringXML similar. Carregamento agora pelo Servlet (enquanto usamos Servlet).

public class MainServlet extends HttpServlet {

private IDAOFactory _daoFactory = null;

public MainServlet() { super();

loadFactory();}

private void loadFactory()

{ApplicationContext appC = new XmlWebApplicationContext();

IDAOFactoryCreator daoFactoryCreator =(IDAOFactoryCreator) appC.getBean( "daoFactoryCreator" );

ParametrosConexao parametros = (ParametrosConexao) appC.getBean( "paramConexao" );

_daoFactory = daoFactoryCreator.create( parametros ); }

...}

Page 21: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Log4JConfiguração e Uso

Page 22: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Log4J – Configuração da dependência - pom.xml

</dependencies>...

<!-- LOG4J --><dependency>

<groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.14</version><scope>compile</scope>

</dependency>

</dependencies>

Page 23: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Configuração do Log4J por XML - log4j.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration PUBLIC "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="myAppender" class="org.apache.log4j.RollingFileAppenderr"> <layout class="org.apache.log4j.HTMLLayout"/> </appender>

<root> <!-- all|debug|info|warn|error|fatal|off|null --> <priority value="debug" /> <appender-ref ref="myAppender"/> </root>

</log4j:configuration>

Page 24: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Exemplo de Uso do Log4J no projeto

public class JdbcAlunoDAO implements IAlunoDAO {

...private static Logger logger =

Logger.getLogger( JdbcAlunoDAO.class.getName() );

...

public void Adicionar(Aluno aluno) throws DAOException {

try{

String sql = "INSERT INTO ALUNO ( NOME, MATRICULA ) VALUES ( ?, ? )";

PreparedStatement pre = _conexao.prepareStatement( sql );

pre.setString( 1, aluno.getNome() );pre.setString( 2, aluno.getMatricula() );

pre.executeUpdate();}catch (Exception e){

logger.error( e.getMessage(), e );throw new DAOException( e.getMessage() );

}}...

}

Page 25: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

EMMA, Clover, Cobertura, etc.Configuração

Page 26: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

<build><plugins>

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>emma-maven-plugin</artifactId><version>1.0-alpha-1</version><inherited>true</inherited><executions>

<execution><phase>process-classes</phase><goals>

<goal>instrument</goal></goals>

</execution></executions>

</plugin>

...</plugins>

</build>

EMMA – Configuração do Plugin - pom.xml

<reporting><plugins>

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>emma-maven-plugin</artifactId><version>1.0-alpha-1</version><inherited>true</inherited>

</plugin>...

</plugins></reporting>

Page 27: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

SureFire – Configuração do Plugin - pom.xml

<build><plugins>

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><inherited>true</inherited><configuration>

<forkMode>once</forkMode><reportFormat>xml</reportFormat><classesDirectory>${project.build.directory}/generated-classes/emma/

classes</classesDirectory></configuration>

</plugin>...

</plugins> </build>

<reporting><plugins>

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>surefire-report-maven-plugin</artifactId><inherited>true</inherited>

</plugin>...

</plugins> </reporting>

Page 28: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Clover – Configuração do Plugin - pom.xml

<build><plugins>

<plugin><groupId>com.atlassian.maven.plugins</groupId><artifactId>maven-clover2-plugin</artifactId><configuration>

<targetPercentage>50%</targetPercentage></configuration><executions>

<execution><phase>verify</phase><goals>

<goal>instrument</goal><goal>check</goal>

</goals></execution>

</executions></plugin>

...</plugins>

</build>

Page 29: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Cobertura – Configuração - pom.xml

<reporting>

<plugins><plugin>

<groupId>org.codehaus.mojo</groupId><artifactId>cobertura-maven-plugin</artifactId>

</plugin>

...

</plugins></reporting>

Page 30: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

jUnit, DbUnit, SeleniumTestes e Configuração

Page 31: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Cobertura – Configuração - pom.xml

<reporting>

<plugins><plugin>

<groupId>org.codehaus.mojo</groupId><artifactId>cobertura-maven-plugin</artifactId>

</plugin>

...

</plugins></reporting>

Page 32: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

@Testpublic void naoPermiteTurmasIguais() {

Turma t1 = new Turma();t1.setCodigo("1");t1.setDiaSemana("segunda");t1.setTurno("manhã");

Turma t2 = new Turma();t2.setCodigo("2");t2.setDiaSemana("segunda");t2.setTurno("manhã");

boolean chamouExcecao = false;

try{

sala.alocarTurma( t1 );sala.alocarTurma( t2 ); // Deve falhar !

}catch (Exception e){

chamouExcecao = true;}

assertTrue( chamouExcecao );}

JUnit – Exemplo de teste - TesteSala.java

Page 33: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

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

DbUnit – Configuração Básica - pom.xml

Page 34: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

DbUnit – XML com dados de teste - DAOTestData.xml

<?xml version='1.0' encoding='UTF-8'?><dataset>

<EMENTA CONTEUDO="SOA" NUM_AULAS="8" DATA_EMENTA="2001-12-30" /><EMENTA CONTEUDO="TMS" NUM_AULAS="10" DATA_EMENTA="2001-11-30" /><EMENTA CONTEUDO="RUP" NUM_AULAS="10" DATA_EMENTA="2001-10-30" />

<FUNCIONARIO DATA_ADMISSAO="01/04/2004" FUNCAO="faxineiro" MATRICULA="001" NOME="joao das couves" /><FUNCIONARIO DATA_ADMISSAO="01/04/2005" FUNCAO="professor" MATRICULA="002" NOME="thiagao" /><FUNCIONARIO DATA_ADMISSAO="01/04/2006" FUNCAO="diretor" MATRICULA="003" NOME="pavio curto" /><FUNCIONARIO DATA_ADMISSAO="01/04/2007" FUNCAO="inspetor" MATRICULA="004" NOME="ze bagunca" />

<SALA NUMERO="1" BLOCO="A" CAMPUS="CENTRO-RJ" CAPACIDADE="50" /><SALA NUMERO="2" BLOCO="B" CAMPUS="CENTRO-RJ" CAPACIDADE="45" /><SALA NUMERO="3" BLOCO="C" CAMPUS="Santa Tereza" CAPACIDADE="50" />

</dataset>

Page 35: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

DbUnit – Execução do teste pelo XML - JdbcDAOTest.java

public void insertIntoCurrentDataSet()throws DatabaseUnitException, SQLException

{DatabaseOperation.INSERT.execute(

_testDatabaseConnection,_currentDataSet);

}

public void compareTables() throws Exception{

ITable actualTable = newTableFromConnection();ITable expectedTable = newTableFromFile();

ITable filteredTable = DefaultColumnFilter.includedColumnsTable(actualTable,expectedTable.getTableMetaData().getColumns());

Assertion.assertEquals( expectedTable, filteredTable );}

@Testpublic void testInsertionFromFile() throws Exception{

insertIntoCurrentDataSet();

compareTables();}

Page 36: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

public class TesteJdbcEmentaDAO extends JdbcDAOTest {

private static final String TABELA_EMENTA = "EMENTA";private static final String ARQUIVO_EMENTA = "DAOTestData.xml";

public TesteJdbcEmentaDAO() throws Exception{

super( TABELA_EMENTA, ARQUIVO_EMENTA );}

DbUnit – Criação simplificada dos testes

Classes de teste que herdam de JdbcDAOTestsó configuram o nome da tabela e o XML.

A classe já faz a execução dos testes, comoinserção e remoção e comparação dosvalores esperados com base no XML.

Assim, as classes terão seu BD testado enecessitam, então, só de testar o acesso

via DAO.

Page 37: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

public void testInsereERecuperaCorretamente() throws Exception{

final int ID = 999999;Ementa ementa = novaEmenta( ID );Ementa ementaGravada = null;

IEmentaDAO dao = daoFactory().CriarEmentaDAO();dao.Adicionar( ementa );ementaGravada = dao.CarregarPeloID( ID );

assert( ementaGravada != null );assert( ementa.equals( ementaGravada ) );

}

dbUnit – Exemplo de teste - TesteJdbcEmentaDAO.java

Exemplo de teste do DAO

Page 38: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Selenium – Configuração Básica - pom.xml

<dependency><groupId>org.openqa.selenium.server</groupId><artifactId>selenium-server</artifactId><version>1.0-20081010.060147</version><scope>test</scope>

</dependency>

<dependency><groupId>org.seleniumhq.selenium.client-drivers</groupId><artifactId>selenium-java-client-driver</artifactId><version>1.0.1</version><scope>test</scope>

</dependency>

Page 39: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

private void entrarEmEmenta(){

selenium.click( "name=ementa" );selenium.waitForPageToLoad( _helper.TEMPO_ESPERA );

}

public void testInserir() throws Exception{

entrarEmEmenta();

selenium.click( "name=ementaInserir" );selenium.waitForPageToLoad( _helper.TEMPO_ESPERA );

final String CONTEUDO = "TDD";

selenium.type( "conteudo", CONTEUDO );selenium.type( "numeroAulas", "20" );selenium.type( "dataEmenta", "05/10/2008" );

selenium.click( "btnConfirma" );selenium.waitForPageToLoad( _helper.TEMPO_ESPERA );

entrarEmEmenta();selenium.click( "name=ementaListar" );selenium.waitForPageToLoad( _helper.TEMPO_ESPERA );

assertTrue( selenium.isTextPresent( CONTEUDO ) );}

Selenium – Exemplo de Teste - TesteEmentaSelenium.java

Page 40: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Pontos a melhorar no projetoDbUnit

Atualmente os parâmetros do banco de dados estão sendo carregados com o Spring. O ideal é colocar a configuração no próprio POM, informando o(s) arquivo(s) XML e operações desejadas para execução. Assim, pouparia-se tempo criando testes para novas classes. Porém, no presente trabalho foi criada uma classe JdbcDAOTest que bastando parametrizar o nome da tabela e o arquivo XML ela executa testes sobre o banco de dados, o que elimina o trabalho da reimplementação de testes do mesmo tipo.

Por causa do carregamento via Spring, os testes do banco de dados funcionam corretamente quando executados pelo ambiente JUnit. Porém, executando pelo maven test, como a configuração não está no POM, ele não reconhece no processo os parâmetros do Spring, o que faz com que não consiga a conexão com o banco, dando falha no teste. Assim, para verificação atual do BD e dos DAOs, os testes são rodados usando JUnit.

Page 41: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Pontos a melhorar no projetoExemplo de como poderia ser a configuração do DbUnit<plugin> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.4.5</version>

<dependencies> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>8.3-603.jdbc4</version> </dependency>

</dependencies>

<configuration><driver>org.postgresql.Driver</driver><url>jdbc:postgresql://localhost:5432/academicNetDB</url><username>postgres</username><password>post</password>

</configuration>

<executions><execution>

<phase>pre-integration-test</phase> <!-- <phase>test-compile</phase> --> <goals>

<goal>start-server</goal> <!-- <goal>operation</goal> --></goals>

<configuration><type>CLEAN_INSERT</type>

<src>DAOTestData.xml</src> </configuration>

</execution> </executions> </plugin>

Page 42: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.

Pontos a melhorar no projetoSelenium

Atualmente os parâmetros do site, como url, porta e tempo de carregamento da página estão definidas como constantes na classe SeleniumTestHelper. Poderia-se criar esta configuração usando o próprio Spring, ou no própria configuração do POM.

Observação: Com o uso do Jetty como servidor (e não do TomCat, que era o utilizado em trabalhos anteriores) foi notado em alguns momentos que era preciso executar o projeto (maven jetty:run) para iniciar o servidor e, então, iniciar os testes (maven test). Com o Tomcat, era comum se iniciar o servidor pelo próprio Eclipse e então executar os testes.

Spring

Usou se no projeto o Servlet padrão. Poderia ter sido utilizado o Servlet do Spring, de forma que seria dispensado a criação dos Commands, bastando fazer um mapeamento dados páginas do projeto. A implementação com Commands foi mantida por falta de tempo hábil (assim como ocorreu com os demais pontos).

Page 43: GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.