Normas ISO 9000 Alexandre G. Lages Cristiano C. A. Soares Thiago C. Nascimento.
GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.
Transcript of GRUPO DATA David, André, Thiago e Alexandre WEBCOMPONENTS.
GRUPO
DATADavid, 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
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.
Visão Geral
Principais Dependências Externas
JARAcesso a Dados
Acesso a Dados - Pacote dao
IDAOFactory
Acesso a dados – IDAOFactoryAbstract Factory (GoF)
Acesso a dados - IDAOFactory
Acesso a dados - JdbcDAOFactory
Conexão com o Bando de Dados
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;}
}
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
Parametrizando a conexão JDBC usando Spring
Refatorando JdbcPostgreConnection Factory
Conexão JDBC e Spring – RefactoringReplace Type Code with Class em JdbcPostgreConnectionFactory criando ParametrosConexao
1
Conexão JDBC e Spring – Refactoring
2Replace Type Code with Class em JdbcPostgreConnectionFactory criando ParametrosConexao
Após, Rename em JdbcPostgreConnectionFactory para ConnectionFactory
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>
...
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 );}
}
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 );
}
...
}
WARAcesso a Dados
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 ); }
...}
Log4JConfiguração e Uso
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>
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>
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() );
}}...
}
EMMA, Clover, Cobertura, etc.Configuração
<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>
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>
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>
Cobertura – Configuração - pom.xml
<reporting>
<plugins><plugin>
<groupId>org.codehaus.mojo</groupId><artifactId>cobertura-maven-plugin</artifactId>
</plugin>
...
</plugins></reporting>
jUnit, DbUnit, SeleniumTestes e Configuração
Cobertura – Configuração - pom.xml
<reporting>
<plugins><plugin>
<groupId>org.codehaus.mojo</groupId><artifactId>cobertura-maven-plugin</artifactId>
</plugin>
...
</plugins></reporting>
@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
<dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.4.5</version> <scope>test</scope> </dependency>
DbUnit – Configuração Básica - pom.xml
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>
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();}
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.
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
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>
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
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.
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>
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).