Alguns meses depois

Dizem por aí que  uma boa premissa para se criar um produto novo é partir de uma necessidade pessoal. Eu já devo ter mencionado isso em algum lugar neste blog. No caso do Job4Dev, foi assim. Na verdade, mais do que uma  necessidade, o Job4Dev teve como ponto de partida uma frustração: os sites de empregos brasileiros de empregos voltado para o mundo TI eram um amontoado de mais do mesmo.

O exercício é simples: entre nos 3 principais sites de empregos, e conte a porcentagem de vagas oferecidas por consultorias de TI, na maioria sem nome, sem projetos definido, sem plano de carreira, sem grandes desafios, cujo único objetivo é fazer outsourcing de recursos de programação. São a grande maioria.

Nada contra este tipo de trabalho. Existe a demanda, e existe gente que se interessa em desenvolver. Ótimo. O problema é que quando olhava estes sites, tinha a nítida impressão de que o mercado brasileiro se resumia a isso. E olhando à minha volta, percebia que meus colegas e outros profissionais bons em geral não passavam nem perto destes  sites, preferindo usar listas de emails, contatos pessoais e o bom e velho networking.

Job4Dev foi desenvolvido tendo como objetivo de oferecer alternativas, captando vagas de várias fontes, filtrando o material e disponibilizando apenas aquilo que julgamos interessante.

E devo confessar que, depois de alguns meses no ar, o retorno e o resultado me surpreendeu. O site ainda tem muito a crescer, mas temos conseguido um fluxo regular de vagas, feedbacks muito bons de usuários e empresas. Isso me confirma uma coisa: o mercado brasileiro talves esteja longe do ideal, mas existem sim boas opções de empresas que procuram profissionais diferenciados, que desenvolvem projetos interessantes. E estas empresas estão carentes de espaços adequados de divulgação.

Easter Egg no Google Reader

Entre no Reader, digite a seguinte sequencia no teclado:

cima, cima, baixo, baixo, esquerda, direita, esquerda, direita, b, a

A palavra Ninja! irá aparece na busca, a barra a esquerda irá ter um skin diferente e todos os contadores ficarão com valor 30 (mensagens não lidas). A referência nerd da coisa (obrigado Thomas) é que existe um jogo chamado Contra, do Nintendinho, onde esta sequência dá ao jogador 30 vidas. Esse código também é chamado de Konami Code, e é bem documentado pela Wikipedia em http://en.wikipedia.org/wiki/Konami_Code.

Mais um daqueles códigos que o pessoal dava a vida para conseguir, e que eu sempre fui incapaz de aprender de cor!

Filtro por Estado no Job4Dev

Mais uma funcionalidade muito requisitada por fãs do Job4Dev da minha rua: filtro por estado. Pedido atendido: agora é possível filtrar as vagas por estado e/ou por palavra chave.

O sistema foi feito de forma a minimizar o impacto no cadastro. Assim, o formulário continua o mesmo, apenas com um campo de localização: escreva a sigla do estado em algum lugar, e o Job4Dev se encarregará de fazer o resto.

Esta funcionalidade ainda não está no RSS ainda, mas seguindo a filosofia “Release Fast, Release Often”, deverá estar disponível em breve.

Conversando com o Twitter

Eu já divulguei aqui que o Job4Dev tem integração com o sistema de microblog Twitter, através do usuário job4dev, onde são enviadas as ofertas de emprego.

O que eu não divulguei ainda é que desde terça está no ar mais um projeto que contou com a minha participação: sigaseutime.com.br. A idéia é bem simples: utilizar o Twitter para agregar notícias e informações de jogos ao vivo do seu time de futebol favorito. Criamos contas para diversos times do Brasil e do mundo (sigaCorinthians, sigaPalmeiras, liveBarcelona, e por aí vai. Acesse o site para o obter a lista completa).

O que eu não contei também é que fazer integração via software com o Twitter é extremamente simples, graças à API REST de acesso. REST? REpresentational State Transfer, termo criado por Roy Fielding, computeiro americano e um dos principais autores da especificação do protocolo HTTP, em sua tese de PhD.

O próprio REST tem como pilar o protocolo HTTP. A idéia básica é definir que existem recursos (fontes de informação) que podem ser acessados através de um identificador global (que no caso do HTTP, é conhecido como URL), e que retornam uma representação da informação (XML, JSON, etc). Os recursos são considerados objetos, e o REST utiliza as ações do protocolo HTTP para agir sobre estes objetos: GET, POST (as mais famosas, para quem trabalha com sistemas web e com ajax), PUT e DELETE.

  • GET URI corresponde à operação de leitura de um objeto
  • POST URI correponde à operação de criação, atualização ou remoção de um objeto, utilizando dados enviados pelo comando.
  • DELETE URI corresponde à operação de remoção de um objeto.
  • PUT URI corresponde, assim como POST, à operação de atualização ou criação de um objeto.

Assim como no HTTP, o REST não armazena sessão: o acesso tem que ser feito sem que o recurso precise ter conhecimento de requisições passadas, proxys, caches e outros recursos utilizados em sistemas web. Ou seja: qualquer serviço REST pode ser acessado apenas com a URI apropriada e a ação desejada.

A API REST do Twitter permite acesso a todas as funcionalidades do sistema, de forma extremamente simples. Por exemplo: caso eu queira listar as mensagens recebidas pelo usuário job4dev em formato xml, basta acessar a URL http://twitter.com/statuses/friends_timeline/job4dev.xml. O sistema retorna informações também em JSON (neste caso, bastaria mudar o xml do final por json).

A maioria dos comandos requer autenticação, que no caso do Twitter é feita usando o Basic Auth: a informação de usuário e senha é enviada em um header chamado Authorization, cujo conteúdo é uma string na forma Basic <dados em base 64>, onde <dados em base 64> é usuario:senha codificado em base64 (formato muito utilizado para transmissão de dados na web).

Vou colocar aqui um exemplo em Python para enviar uma mensagem nova para uma conta no Twitter. A função encodestring é responsável por converter para base64, e a função urlencode gera uma string no formato correto para colocar na requisição HTTP:

auth = encodestring('%s:%s' % (user, password))[:-1]
header["Authorization"] = 'Basic %s' % self.auth
encoded_post_data = urlencode({"status":status})
req = Request(TwitterSender.url, encoded_post_data, header)
url_data = urlopen(req)

O mais interessante desta API é que além de ser simples, ela é muito bem documentada: http://groups.google.com/group/twitter-development-talk/web/api-documentation

job4dev.com.br no ar!

Acabei de configurar o domínio job4dev.com.br, que irá funcionar em paralelo ao domínio job4dev.com. Com isso espero melhorar os resultados nas pesquisas Google (afinal, agora temos um domínio genuinamente brasuca). Ajudem a divulgar a nova marca!

Job4Dev + Twitter

Na sexta feira entrou no ar uma nova funcionalidade do Job4Dev: integração com o Twitter. Para quem não conhece o Twitter, acho que a melhor explicação que eu posso dar é o texto da página inicial do próprio site:

Twitter is a service for friends, family, and co–workers to communicate and stay connected through the exchange of quick, frequent answers to one simple question: What are you doing?

Resumindo tudo: é um microblog. E qual o interesse do Job4Dev por um microblog? Simples: mais formas de divulgação. O Twitter permite o envio de mensagens através de Google Talk, Jabber, Live Journal, RSS e SMS, além do próprio site.

Temos agora um usuário job4dev no twitter, que pode ser acessado através da URL http://twitter.com/job4dev: para onde todos os anúncios de vagas aprovados serão enviados a cada meia-hora, e divulgadas em tempo real para todos os usuários do Twitter que cadastrados na nossa rede de contatos. Simples e eficiente!

PS: Gostaria de aproveitar para dizer que o RSS do Job4Dev no Google Reader anda meio problemático ele não é atualizado desde o início de abril. Estamos tentando corrigir isso o quanto antes.

.com.br liberado para CPF

Até pouco tempo atrás, para se registrar um domínio .com.br, era necessário possuir um CNPJ. Ou seja, apenas donos de empresa podiam registrar domínios .com.br. O resultado é que das duas uma: ou pessoas físicas compravam domínios .com, ou utilizavam serviços de empresas que compravam o domínio em seu nome.

Mas isto mudou. Acabei de receber o seguinte email do registro.br, orgão responsável pelo controle dos domínios brasileiros:

Por decisão do CGI.br, o domínio COM.BR, destinado a atividades comerciais genéricas na Internet, também poderá ser registrado sob um CPF. Ou seja, pessoas naturais com atividades comerciais e afins poderão registrar domínios COM.BR.

Esta modificação terá efeito a partir do dia 01/05/2008.

Inicialmente, somente o domínio COM.BR estará disponível nesta nova categoria, genérica, que permite registro tanto com CNPJ quanto com CPF. Lembramos que, para manter a transparência do registro de domínios .br, pessoas físicas responsáveis por domínios COM.BR estarão sujeitas aos mesmos procedimentos das entidades cadastradas previamente.

ClockingIT

Existe uma ferramenta muito legal para controle de projetos, bugs, releases e afins disponível na web: ClockingIT.

Este projeto tem uma história bem peculiar: foi desenvolvido por um casal norueguês, Erlend e Ellen Simonsen. Erlend é desenvolvedor e é responsável por toda a parte de programação. Ellen é designer e cuida de toda a parte visual.

O ClockingIT segue a mesma receita de muitos projetos de alta qualidade e valor agregado disponíveis por aí: nasceu de uma necessidade do próprio desenvolvedor. Erlend é um consultor de tecnologia independente e desenvolve projetos sob medida para vários clientes, e sentia a necessidade de ter uma boa ferramenta de gerenciamento de projetos. Seguindo a filosofia do Getting Real, resolveu por a mão na massa e começou a desenvolver o ClockingIT usando a plataforma Ruby On Rails.

O sistema permite o cadastro de diversos projetos e colaboradores. Em cada projeto, é possível criar milestones e tarefas (com diversos graus de prioridade, nível de dificuldade, tempo estimado de execução e data de entrega) e designar um colaborador para sua execução. Além disso, o sistema permite a criação de subtarefas e permite registrar o tempo levado para executar cada tarefa, gerando um log de trabalho. Com estes dados, é possível criar relatórios diversos, como timesheets que são extremamente úteis para consultores que ganham por hora. E o sistema ainda oferece vários modos de visualização de todos estes dados: timeline, schedule, lista de tarefas…

Mas o grande diferencial, aquilo que me faz ter vontade de escrever sobre o ClockingIT neste blog, é a qualidade da interface. O design gráfico é simples, limpo e extremamente intuitivo. E o site faz um uso intensivo e inteligente de scripts e recursos assíncronos. Eu destaquei a palavra inteligente porque hoje em dia vemos muitos sites usando Ajax simplesmente por usar, apenas para baterem no peito e gritar “Eu sou uebi doispontuzeru!!!”. Olhando a interface do Clocking IT, talvez muitos resolvem repensas suas visões. A interação como o site é extremamente ágil e leve, exatamente como em software desktop. Qualquer ação efetuada por algum usuário é imediatamente refletida na tela de outros usuários conectados no mesmo projeto. É possível saber em tempo real quem está conectado no sistema, o que está fazendo, a quanto tempo está fazendo. E graças ao chat embutido, é possível até conversar com outros colaboradores.

Last, but not least, o sistema oferece integração com iCal (pode ser integrado com Google Calendar ou com o calendário da Apple por exemplo), sistema de RSS, um wiki, fórum , e uma speedbar (uma janelinha pequena) que permite que o usuário marque o início e fim de uma tarefa (com botões de start, stop e pause e um cronômetro rodando em tempo real).

É, definitivamente o ClockingIT não deixa nada a desejar de ferramentas tradicionais de gerenciamento de projetos. E com certeza ele é uebidoispontuzero.

Links do dia: Computação em foto

  • The history of computer data storage, in pictures
    Pequeno resumo em imagens da evolução dos mecanismos de armazenamento de dados em computadores.

  • Programming Languages and their Celebrity Equivalents

    Comparação divertida entre linguagens de programação e pessoas famosas. Minha comparação favorita foi a do PHP.

  • If a programming language was a boat…

    A idéia é a mesmao do link anterior, mas desta vez a comparação é com barcos. É fácil notar que os autores de cada um dos posts tem visões muito diferentes sobre o mundo da programação. Aquele que compara linguagens com pessoas famosas parece gostar muito de Java, da MS e não ser fã de linguagens dinâmicas e script. Já a comparação com barcos claramente puxa a sardinha pro lado de Ruby.

Nova versão do Job4Dev no ar

Disponibilizei ontem a mais nova versão do Job4Dev, que eu considero como sendo o segundo major release desde que o projeto entrou no ar, no dia 3 de dezembro de 2007.

Para aqueles que utilizam o  sistema apenas para buscar vagas, as diferenças são poucas: busca no site usando o motor do Google e algumas pequenas modificações no design (na maioria dos casos, correções para o IE).

A maior mudança será sentida por aqueles que cadastram vagas no sistema. Uma das grandes reclamações, recorrentes, era de que uma vez cadastrada a vaga, era impossível editar e fazer pequenas correções. O fluxo de trabalho era simplificado ao extremo, e o feedback para o usuário era mínimo. Além disso, eu não tinha controle algum de quem cadastrava vagas.

Com estes pontos em mente, resolvi adicionar um sistema de controle de usuários: todos aqueles que desejarem submeter vagas no site deverão se cadastrar no sistema. Com isto eu consigo oferecer os seguintes serviços:

  • Cada usuário poderá ver suas vagas publicadas, rejeitadas, removidas ou aguardando aprovação.
  • O usuário poderá editar e modificar uma vaga criada por ele. Caso a vaga já tenha sido publicada, ela será colocada em estado de espera e submetida para nova aprovação.
  • Vagas removidas (com data de publicação superior a 30 dias) poderão ser republicadas pelo autor a qualquer momento.
  • O usuário receberá emails notificando modificações no status de suas vagas.

Além disso, o formulário de submissão de vaga foi redesenhado e ganhou uma nova interface para adicionar palavras-chave, inspirada no site del.icio.us.

Screenshots de IE

Quem desenvolve sites e aplicações web sabe: a coisa mais pentelha que existe é conseguir fazer com que as telas tenham exatamente a mesma aparência em qualquer browser (não, eu não faço parte daqueles que acham que um site deva ser desenvolvido para funcionar bem apenas no navegador que domina o mercado e o resto que se dane, a menos que seja para uma intranet homogênea..call center por exemplo). E para resolver isso, não tem muito segredo: é preciso testar, testar e testar.

Hoje em dia existem vários sites que geram screenshots de um site gerados a partir de vários navegadores e são uma mão na roda. No meu caso, que uso Mac para desenvolvimento de projetos pessoais (como o Job4Dev), eu sinto falta de ver o resultado gerado pelo IE. Por isso, o site http://ipinfo.info/netrenderer/index.php é uma ótima pedida: gera screenshots gerados por várias versões do IE e ainda por cima é extremamente rápido.

Backup-ear é preciso

Depois de muito procurar, acho que encontrei um bom sistema online de backup de dados: Mozy. Um diferencial para mim foi o fato de eles oferecerem um cliente para Mac bastante estável e eficiente. O pacote Home não possui limitação de espaço de armazenamento, e o preço é bem acessível (5 dólares/mês, com pacotes anuais e bianuais). Para testes, eles oferecem uma conta gratuita com 2GB de espaço

O sistema é simples: baixe o programa deles, defina pastas ou conjunto de arquivos a serem enviados (por exemplo, todos os arquivos .doc da sua máquina). O mozy irá enviar todos os arquivos para lá e ficará atualizando automaticamente os arquivos.

A primeira carga pode ser demorada, dependendo da sua rede e da quantidade de dados a serem enviados (no meu caso, demorou duas semanas), mas depois o sistema apenas manda os arquivos e pastas modificados (no mesmo estilo de ferramentas como o rsync).

Dica: Ajax, JSON e IE 6

Esta dica é bem pontual, e talvez resolva a vida de no máximo duas pessoas. Mas o problema aqui abordado me custou minutos preciosos, e portanto vou aproveitar o fato de ter um blog para compartilha-lo com vocês. Sem contar que faz um bom tempo que eu não escrevo nada mais técnico.

Cenário básico: aplicação web com interface contendo vários trechos que necessitam de comunicação assíncrona com o servidor (a.k.a Ajax). Por motivos de projeto, a resposta vem em formato JSON (para resumir, eu tive que substituir DWR por Prototype, e para ser o menos intrusivo possível na aplicação, usei o mesmo formato de transmissão de dados do framework).

Dentre os vários dados recebidos do servidor, um deles é uma estrutura de dados representando um endereço:

{cidade: {id: 1, nome: "Sampa"}, estado: {id: 1, nome: "SP"}, pais: {id: 1, nome: "Brasil"},}

Muito bem. Para transformar este trecho em um objeto tratável pelo javascript como uma estrutura de dados, eu usei o comando var data = eval("("+response.responseText+")"), onde response é o objeto de resposta da requisição.

No Firefox, o sistema funcionou maravilhosamente bem. No IE 6, pra variar, necas. Não testei no IE 7.

O problema foi a última vírgula antes da última chave. O uso de chaves indica que estou descrevendo um dicionário (contendo pares chave: valor). Ao colocar uma vírgula no final, o IE entende que teremos mais um par à frente, e reclama ao encontrar uma chave. Tirei a virgula, e tudo funcionou perfeitamente.

________________________________________

Adendo feito algumas horas depois: justiça seja feita, o IE segue a especificação formal do JSON ao pé da letra. Vendo o diagrama da sintaxe do JSON no site json.org, vi que após uma virgula deve haver um par chave:valor. MEA CULPA.

Tag cloud no Job4Dev

Atendendo ao clamor popular, coloquei no ar ontem um sistema de tag cloud no Job4Dev.

A primeira versão está bem simples: lista de tags ordenada por nome, com o número de anúncios em que a tag aparece do lado. A próxima versão, que deve sair em breve, será del.icio.us like, diferenciando as mais populares das menos populares pelo tamanho da fonte.

De grão em grão…

Testando aplicações web com Selenium

Por Odracir Antunes Júnior

Creio que boa parte dos desenvolvedores sabe da importância dos testes automatizados como ferramenta indispensável no desenvolvimento de software. Mesmo assim, para deixar as coisas ainda mais claras, gostaria de compartilhar uma experiência que tive com meus amigos em um projeto recente.

Estavamos trabalhando em um projeto de produto genérico, que serviria para várias empresas. Conseguimos um primeiro cliente que, obviamente, solicitou várias adequações para que o produto pudesse se utilizado por ele. Algum tempo depois tínhamos mais dois clientes além daquele inicial. Um deles pretendia utilizar apenas um sub-conjunto do produto original, e outro precisava de mudanças que eram incompatíveis com os outros dois.

A gestão da configuração do projeto se tornava cada vez mais complexa. Precisávamos atuar em frentes diferentes, para atender às necessidades dos clientes. Tínhamos que implementar as novas funcionalidades, porém sem quebrar o que já existia. Pra variar, acabamos atrasando. E os novos prazos estavam ficando cada vez mais apertados. Algumas vezes nós chegamos à entregar versões preliminares para homologação, com bugs em funcionalidades que já tinham sido testadas e aprovadas em versões anteriores. Isto nos causava um grande desgaste perante o cliente, e era preciso garantir a qualidade do que estava sendo entregue.

Tínhamos uma equipe de testes que também estava sobrecarregada, pois quanto mais complexos se tornavam os produtos, maiores eram as dificuldades na simulação dos cenários diferentes para os testes. Foi definido um “Smoke Test“, com as funcionalidades essenciais do produto que eram comuns entre os clientes. No meio da correria, depois de um refactoring crítico na infraestrutura do projeto, eu tive que testar manualmente a aplicação. Fiquei 4 dias testando e mal passei de 40% da cobertura básica!

Passada aquela correria, começamos a automatizar o processo de “Smoke Test” tanto quanto possível. Já sabíamos que muitas outras correria ainda nos esperavem num futuro não muito distante!

Boa parte das aplicações desenvolvidas últimamente são aplicações WEB, e portanto também é fundamental poder fazer testes através do browser, como se fosse um usuário comum operando o sistema. Obviamente isto não exime o desenvolvedor de implementar os testes unitários. Os testes através da camada web devem ser um complemento aos testes mais básicos.

O Selenium é uma ferramenta de para testes de aplicações WEB, distribuído sob a “Apache License, Version 2.0“. Temos os seguintes produtos, e modos de uso do Selenium.

 

Selenium Core - (Modo direto)

Os testes são efetuados diretamente através do browser. As páginas de teste devem estar hospedadas no mesmo servidor que o programa/site a ser testado. Esta restrição/característica é função da segurança relativa à mesma origem requerida pelo javascript.

Vantagens:

  • Suporte para todos os browsers

Desvantagens:

  • É necessário a instalação remota no servidor.
  • Possui algumas limitações para testes mais complexos.
  • Pode ter um comportamento irregular quando se testam páginas com ajax, onde é necessário um controle maior do tempo, e/ou seqüencia de eventos. Este comportamento é altamente dependente do “engine” java script do browser. Dependendo do caso, às vezes pode apresentar falsos erros em função da priorização das atividades, já que tando “quem testa” quanto “quem é testado” estão sendo executados sob o mesmo “engine” java script, e comportamentos concorrentes podem não ser tão previsíveis assim …

Selenium IDE - (Modo indireto - Plugin no browser)

Os testes são efetuados através de um plugin instalado no FireFox. Este plugin é um ambiente integrado de desenvolvimento. Permite gravar a navegação do usuário, e depois repeti-la à titulo de teste. Também permite exportar os testes gravados em outros formatos. (Maiores explicações adiante…)

Vantagens:

  • A instalação é local e simples.
  • É muito fácil de usar.
  • Permite gravar sessões de teste para uso posterior.
  • Permite exportar as sessões de teste como arquivos fonte Java, C#, Perl, PHP, Python e Ruby, que podem ser usados pelo Selenium RC.
  • Excelente para quem inicia o uso do Selenium.
  • Não é preciso saber programar.

Desvantagens:

  • Funciona como plugin apenas no FireFox.
  • Possui algumas limitações para testes mais complexos.
  • Pode apresentar o mesmo comportamento irregular relatado no item Selenuim Core. (colocar link local para #L1)

Selenium RC - (Modo indireto - Programa de teste + Proxy)

Os testes são efetuados através de um programa, que comanda o browser através de um proxy. Este programa pode ser escrito em Java, C#, Perl, PHP, Python e Ruby.

Vantagens:

  • Permite o uso de verdadeiras linguagens de programação.
  • Permite um controle muito mais apurado do tempo, seqüencia de eventos, etc. …
  • É possível importar os testes gerados pelo Selenium IDE.
  • Muito mais flexível e poderoso. Pode evoluir até para grandes suítes de testes, integração contínua, geração de relatórios . Como o programa está nas suas mãos você pode fazer o que quiser!

Desvantagens:

  • A instalação e configuração do ambiente é um pouco mais trabalhosa.
  • É necessário saber programar.
  • Pode ser mais complicado escrever os testes à partir do “zero”.

Qual ferramenta/modo eu devo usar ?

Além das informações listadas aqui, gostaríamos de sugerir a seguinte abordagem híbrida:

  • Instale o Selenium IDE e crie os seus testes básicos.
  • Exporte esses testes como programas (java, por exemplo).
  • Crie um projeto com as suítes de teste para uso com o jUnit.
  • Faça um refactoring nas classes geradas pelo Selenium IDE, pois o código gerado tem muita redundância.
  • Melhor ainda seria arrumar o código para ficar simples como uma mini “DSL” (Links #9 e #10), mais adequada para a sua aplicação, com chamadas de mais alto nível.

Depois de que automatizamos uma parte dos testes, aquilo que eu levei 4 dias era feito em apenas 20 minutos! Uma cobertura mais abrangente e confiável! A tranquilidade e a segurança que temos depois que os testes passam após um “refactoring”, ou mesmo antes de uma entrega do sistema para o cliente, é algo que não tem preço!

Moral da história: O tempo utilizado na elaboração de testes automatizados não é um tempo “gasto”. Na verdade é um tempo “investido”!

[Odracir Antunes Júnior é Analista de Sistemas com mais de 20 anos de experiência de desenvolvimento de sistemas em C, C++ e Java]

« Previous PageNext Page »