#TDC2013: nosso #orgulho e a nossa participação!

Foi uma sexta e sábado de muito orgulho para o nosso time, participando da primeira edição em Porto Alegre (2013) da The Developers Conference.

Permitir a reunião de tantos profissionais a fim de trocar ideias sobre diferentes tecnologias, tendências, marketing, linguagens de programação, web, mobile, enterprise, embeeded, arquiteturas para escalar e muito mais! O importante era trocar experiências e boas práticas, para capacitar, inspirar e ajudar a fazer acontecer!

Tivemos pessoas da nossa equipe participando da coordenação do evento, de coordenações de trilha, como palestrantes e participantes. Ao todo, 16 pessoas da equipe uMov.me ajudaram o TDC 2013 Porto Alegre acontecer! Nosso agradecimento a todos que fizeram o evento acontecer! Foram mais de 700 pessoas que estiveram pelo evento presencialmente ou online.

umovme-tdc

Que venha o #TDC2014!

Automatizando tarefas repetitivas utilizando Jenkins

Pare para pensar. Em seu trabalho existem tarefas que se repetem com certa frequencia, e que você faz sempre a mesma coisa para resolvê-las? Você provavelmente gostaria de não fazer mais essas tarefas, assim teria tempo para fazer tarefas mais importantes que necessitam do seu raciocínio lógico, ou até mais tempo para o seu lazer, porque não?

A solução para este tipo de problema pode ser a automação dessas tarefas. Ao se criar scripts que automatizem o trabalho antes feito manualmente, vários benefícios são obtidos como abstração do funcionamento, já que qualquer desenvolvedor pode executar o script mesmo sem saber como ele funciona internamente, e qualidade, já que não são mais necessários passos manuais diminuindo a chance de erros.

E é neste ponto que entra o Jenkins. Jenkins é uma ferramenta de integração contínua que fornece uma interface amigável para criação de tarefas que podem ser executadas manualmente, através de um clique, ou ainda agendadas para rodar em determinados horários.

Vale ressaltar que o Jenkins somente executa os scripts criados, então o conhecimento em alguma linguagem de script ainda é necessário. O foco deste post fica somente sobre o Jenkins.

Instalação
Vá na página oficial do Jenkins e selecione o link para o Java Web Archive (.war). Você pode fazer o deploy do Jenkins em um servidor de aplicação normalmente, mas para fins didáticos, vou inicializar como uma aplicação standalone. Para fazer isso, basta navegar pelo prompt de comando até o diretório onde se encontra o arquivo que foi baixado, e executar o seguinte comando: java -jar jenkins.war. Abra seu navegador e digite o seguinte endereço: http://localhost:8080/. Se você fez tudo corretamente a página principal do Jenkins será exibida.

Builds
O exemplo que irei mostrar a seguir, é de um job (tarefa), que irá, a cada commit em um repositório do GitHub, realizar o build da aplicação, inclusive rodando seus testes unitários. Isso possibilita que os desenvolvedores mantenham seu código constantemente integrado com o resto do sistema, e fornece um rápido feedback quando erros ocorrem. Mais sobre Continuos Integration (Integração Contínua) você pode conferir aqui.

Como iremos utilizar o Github, é necessário instalar o plugin que fará a conexão com o repositório. Para instalar o plugin vá em Gerenciar Jenkins -> Gerenciar Plugins -> Disponíveis, selecione o GitHub Plugin, e clique em Download now and install after restart.

Agora que temos o plugin instalado, o próximo passo é criar o job no Jenkins. Clique em Novo(a) Job, defina um nome para o mesmo, e marque a opção Construir um projeto de software free-style.

jenkins1

Clique em Ok. Será exibida uma tela para configuração do job. Existem várias opções de configuração, mas vamos fazer um exemplo bem simples. Em Gerenciamento de Código Fonte marque a opção Git, e insira a url de seu repositório. Em Disparadores de Construção selecione a opção Construir periodicamente e insira os seguintes valores */5 * * * *. Isso determina que o Jenkins faça o build do projeto a cada 5 minutos. Clique em salvar, e o seu job estará pronto para ser executado.

Sem títuloAlém do exemplo

Este foi um exemplo bem básico, com o objetivo de demonstrar a instalação e funcionamento, e ainda despertar o interesse pela ferramenta. Muitas outras coisas podem ser automatizadas via Jenkins, como deploys de aplicações ou até compilações de livros, sua utilidade é muito vasta. Pesquise mais sobre o assunto, e começe a criar o hábito de automatizar suas tarefas que são repetitivas e acabam consumindo seu tempo todos os dias.

Mock it with Mockito

Mês passado eu trouxe um tutorial sobre testes unitários usando JUnit 4 que trouxe bastante conhecimento legal sobre questões como boas práticas para a construção de testes unitário, padrões de desenvolvimento úteis que podem contribuir com isso, e um passo a passo para começar a desenvolver software usando testes unitários.

Agora a ideia é dar continuidade aos princípios apresentados, através de uma aula sobre testes unitários utilizando JUnit 4 + Mockito. Mockito é um framework de desenvolvimento de testes unitários, que tem como objetivo dar ferramentas úteis para a construção de testes unitários mais simples, legíveis, úteis e efetivos.

Mockito

Caso se interesse o download do Mockito pode ser obtido através do site https://code.google.com/p/mockito/ e se quiser ver uma documentação mais detalhada, com exemplos de código e formas de implementação, acesse aqui.

Reuniões que funcionam. Existe isso?

Meetings are bad?

Eu não posso dizer que adoro reuniões. Só que elas são inevitáveis. Então já que eu tenho que fazer elas de vez em quando, procuro formas de criar um local de aprendizado, onde eu possa unir pessoas que querem juntas resolver problemas. Vontade, restrição de tempo e algumas metas a serem cumpridas durante o tempo da mesma. Simples certo? Para exemplificar o processo que uso, vou contar uma história. Certa vez eu cheguei onde estava o time que estava apoiando, e fiz a pergunta:

Vamos fazer a reunião?

A resposta foi uma pessoa pegando uma térmica de café, outro pegando o jornal e outro indicando que precisava de 5 minutos.

Chegamos na sala, mas o pessoal que estava fazendo uma reunião antes, não tinha terminado ainda. Ao questionar, quem estava na sala indicava que era uma reunião importante. Certo… e porque não se marcou então com mais tempo? Porque? Porque?

1a regra para reuniões que funcionam? Faça elas terem um horário de início e fim. Certos. E se alguém usar a sala por 5mins a mais que o esperado? E se alguém se atrasar 5 minutos? Mantenha a hora de fim da reunião. Ou tome a decisão de remarcar a reunião.

Depois de entrarmos na sala, ficamos esperando a pessoa dos 5mins. Enquanto isto, quem estava com a términa começou a servir café, e quem estava com jornal começou a contar as notícias esportivas do dia. Aqueles 5mins se tornaram 10mins.

2a regra para reuniões que funcionam? Tenha uma definição de início da reunião. Quem são as pessoas que podem tocar os assuntos que serão tratados? Quem são as pessoas que podem tomar decisões? Procure trazer duplas para os assuntos que são decisivos ou tenha pessoas de backup que podem ser acionadas por algum meio de contato, para garantir que a reunião possa acontecer.

Quando a pessoa que faltava chegou, assuntos diversos começaram a aparecer. Pequenas urgências que estavam ocorrendo na empresa. E quem puxava as pequenas urgências fazia questão de indicar que eram assuntos rápidos, que enfim, vamos aproveitar alguns minutos para resolver o tal assunto. Não estava na pauta. Porque não trataram isto fora dali? Mas peraí… que pauta?

3a regra para reuniões que funcionam? Tenha uma pauta/agenda. Tenha uma lista de tópicos. Saiba quanto tempo vai ser dedicado para cada tópico. Seja um facilitador das discussões que precisam acontecer, e avise do tempo que vai ser tratado cada tópico. Qual o objetivo que se busca discutindo o tópico X? E o Y? O tópico está ali para ser aberto, desenvolvido, ou é uma reunião para tomada de decisão do tópico Z? Não misture muitos tópicos. Se for o caso marque reuniões isoladas para cada assunto.

Depois de todas as pequenas urgências definidas, uma das pessoas se sente deslocada. E não sabe porque está ali, já que dos 4 assuntos, apenas o 4o será de utilidade dela.

4a regra para reuniões que funcionam? Monte a agenda pensando no uso do tempo de cada pessoa. Se uma das pessoas vem para trabalhar apenas 1 assunto, faça este ser o primeiro assunto. Assim ela participa de forma efetiva e depois pode voltar para outras metas dentro do seu dia. E se for o caso trabalhe melhor a agenda, quebrando a mesma em mais de uma reunião.

Chegando no assunto mais importante da reunião, metade dos participantes não sabia do que se tratava, porque a informação não foi repassada na semana anterior. Aí uma das pessoas se lembrou que tinha ficado de repassar um documento para os outros, mas esqueceu. Aí o que era para ser uma discussão de possibilidades e criação de ideias, com 10mins de duração, se transforma em uma sala de aula, onde durante 20mins extras você vai ficar explicando um determinado assunto. O ponto? Dê a chance das pessoas se prepararem.

5a regra para reuniões que funcionam? Indique as pessoas como elas podem se preparar. Terão situações onde você vai incluir na reunião o momento de capacitação antes do momento de discussão, aí tranquilo. Deixo isto claro dentro da a agenda. Também deixe claro além do que elas podem fazer para se preparar, o que elas precisam ler, o que elas precisam mandar opinião prévia, e o que elas precisam trazer para a reunião.

A regra de querer fechar no horário parece sempre fácil, porque chegando o final da reunião, as pessoas se levantam e indicam que precisam ir para outras reuniões. Todos querem sair dali o mais rápido possível, assim acontece a magia de horas de reuniões que não geram ação alguma. E todas ações ficam para você trabalhar por email ou em uma nova reunião. :-/

6a regra para reuniões que funcionam? Monte a lista de ações durante a mesma. Vá estabelecendo durante a própria reunião ações que precisam acontecer depois que ela terminar. E nestes casos você já vai conseguir no monento do fechamento da reunião, já ter mais claro quanto tempo é necessário para se fazer uma nova reunião, ou se os assuntos podem ganhar vida própria e reuniões mais focadas.

As reuniões, se bem planejadas, vão acabar sempre sendo uma “relação ganha ganha”. Boa sorte nas suas! E lembre sempre! Tenha uma quantidade de minutos para fazer um fechamento. Use a restrição de tempo para guiar o trabalho a ser feito na reunião. Avise as pessoas de onde elas estão e do andamento.

Para fechar, estou compartilhando um formato de convite que estou usando para marcar reuniões, pelo menos nas reuniões onde eu sou o facilitador. Fica como sugestão. Teste por aí, compartilhe o seu processo também e vamos aprender.

=== Agenda:
Costumo apresentar tópicos, quem puxa o tópico em específico (se for o caso) e a duração esperada do mesmo. Não esqueça de ter um tempo de fechamento.

=== Quem participa:
Normalmente indico área de interesse e quem daquela área participa. A lista de participantes não é suficiente. Acabo indicando o que espero da pessoa na reunião.

=== Como se preparar?
Se for o caso, se existir algum documento de apoio, indique para as pessoas. Faça elas poderem se preparar. E assim você evita os famosos “Pode me explicar o assunto X que eu não me lembro?”.

=== Tem que trazer alguma coisa para a reunião?
Caneta, papel, qualquer tipo de recurso que as pessoas precisam trazer para apoiar.

=== Dúvidas?
Procure <<facilitador>>.

Automatização utilizando Ant

Desenvolvedores que iniciaram seu aprendizado na linguagem Java utilizando alguma IDE, muitas vezes desconhecem como funcionam os processos responsáveis por transformar o código escrito, em software propriamente dito. Neste post irei mostrar um pouco sobre os conceitos por trás destes processos, como compilar e geração de arquivos .jar, e como automatizar estas tarefas utilizando o Ant.

Os arquivos .class

Quando desenvolvemos um software escrito em Java, não é nosso código em si que é utilizado para executar o programa. Antes de rodarmos o código que escrevemos, o mesmo deve ser compilado, etapa esta que a maioria das IDEs faz automaticamente. A compilação consiste em transformar o código fonte, legível para nós, em código de máquina ou bytecode, que é a forma que a JVM (Java Virtual Machine) compreende e sabe executar. Enquanto os arquivos que escrevemos possuem a extensão .java, este arquivos gerados, escritos em bytecode, são arquivos .class.

Os arquivos .jar e .war

A não ser que você esteja escrevendo seu primeiro Hello World, dificilmente seu programa em Java terá somente uma classe. O arquivo .jar é o executável do Java, nele se encontram os pacotes com todas as classes e arquivos do seu software. Os arquivos .war funcionam de forma semelhante, mas são criados para aplicações web, nele também se encontram todas as classes e arquivos do projeto. O arquivo .war é utilizado para instalar a aplicação no servidor web como Jboss ou TomCat.

Apache Ant

Apache Ant, ou somente Ant como é mais conhecido, é uma ferramenta que automatiza além dos processos mostrados anteriormente muitos outros. Você pode por exemplo criar e remover diretórios, mover arquivos entre eles, rodar seus testes unitários e gerar relatórios.

Instalação

Baixe o instalador do Ant aqui. Descompacte o arquivo no local de sua preferência. É necessário inserir o caminho da pasta “bin” do Ant às variáveis de ambiente do Windows. Copie o endereço da pasta bin que vai ser algo como “C:\Program Files\apache-ant-1.9.2\bin”. Vá nas propriedades do computador e acesse a opção variáveis de ambiente. Procure a variável Path e adicione no final de seu valor o caminho para o diretório copiado anteriormente. Isso é tudo que precisa ser feito, para conferir se a instalação ocorreu corretamente, apartir do prompt de comando digite: ant –version. Se tudo estiver certo, uma mensagem com a versão de seu Ant será exibida.

O arquivo build.xml

As operações do Ant, mais conhecidas como tasks, funcionam através de configurações escritas em um arquivo XML. Através de comandos simples as tarefas que vimos anteriormente podem ser automatizadas facilmente. Vou demonstrar isso através de um exemplo bem simples com o objetivo de demonstrar na prática como se monta um arquivo de build. Crie os arquivos build.xml e TesteAnt.java, e copie os trecho abaixo, ou baixe o exemplo pronto no meu GitHub.

public class TesteAnt {
public static void main(String[] args) {
System.out.println(“Hello Ant!”);
}
}

<project name=”teste” basedir=”.” default=”executar”>

<property name=”classes” location=”classes”/>
<property name=”arquivo” value=”TesteAnt” />

<target name=”diretorios”>
<mkdir dir=”classes” />
</target>

<target name=”apagar”>
<delete dir=”classes”/>
</target>

<target name=”compilar” depends=”diretorios”>
<javac srcdir=”${basedir}” classpath=”${classes}” destdir=”${classes}”/>
</target>

<target name=”empacotar” depends=”compilar”>
<mkdir dir=”build/jar”/>
<jar destfile=”build/jar/TestAnt.jar” basedir=”${basedir}/classes”>
<manifest>
<attribute name=”Main-Class” value=”main.TesteAnt”/>
</manifest>
</jar>
</target>

<target name=”executar” depends=”empacotar, apagar”>
<java jar=”build/jar/TestAnt.jar” fork=”true”/>
</target>

</project>

Por trás do exemplo

<project name=”teste” basedir=”.” default=”executar”>

Esta linha é o início do arquivo de build, onde é declarado o nome do projeto, o diretório base, e a task padrão que será executada pelo Ant.

<property name=”classes” location=”classes”/>
<property name=”arquivo” value=”TesteAnt” />

A tag property serve para declarar variáveis que podem ser utilizadas dentro do arquivo de build.

<target name=”diretorios”>
<mkdir dir=”classes” />
</target>

A tag target serve para definir um alvo para o Ant. Uma vez definido, você pode chamar o alvo dentro do arquivo, ou até de fora através do comando “ant nomeDoAlvo”. Mkdir cria um diretório com o nome recebido por parâmetro.

<target name=”apagar”>
<delete dir=”classes”/>
</target>

Delete apaga o diretório com o nome recebido. Não se preocupe não estamos criando e apagando em seguida o diretório, você já irá entender.

<target name=”compilar” depends=”diretorios”>
<javac srcdir=”${basedir}” classpath=”${classes}” destdir=”${classes}”/>
</target>

A tag javac, assim como o comando de mesmo nome, compila os arquivos .java gerando como saída os .class escritos em bytecode

<target name=”empacotar” depends=”compilar”>
<mkdir dir=”build/jar”/>
<jar destfile=”build/jar/TestAnt.jar” basedir=”${basedir}/classes”>
<manifest>
<attribute name=”Main-Class” value=”main.TesteAnt”/>
</manifest>
</jar>
</target>

A tag jar empacota os arquivos indicados gerando como saída um arquivo jar. Já a tag manifest cria o arquivo manifest necessário para criação do pacote jar.

<target name=”executar” depends=”empacotar, apagar”>
<java jar=”build/jar/TestAnt.jar” fork=”true”/>
</target>

E a tag java  executa um arquivo .jar. A tag depends indica que a iniciação do target depende da finalização de outro, por isso no exemplo anterior o alvo “apagar” não será executado após o “diretorios”, e sim antes do alvo “executar”. Cuidado ao montar seu arquivo, se um target não for dependência de outro, ele só será executado caso seja declarado como default na tag project.

Executando

Para executar o arquivo é simples, basta abrir o prompt de comando, navegar até a pasta onde se encontra o arquivo “build.xml”, e digitar o comando ant, se tudo ocorrer bem, você terá uma pasta com o arquivo .jar e a mensagem “Hello Ant!” será exibida no console. Também é possível executar um target específico executando o comando ant nomeTarget.

Como disse anteriormente, este foi apenas um exemplo didático, o Ant possibilita automatizar muitas outras tarefas de seu projeto. Abaixo seguem alguns links interessantes para se aprofundar no assunto.

Links

Ant: http://ant.apache.org/

Documentação: http://ant.apache.org/manual/index.html

Lista de tasks: http://ant.apache.org/manual/Tasks/ 

Qual a sua causa?

O relógio chama. Hora de acordar. Vale a pena? Você tem um motivo para acordar. Algo para fazer? Algo para realizar?

Como conseguir manter este foco. Como manter um propósito vivo? Nesta apresentação de pouco mais de 2mins, apresento alguns conceitos de caras famosos, como Daniel Pink e Chip Conley. Podemos ainda falar na famosa pirâmide de Maslow, que acabei pulando nesta apresentação (a pirâmide aparece quase como uma mensagem subliminar).

O dinheiro não é suficiente. Ser reconhecido pode não ser suficiente. Fazer parte de uma causa, que nos ajuda a manter o foco e aceitar as realizações que conseguimos alcançar, pode ser uma opção.

Esta palestra foi realizada em um uMov.me Labs Summit, evento de palestras usado para compartilhar e criar conhecimento.

Link para o vídeo no youtube. Ou mande um play aí na apresentação:

How to com experiências em JUnit 4

JUnit é um framework simples, baseado na arquitetura xUnit para a implementação de testes unitários na linguagem Java. O JUnit geralmente vem integrado em IDE’s como Eclipse e NetBeans, mas pode ser obtido através da seguinte url https://github.com/junit-team/junit/wiki/Download-and-Install. Para começar a trabalhar com JUnit é preciso identificar junto à IDE como criar suites de testes. Geralmente uma suite de testes implementada no JUnit estará vinculada a uma determinada classe a ser testada. Cada suite de testes é formada por um conjunto de testes unitários que farão afirmações específicas sobre comportamentos do código, gerando resultados positivos se as afirmações forem verdadeiras, e resultados negativos se as afirmações forem falsas.

Testes unitários no JUnit são caracterizados por métodos de classe que implementam comportamentos da ferramenta. Cada teste unitário pode ser mapeado através de uma anotação @Test, declarada junto com o método de teste para sinalizar ao JUnit que este método deve ser invocado quando executar a(s) suite(s) de testes. Cada teste deve mapear exatamente um cenário a ser testado na aplicação, exigindo que determinados comportamentos sejam testados várias vezes para os diferentes cenários identificados.

Existem afirmações básicas que podem ser utilizadas ao implementar um teste unitário. Dependendo das necessidades e objetivos do teste, afirmações diferentes podem ser melhor aplicadas ao contexto. O teste mais simples pode ser construído usando o comando assertEquals(expected, obtained), que serve para comparar dois valores (objetos), e verificar se eles são iguais (um valor esperado e um valor obtido).

Outros testes podem ser construídos usando comandos como assertTrue(booleanValue). assertFalse(booleanValue), assertNull(valueObject), assertNotNull(valueObject), assertArrayEquals(expectedArray[], obtainedArray[]), e alguns matchers que fazem comparações específicas entre os valores esperados e os valores obtidos. Exceções podem ser esperadas em determinados cenários de teste, sendo verificadas através da anotação @Test presente no cabeçalho, inserindo a Exception.class no atributo ‘expected’. Ex.: @Test(expected=’Exception.class’)

É possível também criar critérios próprios de teste, implementando classes de Assertions especializadas nas abordagens adotadas pelo desenvolvedor. Para isso basta construir comparações e comportamentos que verifiquem as condições desejadas do código. Caso as verificações falhem, o resultado deve ser transmitido através do comando fail(message). Dessa maneira o teste irá falhar e exibir a respectiva justificativa para a falha.

O tutorial apresentado nos slides pode ser consultado através do link https://github.com/rmuchoa/JunitExperience com os códigos armazenados no github. Ps.: O acesso a banco não foi implementado de verdade, foi apenas uma prova de conceito inicial.

Análise de Código utilizando SonarQube

No meu último post falei sobre métricas de código e os benefícios que eles podem trazer para a boa saúde do código. Hoje irei apresentar uma ótima ferramenta para gerar automaticamente estas métricas, SonarQube.

SonarQube é um software open-source que se propõe a ser a central de qualidade do seu código-fonte, lhe possibilitando o controle sobre um grande número de métricas de software, e ainda apontando uma série de possíveis bugs. Tudo isso é gerado através de uma análise completa do código, e após isso os resultados obtidos são mostrados através de uma interface web, em forma de dashboards, e gráficos. Um exemplo do resultado disto pode ser visualizado nesta página.

Iniciando o SonarQube

Vejamos então como configurar o SonarQube. Para este exemplo irei utilizar um projeto Java do jogo FizzBuzz. Além de Java, mais de 25 linguagens são suportadas como C# e Python por exemplo. Uma lista completa pode ser conferida aqui.

Baixe o SonarQube 3.6.3. Descompacte o arquivo em uma pasta de sua escolha. Abra a pasta “sonar-3.6/bin” e entre na versão relativa ao seu sistema operacional. Execute o arquivo StartSonar.bat (no caso do Windows). Um console irá aparecer e executar o serviço do Sonar. Para verificar se tudo ocorreu corretamente acesse o seguinte endereço em seu navegador: http://localhost:9000/. A tela abaixo deve aparecer.

exemplo

Tela de apresentação do SonarQube

Configurando o projeto

O próximo passo será criar o arquivo de configuração. Crie um arquivo com o nome “sonar-project.properties” na raiz de seu projeto. Abaixo segue o arquivo com a configuração para o projeto exemplo, copie para o seu arquivo e faça as adaptações necessárias para o seu projeto.

# metadados requeridos

sonar.projectKey=FizzBuzzSonarExample

sonar.projectName=FizzBuzzSonarExample

sonar.projectVersion=0.1

# caminhos para os códigos fontes

# caminhos podem ser separados por vírgula

sonar.sources=src/main/java

sonar.tests=src/main/test

# A linguagem do projeto

sonar.language=java

# Formato

sonar.sourceEncoding=UTF-8

Analisando o código

Para fazer a análise do código iremos utilizar o SonarQube Runner. Baixe o arquivo SonarRunner 2.2.2, e extraia o conteúdo em uma pasta de sua escolha. Agora é necessário adicionar o caminho onde se encontra o arquivo “sonar-runner.bat” às variáveis de ambiente (no caso do Windows). Clique com o botão direito em Computador e escolha propriedades. Vá em Configurações avançadas do sistema e entre em variáveis de ambiente. Edite a variável Path, adicionando no final o caminho para o SonarQube Runner, que irá ser algo como: “suaPasta\sonar-runner-2.2.2\bin”

variaveis

Adicionando o SonarQube Runner às variáveis de ambiente

Feita a configuração, é hora de análisar o projeto. Se certifique que o SonarQube foi iniciado e que seu projeto tenha o arquivo “sonar-project.properties”. Através do Prompt de Comando, navegue até a pasta raiz de seu projeto e digite o comando: “sonar-runner”. Se tudo ocorrer bem a análise deve iniciar e o resto do trabalho é feito automaticamente. O tempo de duração irá variar de acordo com o tamanho de seu código, e no final uma mensagem de sucesso é exibida.

prompt

Mensagem de sucesso na execução do Sonar Runner

Agora você pode acessar novamente o endereço http://localhost:9000/ para conferir o resultado. Os dashboards com as métricas padrões serão exibidos. Você pode configurar os dashboards, efetuando login com usuário: admin, e senha: admin. 

Por fim acesse a documentação oficial para conhecer as diversas opções de métricas disponíveis, e escolha as que atenderem o seu projeto.

Clean code good! Spaghetti code bad!

Desculpem pelo título em inglês, era para poder fazer a piada. O ponto é que ler um código espaguete é diferente de comer espaguete. O código neste “formato” provoca dores de cabeça e muitas vezes gera sentimentos como ódio, fúria, principalmente se você é chamado para corrigir algo em um código assim perto das 18h da sexta-feira.

O ideal é poder iniciar novos sistemas com boas práticas, de padrões de projetos e facilidade de leitura. Mas nem sempre é assim. E aí vem a importância do estudo contínuo de orientação a objetos, padrões de projetos, e tópicos de engenharia de software em geral.

excelencia-tecnica.032

Uma das referências neste aspecto é Bob Martin, o Uncle Bob.

Usei o Uncle Bob como motivação em alguns time que trabalhei, usando a regra da banda verde.  Selecionava pessoas que acreditava que tinham potencial de disseminar a cultura de TDD e Clean Code pela equipe, e doava uma banda verde para que aquele desenvolvedor sempre que fosse tocar no código se lembrasse de manter o código limpo e desenvolver como um desenvolvedor profissional.

Praticar código limpo. Se eu posso dar um conselho para você, esse é o meu conselho. E dentro da prática, está em transformar código. E transformar com paciência. Baby steps. Saber que débito técnico é uma realidade em qualquer código de produção. Mesmo times ágeis focados em refactoring, testes e qualidade no código sempre, encontrarão oportunidades de melhoria, para ganhar mais desempenho e estabilidade em algum pedaço de código fonte.

Pensando nisto trouxe um dojo diferente para a equipe. Coloquei um código Java ruim, com vários pequenos problemas que passam desapercebidos pelos desenvolvedores muitas vezes, para que durante o espaço do dojo o time fosse trabalhando criando testes básicos para garantir o comportamento do fonte e a partir daí focassem na refatoração da estrutura. Dá para ver o resultado depois de 40mins programando em um repositório do github. Lá tem o código original para quem quiser brincar.

Os Coding Dojos são excelentes oportunidades para a prática do código limpo. Seja de um problema do zero como de um problema “pronto” para ser transformado, como é o caso deste “bad code dojo”. Estudar ferramentas de apoio no processo do TDD, como ferramentas de auditoria de código fonte e cobertura de testes, também são ótimas possibilidades. No meu post sobre TDD tem algumas dicas.

E essa prática dever ser igual a do seu esporte favorito. Deve fazer parte da sua rotina praticar código e resolver problemas. Escolha um kata, e pratique código limpo! Comecei o post em inglês e vou terminar com uma tagline para vocês sobre qualidade de código e testes. Só quem faz teste automatizado vai entender:

Keep the bar green to keep the code clean!

Android & Lua

Neste post, vou apresentar um pequeno projeto de exemplo que mostra uma integração de Lua com uma aplicação Android.


O que é Lua?

Lua é uma “embed language”, ou seja, tem como objetivo ser usada dentro de uma aplicação escrita com outra linguagem (para estender a app, configurar, etc.). Quando foi criada na PUC-Rio, por exemplo, era usada por engenheiros da Petrobras (que nem mesmo eram programadores) para configurar o funcionamento de alguns softwares usados nas plataformas de petróleo.

Mais detalhes na página oficial: http://www.lua.org


Como um programa escrito em Lua roda dentro de uma aplicação?

Lua nada mais é que uma biblioteca escrita em C. É multiplataforma, pois usa apenas as funções e tipos da biblioteca padrão do C. É possível executar programas escritos em Lua (scripts) através da linha de comando, mas isso nada mais é que um pequeno executável que tem a biblioteca Lua dentro.

Então, para incluir Lua na sua aplicação, basta incluir essa biblioteca no seu programa e usar suas funções. É possível carregar arquivos com os scripts, executá-los e integrar funções e dados; por exemplo, funções escritas em C que podem ser chamadas pelo script Lua, e funções do script podem ser chamadas pelo código em C.


Lua e Android

No link https://github.com/marciodrosa/LuaAndAndroidSample há um sample que mostra como integrar Lua em uma aplicação mobile. No caso, Android. Teoricamente, deve ser possível também em outras plataformas, como iOS e Windows Phone 8 (o Windows Phone 7 não tem suporte a programação com C, logo, só é possível executar Lua caso exista alguma implementação não oficial da biblioteca em C#).

O objetivo é mostrar como uma aplicação poderia ser estendida com um plug-in escrito pelo usuário.

Ao executar a app, são exibidos três caixas de texto. Ao alterar valores das duas primeiras, a soma destes valores aparece na terceira. Essa lógica e manipulação do terceiro campo é feita por um script Lua.

postimg1 - screenshot


Mas as aplicações Android são escritas em Java, não em C!

Java permite integração com código escrito em C, a chamada Java Native Interface (JNI). O código escrito em C precisa ser compilado em uma lib, e por isso existem as ferramentas do Android para isso: o Android NDK (http://developer.android.com/tools/sdk/ndk/index.html). Além do compilador, há algumas bibliotecas disponíveis no NDK.

Assim, no Android, ocorre uma conversa entre três linguagens: Java <—> C <—> Lua.


Como funciona a app de exemplo LuaAndAndroidSample

Dentro do projeto há um arquivo “myscript.lua”, que é empacotado junto com a aplicação. Essa foi a maneira utilizada por este projeto de exemplo, mas é claro que poderia ser feito de outras maneiras, afinal, o script é apenas um texto; poderia ser recebido pela rede, lido de um arquivo, ou até mesmo criado dentro da app, em uma caixa de texto. O conteúdo do script é o seguinte:

 return {
   onfieldvaluechangedbyuser = function(context)
     local op1 = tonumber(context.fields["Field one"].value) or 0
     local op2 = tonumber(context.fields["Field two"].value) or 0
     return {
       newfieldvalue = {
         field = "Field three",
         value = op1 + op2,
       }
     }
   end
 }

Este script é como um plugin, ele altera o comportamento da aplicação para mostrar uma nova informação na terceira caixa de texto. Quando a app é iniciada, ela carrega e executa o script, que apenas retorna uma tabela (objeto) com as funções de callback para serem chamadas em determinados eventos. No exemplo, esta tabela tem uma função chamada “onfieldvaluechangedbyuser”, que é chamada pela app quando uma caixa de texto tem o valor alterado pelo usuário.

A função onfieldvaluechangedbyuser recebe um objeto de contexto, que possui os dados da aplicação (como os valores das três caixas de texto). Na implementação, ela retorna um outro objeto (result), que é então processado pela app. Este outro objeto pode possuir um novo valor para algum campo. No myscript.lua, o script retorna um novo valor para ser setado na terceira caixa de texto.

Resumidamente, este é o fluxo do que ocorre:

Usuário altera um valor na caixa de texto –> app chama o callback do script, passando o contexto –> script retorna um resultado –> app processa o resultado.

A idéia dessa arquitetura é isolar a execução do script em uma sandbox: não há interação entre a app e o script (por exemplo, o script não altera o valor da terceira caixa de texto; ao invés disso, ele retorna um objeto solicitando que a app faça isso). Esse isolamento é feito para deixar a execução do script mais unitária, facilitar os testes e simplificar o fluxo.

Além disso, usei um pouco da idéia dos plugins do Blender (blender.org), que também são executados assim que a aplicação é iniciada, e que possui funções de callback para serem chamadas mais tarde, quando ocorrem eventos (também recebendo um objeto de contexto como parâmetro).

postimg2 - flow


Como foi feita a integração na app (a “engine” de plug-ins)

A arquitetura básica da “engine” é exemplificada na seguinte imagem:

postimg3 - languageflow

  • A biblioteca em C foi nomeada de “Bridge”, já que é uma ponte entre a app e os scripts.
  • A aplicação Java e o “Bridge” em C conversam entre si (Java solicita para a Bridge que o plugin execute; a Bridge retorna resultados para a aplicação Java).
  • A Bridge e uma engine Lua conversam entre si. Essa engine não é o plugin em si. Ela é usada para fazer a lógica de chamada do plugin, processar erros, resultados, etc. Isso mostra como Lua pode ser usado não apenas para estender a aplicação: neste caso, foi usada para implementar uma lógica que pertence nativamente à aplicação. Isso pode ser muito útil para aplicações multiplataforma. Por exemplo, se a mesma app for implementada para outro sistema, como iOS, o código dessa engine em Lua pode ser reaproveitado.
  • Por fim, a engine em Lua faz o plugin executar. O plugin não se comunica com ninguém, ele executa em uma sandbox isolada, evitando que a lógica implementada por um usuário possa agir de maneira inesperada na aplicação. Toda a comunicação é feita entre a engine Lua e a Brigde C.

Algumas informações adicionais

  • Embora Lua utilize ANSI C (apenas as bibliotecas padrão), nem tudo são flores: o NDK, por exemplo, não possui a API de internacionalização do C (utilizada pelo Lua para saber se um número decimal usa ponto ou vírgula). Então, pequenos ajustes são necessários. O código fonte do Lua 5.2 pronto para ser compilado para Android pode ser pego no meu repositório do Github: https://github.com/marciodrosa/LuaAndroid. Além dos ajustes necessários, ele também direciona as mensagens de erro e log para o logcat.
  • Para fazer o build de uma lib para Android usando código-fonte C, os arquivos de código devem ser colocados dentro de uma pasta chamada “jni” e o comando “ndk-build” deve ser executado. Dentro da pasta “jni” também há alguns arquivos de configuração, como “Android.mk” e “Application.mk”, e outras libs pré-compiladas, caso sejam usadas pelo projeto. O NDK automaticamente move os binários gerados para dentro da pasta “lib”. No projeto Java do Android, as libs que serão usadas devem ser carregadas usando System.loadLibrary (ver a classe StartActivity do projeto LuaAndAndroidSample). O build pode parecer um pouco difícil de entender no começo. Para mais detalhes, é necessário ler a documentação do NDK. A maior parte da documentação não está disponível online; ao invés disso, vem junto com o projeto do Android NDK, quando ele é baixado.
  • No projeto AndroidAndLuaSample, há um método que gera o objeto “context”, que é passado para o callback do script. Ele gera o context concatenando scripts. Obviamente, isso não é uma boa prática, não estamos lidando com linguagens orientadas a string! Que fique claro que isso foi feito apenas para demonstração. O correto seria criar o objeto de contexto usando a API C do Lua.
  • Este sample funciona apenas em dispositivos com processador ARM. É necessário fazer outro build das bibliotecas C para que elas funcionem com outros processadores, como Intel.

Links

Página oficial do Lua:
http://www.lua.org/

Documentação do Lua (manual, referência da API e referência da API C):
http://www.lua.org/manual/5.2/

Livro online gratuito sobre Lua (mas é de uma versão antiga do Lua, com algumas features desatualizadas):
http://www.lua.org/pil/contents.html

Android NDK:
http://developer.android.com/tools/sdk/ndk/index.html

Lua 5.2 para Android:
https://github.com/marciodrosa/LuaAndroid

Código-fonte do projeto de exemplo “LuaAndAndroid”:
https://github.com/marciodrosa/LuaAndAndroidSample