VidaGeek.net

Linux, Open-source, Programação e Produtividade

Archive for the ‘Java’ Category

Aplicações para a Internet que se comunicam umas com as outras é algo mais do que comum. Ou sua aplicação consome algo que outra produz ou ela produz algo para outra consumir.

É bem fácil testar o que sua aplicação produz. Basta subir um servidor local, fazer uma requisição para o endereço correspondente e processar o resultado. Mas, por outro lado, como testar que sua aplicação consome o que outra produz adequadamente?

É claro que não vamos querer depender da aplicação remota de verdade. Queremos deixar os testes automatizados o mais isolados possível dos recursos externos. Então vamos, provavelmente, querer que o objeto responsável por fazer as requisições para fora não as faça de verdade e que devolva dados semelhantes aos da aplicação real.

Um jeito de fazer isso seria “embrulhar” a comunicação com a Internet numa classe nossa e, nos testes, mockar essa classe e passar essa classe mockada para as classes (ou os métodos) que precisam dela. É possível fazer isso em qualquer linguagem que suporte orientação a objetos.

Em Ruby ainda temos uma outra possibilidade. Como as classes são abertas, podemos re-escrever os métodos da classe Net::HTTP, por exemplo. Assim, não precisamos criar um embrulho; podemos utilizar sempre a classe do sistema.

Pois também não precisamos fazer isso na mão. A gem FakeWeb permite mockar requisições para determinadas URIs com um código bastante sucinto. Por exemplo, se você quiser que seu programa receba “olá mundo” quando fizer uma requisição do tipo GET para a URI http://foo.com/bar, basta escrever antes do código que executa a requisição:


FakeWeb.register_uri(:get, "http://foo.com/bar", :body => "olá mundo")

Em Java também é possível fazer algo parecido com um pouco de magia negra, desde que controlemos a criação do objeto responsável pela requisição. Mas, a meu ver, a primeira abordagem resulta num código mais desacoplado. Qual a sua opinião?

Posts Relacionados:

  • Atualizando o RubyGems no Mac
  • FISL 8.0: Wireless Meshing with OLPC
  • Eleições via Internet?
  • Firefox começa a dominar Europa
  • Aplicações portáveis em C/C++
  • Os criadores do Skype atacam novamente…
  • Algumas impressões de JavaME
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

    Encoding hell

    Encoding é sempre um inferno. Se você nunca precisou brigar com encoding, pergunte para seus amigos e a cara deles dirá tudo.

    Pensando nisso, sempre que inicio um projeto, defino qual deve ser o encoding para todos os arquivos que ficam dentro do projeto.

    Não foi diferente nesse projeto. Como já é comum, definimos que tudo dentro do projeto deveria estar em UTF-8. Isso funcionou durante muito tempo. Controlamos bem todos os pontos de entrada para garantir que estivesse em UTF-8. Até mesmo em pontos que não tínhamos confiança em qual encoding estavam os dados, usamos (com bastante sucesso) o ICU4J.

    Mas mesmo assim tivemos alguns problemas estranhos. Uma de nossas ferramentas funcionava muito bem no Linux, mas não tão bem no Windows e no Mac. Mas rodando ela de dentro do eclipse funcionava perfeitamente em todos os ambientes.

    Depois de muito procurar, descobrimos que a causa eram problemas com encoding. Checamos novamente todos os pontos de entrada envolvidos e nada. Depois de muito sofrimento encontramos um post que nos deu uma grande dica de qual era o problema (no momento em que escrevo este post, o site parece estar fora do ar. Clique aqui para ver o post na cache do Google).

    No post ele comenta sobre dois parâmetros da VM. O -Dfile.encoding e -Dsun.jnu.encoding. O que eles fazem? Controlam o encoding da leitura de arquivos. Triste, não? Não adianta você especificar seu encoding no momento da criação do seu java.io.Reader. Se a leitura for feita a partir do sistema de arquivos, será lido no encoding padrão do SO.

    Para resolver o meu problema, foi apenas subir a VM especificando o encoding:

    
    java -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
    

    Ah, e não adianta usar o System.setProperty. As propriedades são usadas no momento em que a VM sobe.

    Outra coisa, quem descobriu o post e a solução foi o Edmilson Miyasaki, da Adaptworks.

    Posts Relacionados:

  • Como descobrir o real encoding de um arquivo em java
  • UTF-8 no Latex
  • Proteção de Tela como Papel de Parede no Linux
  • Um caso de ódio e talvez um pouco de amor (Também conhecido como automatizadores de build)
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

  • 0 Comments
  • Filed under: Dicas, Java, Programacao
  • Um dos grandes problemas que enfrentamos no meu atual projeto na AdaptWorks foi descobrir qual o real encoding de páginas html arbitrárias.

    Existem diversas causas para esse problema:

    1. Muitas pessoas não fazem idéia de como trabalhar com encodings de arquivos
    2. Nem sempre o encoding na resposta do servidor é o encoding do arquivo
    3. A tag meta com o charset também pode não bater com o encoding do arquivo
    4. Não existe uma forma simples de detectar qual o encoding do arquivo

    Depois de muito procurar, encontramos um projeto que usa diversas heurísticas para detectar o encoding correto do arquivo.

    O ICU (International Components for Unicode) faz todo o trabalho pesado para a detecção do encoding, com mais confiabilidade do que os dados enviados pelo servidor ou especificados pelo criador da página.

    Entre os vários usuários do ICU, estão Google, IBM e Apple.

    Ele é meio chato de usar, mas vale a pena.

    Posts Relacionados:

  • Encoding hell
  • Proteção de Tela como Papel de Parede no Linux
  • Deixando seu Ubuntu mais rápido
  • Como migrar de SVN para GIT
  • Gerando memória swap on-the-fly
  • UTF-8 no Latex
  • YACP - Aprendendo a usar suas ferramentas
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

    Red, Green, Refactor?

    Já faz um bom tempo que eu mudei o meu ciclo de desenvolvimento com testes do Red, Green, Refactor (ciclo tradicional de TDD) para algo um pouco diferente.

    O que aconteceu foi que eu tinha muito problema para pensar nas unidades pequenas sem ter as unidades grandes. Ah? Basicamente eu não consigo pensar em como implementar sem estar resolvendo o problema.

    Confuso ainda, certo?

    Bom, digamos que eu queira implementar algo que transforme um html em uma árvore (basicamente, parsear html). Eu não consigo pensar em como eu faria para parsear a tag. Apenas consigo pensar em como funcionaria para o html. Algo como:

    
    HtmlParseado html = new HtmlParser().
                      parse("<html><title>Conteudo</title></html>");
    

    Somente no momento em que estou dentro do método parse que eu consigo pensar em como descobrir quais são as tags. Por que isso? Por causa da abstração.

    No código acima não faz o menor sentido pensar nas tags, apenas no html completo. Dentro do método parse começa a fazer sentido procurar pelas tags.

    Então o que tenho feito? Eu crio um ou mais testes que sobre a funcionalidade inteira (no caso, o que o parse deve fazer com o html).
    Algo como:

    
    @Test
    public void testaQueOParserFunciona(){
      HtmlParseado html = new HtmlParser().
                     parse("<html><title>Conteudo</title></html>");
      Assert.assertEquals("html", html.getFirstChild().getTagName());
      ...
    }
    

    O problema é que esse teste é muito grande para guiar o desenvolvimento. O que eu faço então? Parto para o problema menor que é o reconhecimento de tags.

    Como nesse ponto eu já consigo imaginar mais ou menos o que quero que aconteça, consigo criar os testes para fazer o reconhecimento de tags.
    Mas durante todo esse tempo, o meu teste do ponto mais alto da abstração continua sem passar. Isso quebra com o RGR, mas me ajuda muito com o desenvolvimento da interface de uso.

    Talvez eu tenha perdido um pouco na qualidade do código usando essa abordagem top-down, mas ganho bastante em termos de usabilidade desse código. Isso me força a pensar em primeiro lugar em como vai ser usada a funcionalidade final e não nos menores constituintes dela.

    Outra coisa que esses testes me ajudam muito é a saber quando eu terminei a funcionalidade mais complexa.

    O que acham disso? Já fizeram (ou fazem) algo semelhante?

    Posts Relacionados:

  • Guia Latex - Parte IV: Estética (imagens e coloração)
  • “Free Software Song” de Stallman faz ações da Microsoft caírem
  • Sincronizando o Address Book do seu mac com os Contatos do Gmail
  • Tabelas assimétricas no LaTeX
  • Autores
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

  • 3 Comments
  • Filed under: Dicas, Java, Programacao