quinta-feira, 13 de dezembro de 2007

O Arquivo da(s) Apresentações - Finalmente!

Olá Pessoal,

Segue o link do pdf da apresentação realizada no Natal Java Day e no Rio Java Developers.

Fiquem a vontade para comentar a apresentação.

Em breve concluo os comentários sobre ela.

Abraços.

sexta-feira, 7 de dezembro de 2007

Ops! Mais um evento (agora no Rio)

Olá Pessoal,

É rápido.

Evento de java amanhã no centro do Rio. Inscrições e maiores informações
no site do evento.

Estarei por lá paresentando novamente a palestra de EJB3/JPA

Até lá!

Abraços.

quinta-feira, 22 de novembro de 2007

Feliz, Natal!

Após uma curta temporada em Natal estou de volta ao Rio. Com algumas horas a mais do que deveria de vôo, retorno bastante satisfeito, pois o principal motivo da minha viagem a Noiva do Sol foi a participação no III Natal Java Day onde tive o prazer de apresentar uma palestra sobre EJB e JPA. O outro motivo foi descansar um pouco, pois ninguém é de ferro...

Fiquei muito feliz ao ver cerca de 400 pessoas preenchendo as cadeiras do CEFET às 08:30 a manhã no meio de um feriado. Impressionante! Impressionante também foi a organização do pessoal do Jug JavaRN (aos mais desavisados: Java User Group): até transmissão pela internet o evento teve. Coisa de profissinal.

Como nem todos tiveram o prazer de acompanhar o evento, darei um breve resumo da minha palestra aqui.

Comecei falando do histórico da tecnologia java o ponto de vista de iniciativas da comunidade que acabaram influenciando diretamente a sua evolução. Foram citados XDoclet (annotations), Hibernate (JPA), Struts (JSF), Spring (Injeção de depedência, uso intensivo de POJO).

Na seqüência, falei um pouco sobre JPA - talvez o principal avanço da JEE5. Foi apresentado o conjunto dos elementos principais dessa especificação: EntityManagerFactory, EntityManager, Interface Query, ....... Apresentei um pequeno código de um simples CRUD (acrônimo para Create, Retrieve, Update e Delete ou o bom e velho lê-esquece-grava-apaga). Complementei com os prós e contras das estratégias de mapamento objeto-relacional: Um atabela por toda a família de classes, uma tabela por classe concreta e uma tabela por classe com joins.

Como as consultas são umas das facilidades da nova especificação, com a turbinada que a EJB-QL (finalmente) recebeu, citei as consultas simples, nomeadas - aquelas que são "fixas" e com um sentido em definido no sistema, como "pessoasRicas" - usando objetos para facilitar a escrita das Querys. Não foi esquecido o uso das consultas netivas usando o bom e velho SQL, além da citação dos avanços nas funçoes de agregação, subconsultas e afins.

No uso de injeção de dependência foi mostrado a grande facilidade que é o seu uso, assim como o contra-ponto de que as dependências a serem injetadas tem que estar no JNDI. Explico os palavrões:
.Injeção de Dependência - Quando dependências para que sua classe funcione são disponibilizadas para você sem que haja preocupação com a forma de como essas dependências chegam. Um exemplo simples de uma dependência é um EntityManager. Quem providencia isso? O Container.
.JNDI - Java Naming Directory Interface - Uma API padronizada para acesso a serviços de diretórios nomeados como LDAP ou AD. Um conainer tem que prover esse tipo de serviço onde, a partir de um nome, uma busca retorna o objeto.
Com isso até faz sentido o uso de objetos no JNDI para a injeção, já que ele é onipresente enquanto o container estiver no ar.

Os interceptors não foram esquecidos. Essas classes qie ficam na frente de EJBs com comportamento inspirado na AOP (Aspect Oriented Programming - Programação orintada a aspetos) possibilita que interesses interceptem as chamadas aos ejbs e processem permitindo uma centralização desse processamento em uma classe ao invés de estar espalhado por vários lugares colaborando para duplicação de código. No exemplo da apresentação foi considerado o interesse da saber quanto tempo o métodp gasta para processar. O que há de ruim nisso? A classe a ser interceptada precisa conhecer o seu interceptador, o que bate de frente com a proposta da AOP de que o interceptador é que conhece o interceptado. Bola Fora.

Como uma das bases da facilidades da especificação são as anotações, elas foram citadas o tempo todo e, sempre qie possível, ressaltando que os comportamentos padrões tendem a minimizar a escrutade código. Como toda a parametrização feita com anotações pode ser feita também com XML, essas duas opções foram comparadas.

Ainda faltam falar de alguns tópicos...

Procurei fazer uma palestra refletindo pontos fortes e fracos para apoiar a tomada de decisão dos desenvolvedores, não sendo mais uma palestra de EJB3. Espero ter conseguido atingir o objetivo colaborando para o bom uso da tecnologia. A apresentação? Está disponível aqui.

Como não bastasse, após a minha apresentação bati um excelente papo com o Daniel Oliveira do DFJug sobre "Comunidades". Mas isso é um outro post...

Alguns links interessantes:


Abraços.

quinta-feira, 15 de novembro de 2007

III Natal Java Day

Pessoal,

Nos dias 16 e 17 de novembro ocorrerá a terceira edição do Natal Java Day, evento anual promovido pelo Grupo de Usuários JavaRN que reúne estudantes e profissionais de TI que utilizam Java para o desenvolvimento das mais diversas aplicações.

E no 2.º dia teremos inúmeras palestras interessantes, e eu também estarei lá, apresentando os novos horizontes para aplicações usando EJB3/JPA. :-)

Quem quiser comparecer é só acessar o site http://www.jeebrasil.com.br/nataljavaday/index.jsp e realizar a inscrição.

 

Após o evento postaremos mais notícias, fotos e curiosidades! :-O

Conto com a sua presença.

Abraços

quarta-feira, 24 de outubro de 2007

A Fábula dos Elefantes

Era uma vez um grupo de elefantes que viviam em uma pequena clareira. Ao seu redor existiam pequenos eco-sistemas que coexistiam com os paquidermes - alguns arbustos com pássaros, formigueiros, colméias... Vez por outra um novo elefante chegava no grupo ou um antigo saía, mas sempre que algum deles se movimentava, alguns eco-sistemas corriam o risco de serem esmagados, de modo que essas pequenas comunidades precisavam estar sempre atentas ao donos da clareira.

Estive no Microsoft Track (10/10) aqui no Rio. O Evento foi muito interessante, principalmente por assistir a mudança de discurso da Microsoft em relação ao mundo open-source e a comunidades ao redor de suas tecnolgias, mesmo que seja um discurso atrasado pelo menos 3 anos.

O fato é que um dos elefantes está se mexendo e isso merece atenção.

Agrdecimento especial a Otávio Coelho por me apresentar a fábula aqui descrita.

Abraços.

terça-feira, 18 de setembro de 2007

Preparando o Terreno para o Selenium

A importância da realização dos testes em um sistema não é motivo de discussão, mas sem o apoio de ferramenta para automatizar esses testes, essa atividade pode tornar-se um verdadeiro calvário. Ainda mais se houver a necessidade que essa execução ocorra várias vezes ao longo do cilo de vida da aplicação.

Se pensarmos de forma simplista temos duas abordagens para testes:
1 - Dada uma entrada, existe uma saída esperada
2 - Dada uma entrada, observar como será o comportamento do sistema

Nos prendamos a primeira abordagem.

O princípio básico dos testes unitários com o junit se dá através de afirmações (assertions), ou seja, você programa várias afirmações para suas classes através de seus métodos: "dado duas entradas 1 e 1, é esperado que a soma seja 2" e assim por diante.

O Selenium usa esse mesmo princípio realizando testes em função dos resultados respondidos pelo sistema, com o seguinte tempero: Os testes dizem respeito ao sistema como um todo - tipicamente são testes funcionais. Um simples navegar de telas pode reprentar a realização de um cálculo complexo. E é justamente neste ponto que precisamos ter atenção.

Vamos a um exemplo simples: Uma calculadora de Horas extras para profissionais CLT. Dado um volume de horas trabalhadas e seu salário, a calculadora responde quanto você deve receber. Para este simples exemplo temos alguns cenários possíveis:

a) As horas trabalhadas foram durante a semana;
b) As horas trabalhadas foram num feriado;
c) As horas trabalhadas foram de um dia até o outro.

Esse tipo de cálculo prevê uma série de adicionais que devem incidir sobre o cálculo de suas horas, de modo que para este exemplo simples os dados existentes para o sistema acabam ganhando uma importância grande.

Num sistema de maior complexidade o conhecimento prévio desses dados ganha um nível a mais. Dessa forma é muito importante que tenhamos conhecimento prévio dessa massa de dados para os casos de testes que serão executados principalmente porque, dado o automatismo, a possibilidade de repetição é fundamental para um boa produtividade na criação de códigos com qualidade.

Seguindo o princípio K.I.S.S. (Keep It Stupidly Simple), podemos criar facilmente uma classe que carregue o banco de dados a partir de um arquivo .SQL onde cada linha tem um comando SQL:



public class CarregaMassaDados {
   public static void cargaDados(String arquivoSql) {
      String stm = "";
      BufferedReader in = null;
      Connection connection = null;
      Statement stmt = null;
      if ((arquivoSql == null) ("".equals(arquivoSql))) {
         throw new RuntimeException("O Parâmetro arquivoSql deve ser informado");
      }
      try {
         Class.forName("org.postgresql.jdbc3.Jdbc3ConnectionPool");
         connection =
            DriverManager.getConnection(
            "jdbc:postgresql://127.0.0.1:5432/BDAplicacao",
            "LOGIN",
            "SENHA");
         in = new BufferedReader(new FileReader(arquivoSql));
         stmt = connection.createStatement();
         String sql;
         while ((sql = in.readLine()) != null) {
            stmt.executeUpdate(sql);
         }
      } catch (ClassNotFoundException e) {
         throw new RuntimeException("Database driver não encontrado.");
      } catch (SQLException e) {
         throw new RuntimeException("Database não conectado.");
      } catch (IOException e) {
         throw new RuntimeException("Impossivel ler o arquivo.");
      } finally {
         try {
            if (in != null) in.close();
            if (stmt != null) stmt.close();
            if (connection != null) connection.close();
         } catch (IOException e) {
            throw new RuntimeException("Impossivel ler o arquivo.");
         } catch (SQLException e) {
            throw new RuntimeException("Database não conectado.");
         }
      }
   }
}

A chamada a carga de dados pode ser colocada no início dos seus testes, permitindo que a sua massa de dados seja conhecida garantido assim a repetividade de seus testes.

Abraços.

segunda-feira, 10 de setembro de 2007

SOA, Java e Paixão

No ano passado estivemos no Sun Tech Days 2006 em São Paulo. Lá tivemos a oportunidade de conhecer em algumas das palestras uma figura muito peculiar que, inclusive pode ser vista em uma bela performance em http://www.youtube.com/watch?v=BXHE4SktsbM .

O dançarino em questão é Sang Shin, evangelista da Sun que apresentou uma bela palestra sobre SOA com objetividade e didática suficientes para romper qualquer barreira que o idioma pudesse causar. Nessa palestra (estou procurando o link, mas fiquem com este por enquanto) ficou muito claro o propósito de SOA e que ele não é Webservice :-) Ainda falaremos um pouco sobre SOA, mas no momento gostaria de ressaltar a paixão desse profissional.

Preocupado em compartilhar conhecimento, ele mantém um site - o www.javapassion.com - através do qual é possível se inscrever em alguns dos vários cursos que ele ministra. O custo? De graça e eles são em inglês.

Abraços.

sábado, 8 de setembro de 2007

Testes Funcionais na Web - Selenium

Quem está procurando uma ferramenta para testes funcionais (de tela) que:

  • não seja preciso "decorar" mais uma linguagem ou 1001 novos comandos;
  • siga um padrão, xunit por exemplo;
  • seja possível integrar os scripts a um repositório de gerência de configuração para integração contínua;
  • possa ser criado por equipe de testes, não necessariamente por programadores;
  • não seja preciso escrever uma linha de código;
  • não tenha custo de aquisição "grátis";
  • execução totalmente automática.

Esté querendo muito?! Não, existe uma ótima ferramenta chamada Selenium (http://www.openqa.org/selenium/), que é grátis e open-source.

A idéia deste post é mostrar alguns benefícios e na prática esta suite. Digo suite, pois há diversos projetos em paralelo (não é fácil de entender) que podem ser utilizados em conjunto para um melhor resultado.

A seguir vamos criar um passo a passo de utilização, que está misturado com um processo que pode ser adaptado de acordo com as suas necessidades. Lembre-se que a ferramenta pode ser utilizada em qualquer processo desde CMMi até processos Ágeis.

Vamos a nossa receita de bolo...

Passo 1 - Criando um plano de testes (trabalho árduo)

Neste passo é onde os analistas do negócio ou sistemas descrevem as entradas de testes necessárias e os resultados esperados para que o atendimento a um requisito seja corretamente satisfeito.

Passo 2 - Automatizando o plano de testes

A partir do plano de testes criado é necessária a automatização de cada entrada de teste. No Selenium esta automatização é realizada através de uma IDE extremamente simples e robusta.

A ferramenta integra um plugin ao Mozila Firefox. Isto não quer dizer que os testes são executados apenas sob o Firefox, a IDE é apenas um adicional que afeta a produtividade na implementação dos testes.

Você pode baixar o Mozilla Firefox em http://www.mozilla.com/en-US/firefox/, recomendo o uso da versão 2.0 pois foi a versão que utilizei para avaliação da ferramenta. E para baixar o XPI (plugin para o firefox) do Selenium acesse a url http://www.openqa.org/selenium-ide/.

O objetivo do Selenium IDE é provê interface amigável para gravação dos testes através de toda ação do usuário à aplicação web. Estas ações são gravadas como um roteiro, baseado em HTML, que pode ser exportado em inúmeras linguagens (próximo passo).

Abaixo a tela principal do Selenium IDE para gravação dos testes, simples e poderosa. Digo poderosa porque é possível alterar ordem das ações, consultar todas as funções disponíveis (asserts, verify, alerts) e ainda incluir ações não gravadas.

Passo 3 - Exportando testes automatizados

Os testes automatizados através do auxílio da IDE no Mozilla Firefox são gravados no formato tabular - HTML (usado no método de testes FIT, talvez um próximo post).

Este formato não é ideal, visto que é necessário o auxílio da IDE ou utilização de um outro projeto chamado Selenium TestRunner.

Desta forma, o ideal é que tenhamos o teste escrito em linguagens flexíveis e extensíveis como: Java, C#, PHP ... O Selenium IDE oferece exportação dos testes nestas várias linguagens e estruturado de acordo com o respectivo xUnit (jUnit, nUnit...). E acreditem, oferece suporte a extensibilidade, ou seja, podemos colaborar com novas linguagens. :-)

Uma observação importante é que o script em HTML também deve ser salvo para futuras manutenções nos testes sem a necessidade de re-gravação, o Selenium IDE só lê neste formato e exporta "n" outros.

Passo 4 - Adaptando os testes

Não vamos nos enganar, o script gravado pelo Selenium IDE não é perfeito. Desta forma, é necessário que refinemos geralmente nos seguintes pontos:

  • As vezes é necessário incluir entre ações "tempo de espera", pois depende da velocidade que o navegador executou a ação naquele momento. O ideal é que sempre entre requests tenhamos um wait para garantir.
  • Sempre que exportamos na linguagem que desejamos o Selenium IDE usa hard-coded para informação de servidor, abrir página inicial, usuário e senha de acesso e etc. Recomendo que seja criada uma classe base para tratar situações que valem para todos os testes da aplicação.

Assim, recomendo que do conteúdo exportado pelo Selenium IDE sejam copiados os test cases (métodos de testes) ajustados e depois é só colar na sua IDE preferida.

Crie uma classe de teste que pode ser em qualquer linguagem. Em qualquer?! Sim, até mesmo se for diferente da sua aplicação. Lembre-se o Selenium testa somente aplicações web.

Cole o teste e adapte-o de acordo com as nossas dicas.

É claro que o Selenium estende os frameworks xUnit das linguagens específicas, ou seja, ele estende o jUnit, nUnit e etc. Então, é necessário que façamos a inclusão das dependências. Este já é um outro projeto no site do Selenium, chamado de Remote Control. Baixe-o a partir da url: http://www.openqa.org/selenium-rc/download.action. Neste projeto temos as extensões para cada linguagem (.NET, Java...) e o server (já já explico).

Passo 5 - Executando a classe de testes

Bom, aqui nós chegamos a etapa final: execução dos testes. Diferente de inúmeras ferramentas de testes de aplicações web onde são enviados requests e recebidos responses do servidor (parse para lá, parse para cá) o Selenium trabalha usando o próprio browser. Isso mesmo, terceiriza o serviço mais difícil: eventos em páginas web, navegação, renderização e tudo mais. Esta é uma grande vantagem em relação a outras ferramentas como o jWebUnit.

Aí surgem algumas perguntas:

Eu só posso testar em um browser? Não, você escolhe o browser em que deseja executar os testes, ou seja, podemos executar os mesmos testes no Internet Explorer e Firefox, testando assim a compatibilidade cross-browser.

Fico dependente do browser, ou seja, meu teste é mais lento e não posso executar testes em paralelo? Verdade, o teste fica lento, preciso de ambiente gráfico para execução e só é possível executar um teste por vez (por enquanto!).

Então, a cada entrada de teste o browser é aberto e ações externas são realizadas sobre ele. O responsável por realizar estas ações é o Selenium Server, aplicação console, que inicia um serviço que recebe as requisições e as envia ao browser. Também é responsável por capturar eventos e traduzí-los em teste de sucesso ou falha. O Selenium Server vem junto com o pacote do Remote Control. Este server é implementado em Java e precisa da máquina virtual para rodar. Exemplo de linha de comando para executá-lo:

java -jar selenium-server.jar -interactive

Após iniciar o servidor, basta executar os testes da sua IDE de preferência.

Problemas conhecidos

  • Utilize a opção multiwindow para iniciar o servidor do Selenium. Esta opção resolve problema quando a aplicação possui frames. A utilização de frames causa instabilidade no Selenium que utiliza um frame para execução dos seus comandos.
  • A ferramenta apresentou problemas para executar em um ambiente com proxy no meio. Se você tiver executando teste em aplicação web, na internet, e tenha um proxy no caminho poderá ter problemas. No site do Selenium informa que é compatível, testei mas não funcionou. Quem souber, pode comentar!

Conclusão

Este foi um breve post sobre esta ferramenta maravilhosa para testes funcionais na Web. Após várias pesquisas esta ferramenta foi a que mais se aproximou de critérios como teste de qualidade, facilidade, produtividade e estabilidade.

Bom galera, é isso aí. O post ficou um pouco longo mas objetivo. Prentendo incluir mais algumas informações práticas. Talvez um próximo post faço um exemplo de ponta a ponta de alguns testes em uma aplicação web por aí. Sugestões são aceitas.

Abraços e até a próxima!

quarta-feira, 5 de setembro de 2007

O início

Neste blog conversaremos sobre problemas rotineiros ligados a desenvolvimento de software, passando por dicas de linguagens, programação, frameworks, orientação a objetos... Essas conversas serão protagonizadas por Fernando Bichara, Wesley Gonçalves e, claro, quem mais quiser...

Sejam benvindos!