quarta-feira, 26 de dezembro de 2012

Tutorial do Maven para Android

O Maven é uma ferramenta de gerenciamento de projetos, com ela você pode gerenciar as dependências de seu projeto, automatizar relatórios, execução de testes e etc.

É muito popular em Java mas há também um plugin para usá-lo para gerenciar também um projeto Android.

Pré-requisitos
  1. JDK 1.6 +
  2. Android SDK
  3. Maven 3.0.3 +
  4. Eclipse Indigo ou Juno
Primeiramente é necessários configurar a variável de ambiente ANDROID_HOME apontado para o diretório em que está o seu Android SDK, no meu é a seguinte:

export ANDROID_HOME=$HOME/dev/android-sdk

Adicione essa variável em seu path bem como os sub-diretórios $ANDROID_HOME/platform-tools $ANDROID_HOME/tools, exemplo:

export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools

Para o Windows seria algo como 
%ANDROID_HOME%\tools e %ANDROID_HOME%\platform-tools

Integração com o Eclipse

Para o Maven para android funcionar bem com o eclipse é necessária a instalação do plugin M2E-Android.

Abra o eclipse e no menu superior escolha Help > Eclipse Marketplace.
Busque por Android M2E.
Clique em Install no item Android Configurator for M2E.
Next, next next e finish...
Reinicie o Eclipse.
Pronto seu plugin já deve estar instalado

Criando um projeto com o Maven

É possível criar um projeto Android pelo maven usando o Eclipse, eu pessoalmente prefiro criar na linha de comando.


mvn archetype:generate \
  -DarchetypeArtifactId=android-release \
  -DarchetypeGroupId=de.akquinet.android.archetypes \
  -DarchetypeVersion=1.0.8 \
  -DgroupId=com.blogspot.runnerdtalks\
  -DartifactId=MavenTest \
  -Dplatform=10 \
  -Dpackage=com.blogspot.runnerdtalks.maventest

Esse archetype gerará um projeto com algumas configurações extras para permitir que o app seja publicado no Google Play.

Ao usar esse archetype serão criados 2 projetos, um chamado MavenTeste para o aplicativo e outro chamado MavenTest-it para os testes do aplicativo criado.
Esse archetype já possui configurações que possibilitam a publicação do aplicativo também no Google Play, ainda existem outros archetypes com menos opções pré configuradas, é possível encontrar esses outros archetypes neste link aqui

Importando o Projeto para dentro do Eclipse.

No eclipse vá em File > Import > Existing Maven Projects escolha o diretório do projeto recém criado e selecione só os dois projetos filhos.



E Finish

Se o projeto estiver reclamando da falta dos diretórios src/test/java crie eles e de um refresh no projeto pelo eclipse.

Para adicionar dependências é só editar seu pom.xml como um projeto Maven normal, depois clique com o botão direito em seu projeto vá em Maven > Update Project.

Lembrando que se um dia precisar compartilhar este projeto com seus amigos ou subir no repositório, sempre remover os arquivos do eclipse e os binários de seu SCM.

Referências

Maven Android Plugin
M2E Android
Android Maven Archetypes



sábado, 11 de agosto de 2012

Python

No encontro que tivemos no Utils.runNerdTalks(10), falamos sobre Python.

É difícil falar de uma linguagem, porque tem muita coisa a se falar.

O que posso dizer, é que é a linguagem que mais estou usando ultimamente, e a cada dia descubro coisas novas, e interessantes.

Python 

O Python é uma linguagem de programação de alto nível, interpretada, imperativa, orientada a objetos, de tipagem dinâmica e forte. O código é aberto, e multiplataforma.

Ela foi criada por Guido van Rossum, que não por acaso trabalha hoje na Google (uma das empresas mais conhecidas que utilizam Python).

Apesar do nome estar associado ao réptil píton, a linguagem veio em homenagem ao grupo humorístico britânico Monty Python.


Always Look on the Bright Side of Life

1) Instalação

O Python já vem instalado em vários sistemas operacionais como Linux e Mac. Caso não tenha instalado na máquina acesse aqui.

Hoje ele está na versão 3, mas utilizamos a versão 2.7 para exemplificar. A versão 3 tem quebra de compatibilidade com a versão 2.7



Para verificar a versão do Python na máquina digite:
python --version

2) Começando a brincar

Para abrir um shell interativo, digite
python

Abrirá algo como:


Dentro dele, pode-se digite:
x = 1
y = 1
resultado = x + y
print resultado


Note que diferentemente de Java, nós não atribuimos o tipo para as variáveis. Assim sendo posso também fazer:
x = "Alexandre "
y = "Uehara"
resultado = x + y
print resultado


Isso é o começo para brincarmos com o Python (em um shell interativo). Aliás caso queiram, pode instalar também o iPython (o qual recomendo bastante).


3) Bibliotecas

Para instalar o iPython e outras bibliotecas, recomendo instalar pelo easy_install ou pip. Eles são gerenciadores de bibliotecas (tal como apt-get e RubyGems).

Lembrando que em Python muitas bibliotecas já vem como padrão, não precisando instalar bibliotecas de terceiros.

Exemplo:
Caso eu queira instalar o virtualenv, digite:
sudo easy_install virtualenv
ou

sudo pip install virtualenv

Aliás o virtualenv, é uma ferramenta para termos várias versões de python em sua máquina. Semelhante ao RVM em Ruby.

4) Escrevendo um programa

4.1) Hello World
Para escrever um Hello World, crie um arquivo, helloworld.py
Dentro dele escreva:
print Hello World

Só isso? Sim, só isso. Depois disso, digite no terminal:
python helloworld.py

4.2) Hello World executável
Dentro do mesmo arquivo adicione na primeira linha:
#!/usr/bin/python

Depois dê permissão de executável ao arquivo:
chmod ugoa+x helloworld.py

E, execute:
./helloworld.py

Simples!!!

4.3) Blocos == Identação
O que torna o Python simples de ler, entender e dar manutenção é que não existe blocos com chaves "{" e "}" como no Java. Os blocos são as próprias identações.

 Exemplo: crie um programa chamado:
- nome.py
#!/usr/bin/python
if nome == "Alexandre":
  print nome
else:
  print "outro nome"

Veja que colocamos 2 espaços depois do if, e depois do else. Dê novamente a permissão de executável ao arquivo, e execute.

4.4) Classes 
Apesar da linguagem ser orientada a objetos como vocês puderam ver anteriormente, não precisamos utilizá-lo dessa maneira.

Mas o legal, é realmente usá-lo como OO. Para criar uma classe:
class Empregado()
  def __init__(self, nome):
    self.nome = nome
  def printNome(self, mensagem="Meu nome é: "):
    print mensagem + self.nome

Mas o que é esses montes de "self". É... realmente não é elegante, mas é como se fossem os vários "this" do Java.

E o "__init__"?? É o construtor da classe.

 E o "mensagem=" no método "printNome". O "mensangem=" é o argumento do método, mas com um valor default. Isso é para faciliar a sobrecarga de métodos. Lembrando que não é necessário colocar um valor default para ele..

É possível também passar ao método os argumentos em qualquer ordem, passando o nome do argumento:

#!/usr/bin/python
# -*- coding: utf8 -*-
class Empregado():
  def __init__(self, nome):
    self.nome = nome
  def printNome(self, mensagem="Meu nome é: ", mensagemfinal="."):
    print mensagem + self.nome + mensagemfinal

def main():
  empregado = Empregado("Alexandre")
  empregado.printNome(mensagemfinal="!!!")

if __name__ == "__main__":
    main()


Veja que adicionamos na 2a. linha o encoding.
E para iniciar o programa, colocamos o main.

4.5) Bibliotecas
Para chamar uma biblioteca é só chamar o import:
#!/usr/bin/python
# -*- coding: utf8 -*-
import unittest
ou
#!/usr/bin/python
# -*- coding: utf8 -*-
import os
print os.getcwd()

Veja que acima, nós adicionamos a biblioteca "unittest" e na outra o "os".
Ah! E como dá para perceber, o "unittest" vem como padrão no Python. Muito legal! hahah!!!!

Caso não queira importar tudo, pode-se chamar:
#!/usr/bin/python
# -*- coding: utf8 -*-
from datetime import timedelta
d = timedelta(microseconds=-1)
print d
Importando apenas o timedelta do datetime

4.6) "Grandes poderes trazem grandes responsabilidades."
A linguagem Python deixa você fazer muitas coisas, que outras linguagens não deixam, como acesso a atributos protected.

Ou seja, não é uma linguagem "burocrática", entãããããããão tome cuidado com o que você vai fazer.

Usos da Linguagens

O Python é poderoso. Há muitos tipos de uso como:
- em scripts
- web, usando Frameworks como, Django, FlaskZope, etc
- CMS, como Plone
- Sistemas embarcados
- Games, usando por exemplo o  PyGame, PyOpenGL
- Jython - Python rodando na JVM
- IronPython - para .NET
- Procesamento de imagens - PIL - Python Imaging Library
- Interfaces Gráficas - PyGTK, PyQt
- etc.

Conclusão

Gostaria de escrever muito mais coisa sobre a linguagem, mas o post já está ficando comprido demais. O que escrevi foi o básico e bem superficial. Abaixo ficará algumas fontes, para quem se interessar mais. Ou entre em contato comigo no @AleUehara

E por último digite no interpretador python:
import this


The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Fontes: 

Site Oficial - Python
Python Brasil
Evento Python Brasil
Wikipedia - Python
Django Brasil
Python - Google Groups
Google Python Style Guide
Code Academy
Learn Python

- Livros
Dive into Python
Livros de Python
6 Livros Gratuitos Aprenda a Programar (em pt-br)
Tutorial de Python (em pt-br)

- Curso
Globalcode - Academia Python

- Video
Introducing Python
Show me Do
Python Brasil [5]

- Aplicativo no iPhone
Python for iOS

- Curiosidade
Mandelbrot in Python

quarta-feira, 6 de junho de 2012

Mocks com Mockito - Parte 3

Neste post vamos abordar o uso de Spies usando o Mockito.

Ao contrário de Mocks com os Spies é possível chamar os métodos reais da classe.

List<String> listaSpy = new ArrayList<String>();
listaSpy = Mockito.spy(listaSpy);

listaSpy.add("item1");
//Chama o método verdadeiro do objeto e retorna a String = "item1"
listaSpy.get(0); 
Mockito.doReturn("outra coisa").when(listaSpy).get(0);
//Não chama o método verdadeiro e retorna a String = "outra coisa"
listaSpy.get(0); 

Ao contrário dos Mocks um objeto Spy age como se fosse um Semi mock, em outras palavras,  quando não definimos um outro comportamento para o Spy, seu funcionamento é igual ao de um objeto normal. No entanto ao definirmos um outro comportamento (linha 8) ele se comporta como um Mock para o caso que definimos.

Ok e eu com isso?! Vamos ver um uso mais real de um spy.

O uso que eu tive ao usar o Spy foi para Mockar criação/instanciação de objetos.

Por exemplo, na classe Connection temos o seguinte método.

//declaração da classe Connection
public boolean connect() {
  try {
    socket = new Socket(hostAddress, port);
    printStream = new PrintStream(socket.getOutputStream());
    bufferedReader = new BufferedReader(
                       new InputStreamReader(socket.getInputStream()));
    return true;
  } catch (UnknownHostException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  }

  return false;
}

public String readMessage() { 
//...
  return bufferedReader.readLine();
//...
}

Como faremos para testar esta classe e o método readLine(), se no cenário atual nós não podemos criar um mock de BufferedReader em nosso teste e passa-la para o objeto Connect, pois o BufferedReader é instanciado dentro da classe Connect!. :/

Spy ao seu resgate! Uma solução é usar Spies para simular isso... então nosso primeiro passo é criar métodos na classe Connect que criem os objetos que precisamos.

Ficando assim o código.

//declaração da classe Connection
public boolean connect() {
  //..
  socket = createSocket();
  printStream = createPrintStream();
  bufferedReader = createInputStream();
  return true;
  //...
}

public String readMessage() { 
  //...
  return bufferedReader.readLine();
  //...
}

protected Socket createSocket() //...
protected PrintStream createPrintStream() //...
protected BufferedReader createInputStream() //...


Veja que os métodos que criam os objetos são protected, isso é necessário pois o Mockito não consegue interceptar métodos que são privados.

O teste da classe ficará assim:

import static org.mockito.Mockito.*;
import static org.junit.Asserts.*;

@Test public void shouldReadMessage() throws UnknownHostException, IOException {
  //cria instancia da classe a ser testada
  Connection connection = new Connection("127.0.0.1", 14000);
  //transforma em um spy
  connection = spy(connection);
  //cria os mocks que serão retornados 
  //pelos metodos de criação de objetos 
  Socket socket = mock(Socket.class);
  BufferedReader bufferedReader = mock(BufferedReader.class);
  PrintStream printStream = mock(PrintStream.class);

  //define o comportamento dos métodos 
  doReturn(socket).when(connection).createSocket();
  doReturn(bufferedReader).when(connection).createInputStream();
  doReturn(printStream).when(connection).createPrintStream();
  when(bufferedReader.readLine()).thenReturn("readed from mock");

  connection.connect();
  assertNotNull(connection.readMessage());
}

Veja que apesar de termos que alterar a nossa classe e extrair as criações de objetos para métodos protected, foi possível criar um teste do método readMessage usando mocks dos objetos do socket.

O uso de Spies da maneira que foi mostrada, pode indicar que seu código esteja com um acoplamento alto e como sempre cabe pensar um pouco se não existe um jeito melhor de programar sua classe para evitar isto.

Isso conclui nossa série de posts sobre o Mockito, pelo menos por enquanto, espero muito que a pequena introdução que escrevi aqui os ajudem a criar seus testes unitários assim como tem me ajudado bastante.

Segue os links que usei de referência
Mocking object creation
Mockito class javadoc
Site do Mockito

Código fonte: https://github.com/diegoy/talks-mockito

Qualquer dúvida, como sempre perguntem, farei o possível para ajudar.

terça-feira, 5 de junho de 2012

Mocks com Mockito - parte 2

Para continuar nosso "papo" sobre Mocks vou apresentar mais algumas funções do Mockito

Como talvez você já tenha percebido o mockito não serve só para mocks, mas serve também para testar o comportamento da classe que está sob teste com suas dependências.

Usando o mesmo exemplo da nossa classe que envia mensagens. Imagine agora que temos um novo métod que recebe uma ou várias mensagens e as envia usando o objeto connection.

Usando o Mockito podemos escrever um teste como o abaixo.

import static org.mockito.Mockito.*;
//class declaration bla bla bla.
@Test
public void behaviourTest() {
  Connection connection = mock(Connection.class);
  
  MyMessageSender messageSender = new MyMessageSender(connection);
  
  messageSender.sendMultipleMessages("Mensagem 1", "Mensagem 2");
  
  verify(connection, times(2)).sendMessage(anyString());
}


Traduzindo a Linha 11:
  • Verificar que o método sendMessage com o argumento...
    • uma string qualquer
  • foi chamada duas vezes

O Mockito também possibilita simular o retorno de mensagens.

Para demonstrar isto criaremos um novo para sabe se a nossa classe está recebendo as mensagens corretamente, nesse caso ao invés de usar o mock para testar a passagem de parâmetros para ele teremos que usa-lo para simular os retornos de seus métodos.

Testaremos a classe MyMessageReader que se parece com a seguinte classe.

public class MyMessageReader {
  private Connection connection;
  
  public MyMessageReader(Connection connection) {
    this.connection = connection;
  }

  public String readMessage() { 
   return connection.readMessage();
  }
}

Novamente nossa classe sob teste usa um objeto Connection, mas desta vez o método que chamamos é connection.readMessage()

Nosso teste então terá que simular um retorno de connection.readMessage(), usando o Mockito ficaria como o código abaixo.

@Test
public void readMessageTest() {
  connection = mock(Connection.class);
  
  given(connection.readMessage()).willReturn("minhaMensagem");
  myMessageReader = new MyMessageReader(connection);
  
  String readedMessage = myMessageReader.readMessage();
  
  assertEquals(readedMessage, "minhaMensagem");
}

Claro que como tudo em programação existe mais de uma maneira simular os retornos de chamados dos métodos, as duas linhas seguintes são equivalentes.

given(connection.readMessage()).willReturn("minhaMensagem");
when(connection.readMessage()).thenReturn("minhaMensagem");

A primeira linha tem uma abordagem mais em linha com BDD, tanto que o método given é da classe BDDMockito.

Caso o método que simulamos o retorno receba um parâmetro podemos definir diferentes tipos de retorno para diferentes parâmetros, como no exemplo abaixo.

Map map = mock(Map.class);
given(map.get(anyString())).willReturn(null);
given(map.get("chave1")).willReturn("valor1");

map.get("chave1"); //retorna string "valor1"
map.get("outraChave");//retorna nulo

No próximo post de Mocks mostrarei como usar Spies em seus testes com Mock.

Se quiser o código completo pode pegar no git hub.
https://github.com/diegoy/talks-mockito

Valeu!

Mais:
Mocks com Mockito, parte 3

domingo, 3 de junho de 2012

Mocks com Mockito

Desta vez vamos ter uma breve introdução ao uso de Mocks em seus testes.

Há vários benefícios que o uso de testes unitários podem trazer, eu pessoalmente gosto muito de ter testes pois ajuda muito na hora de refatorar seu código e ter a certeza de que o seu funcionamento não mudou, escrever os testes também nos ajuda a identificar casos em que o código está com um alto acoplamento.

Usando TDD ou não os testes são importantes mas podem ser muito difícil de escreve-los

Muitas vezes ao tentar escrever testes para algumas classes temos alguns desafios.
Um Software geralmente depende de vários outros sistemas para funcionar, por exemplo uma base de dados, levando isso em conta os testes de classes que se comunicam com a base de dados são mais difíceis de escrever e o uso de um framework de mocks pode ajudar muito! 

Neste artigo vamos falar do Mockito, que é um framework de mocks criado para a linguagem Java (há versões para outras linguagens). 

A instalação é simples, baixe o jar no site do mockito, coloque-o no seu classpath e pronto! Ou se preferir configure no dependencies de seu maven :)

Suponha que em seu código você tenha uma classe que seja responsável por enviar mensagens através de um socket, aqui vou chama-la de MyMessageSender, sua classe tem como regra enviar mensagens somente com letras maiúsculas.

public class MyMessageSender {
 
  private Connection connection;

  public MyMessageSender(Connection connection) {
    this.connection = connection;
  }

  public void send(String string) {
    connection.sendMessage(string.toUpperCase());
  } 
}

No construtor da classe MyMessageSender passamos como parâmetro um objeto do tipo Connection. Esse objeto possui a conexão do socket e também possui um método sendMessage que escreve uma mensagem no socket.

Para fazer o teste unitário desta classe necessitaríamos instanciar a classe connection para passarmos à classe testada.
 
public class Connection {

  // declaracao dos atributos

  public Connection(String hostAddress, int port) {
    super();
    
    this.hostAddress = hostAddress;
    this.port = port;
  }
 
  public boolean connect() {
    try {
      socket = new Socket(hostAddress, port);
      printStream = getPrintStream(); //abre um output stream
      inputStreamReader = getOutputStream(); //abre um input stream
      return true;
    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  
    return false;
  }
 
  public void sendMessage(String message) {
    printStream.print(message);
    printStream.flush();
  }
}

Vendo a classe Connection perceba que será um pouco trabalhoso instancia-la dentro do teste, pois ela se conecta a um sistema externo, levando isso em conta precisaríamos também criar um mock desse sistema externo para testarmos adequadamente a nossa classe. E consequentemente estaríamos testando muito mais que somente nossa classe MyMessageSender.

Usando o Mockito podemos facilmente criar um mock de Connection para usar em nosso teste sem termos que nos preocupar com as conexões que são necessárias a classe Connection.

@Test
public void sendMessageTest() {
 Connection connection = Mockito.mock(Connection.class);
 
 MyMessageSender messageSender = new MyMessageSender(connection);
 
 messageSender.send("Uma mensagem");
 Mockito.verify(connection).sendmessage("UMA MENSAGEM");
}

Na linha 3 criamos um mock da classe Connection.

Na linha 8 colocamos uma verificamos que o método sendmessage do objeto connection foi chamado passando como parâmetro a string "UMA MENSAGEM". Qualquer string diferente da informada na linha do verify vai causar uma falha no teste.

Assim conseguimos garantir o correto funcionamento da classe MyMessageSender sem precisar ficar criando uma instância real da classe Connection.

No próximo post escreverei como o Mockito pode te ajudar para simular respostas de métodos.

Código fonte disponível no meu github
https://github.com/diegoy/talks-mockito

Mais:
Mocks com Mockito, parte 2
Mocks com Mockito, parte 3