Um Manifesto!

...

  • Increase font size
  • Default font size
  • Decrease font size

Blog

Testes Unitários em PHP com simpletest

E-mail Print PDF

Testes automatizados são parte importante do desenvolvimento de software, apesar de ser a mais demorada prática a se aceitar, é a que mais traz benefícios. O seu uso deve ser simples, e por isso é bom o uso de um framework prático para tal.

No começo escrevi scripts de testes "na mão" mesmo, com ifs e elses, mas, apesar de ser melhor que nada, não é nada prático se comparado ao uso de um bom framework. Então tentei usar o phpunit uma vez, mas achei mais complexo que o necessário, então parti para o simpletest.

O simpletest é realmente simples, basta fazer o download do pacote e descompacta-lo na sua pasta de testes, e em seguida é só escrever sua suite de testes.

Uma suite de testes é escrita da seguinte forma:


< ?php

include_once 'simplestest/autorun.php';

class AllTests extends TestSuite {
function allTests() {
$this->TestSuite("Meus testes");
$this->addTestCase(new MeuCasoDeTests1);
$this->addTestCase(new MeuCasoDeTests2);
}
}

?>

E cada caso de teste se define da sequinte forma:


< ?php

include_once 'simpletest/autorun.php';

class MeuCasoDeTests1 extends UnitTestCase {
function testFoo() {
$this->assertEqual("foo","foo");
}
function testBar() {
$this->assertEqual("foo","bar");
}
}
?>

Cada função no caso de teste iniciada por "test" será executada na ordem declarada, e o cada "assert" é um teste. Existem vários "asserts" disponíveis.

Basta acessar pelo browser a url do caso de testes ou da suite de testes e ter certeza de testar tudo, para garantir a qualidade do software.

Last Updated on Tuesday, 01 December 2009 13:25
 

Programando fora da zona de conforto: Programação Funcional e NoSQL

E-mail Print PDF

Mais alguns links da série de programação funcional, e também adcionar o NoSQL a lista, banco da dados não relacionais para resolver o problema da escalabilidade.

 Divirta-se. 

Last Updated on Sunday, 06 December 2009 13:32
 

Linux em um pendrive: Debian e Enlightenment (E17) persistente.

E-mail Print PDF

História

 

Enlightenment E17
 

 

Além de já ter usado o Linux em um pendrive com o DSL, que é uma das distros que melhor se adaptam ao estilo, é fácil hoje instalar outras distros semelhantes, como o Slax, o SliTaz (muito bom) e o TinyCore(abandonei o DSL por este), com seus 10MBs.

A boa noticia é que hoje é bem mais fácil rodar um linux a partir de um pendrive, temos o projeto pendrive linux, com vários distros preparadas para tal, e o unetbootin para configurar e “bootar” qualquer ISO a partir de um pendrive.

Parti então para as distros completas: Ubuntu e Debian. O Ubuntu eu não gosto, acho um desktop muito fraco. O Debian iniciei com o projeto do Debian Live, oficial, mas este se baseia na versão estável, então está muito antigo nos pacotes. Mas como o debian é o debian era possível reconstruir o Debian live em qualquer versão, com o Debian Live Helper, mas também dava muito trabalho e demorava muito.

Foi ai que pensei em ficar com as minimalistas, entre o TinyCore e o SliTaz. Não fiquei com o SliTaz por que me parecia pacotes muito antigos, em especial o kernel, já o TinyCore eu fiquei com preguiça mesmo, afinal ainda seria muito parecido com o DSL.

Ai eu esbarrei no Elive. Na verdade já paquerava o Enlightenment tem um bom tempo, mas E16 não é tão interessante, e o E17 envolvia muitas gambiarras, e as versão “fáceis” de instalar não estavam muito legais.

Uma boa opção me pareceu usar o Elive, baseado no debian, que já vem configurado com tudo de bom e melhor do Enlightenment de desenvolvimento, por isso resolvi testa-lo.

Como fazer

 

Unetbootin com E17 ELIve
 

 

Primeiro instale o Unetbootin, que está presente na maioria das distribuições modernas:

# aptitude install unetbootin

Executando-o como root, o unetbootin já existem diversas distros prontas, ele mesmo se encarrega de baixar a ISO configurar o pendrive e torná-lo bootável com o syslinux.

Você pode também fazer o Download da ISO do ELive você mesmo(eu fiz assim), e seleciona-la no unetbootin, e então é só seguir e iniciar o processo, não tem mistério nenhum.

O passo seguinte, após o unetbootin dizer que terminou, é configurar um arquivo para que o Elive salve as alterações. Você precisa primeiro criar um arquivo para ser a “partição” da persistencia:

# dd if=/dev/zero of=elive-rw bs=1M count=1024

O valor do count diz o tamanho do arquivo em megabytes, veja quanto resta no pendrive e quanto você quer usar, no exemplo vai ter 1GB (mais ou menos).

Em seguida formate-o como ext3, apenas confirme:

# mkfs.ext3 elive-rw

Agora pode copiar o arquivo elive-rw para a raiz do pendrive, e editar o arquivo de boot “syslinux.cfg” nessa mesma raiz. No linha append da entrada padrão adcione “persistent=elive-rw” e salve.

Basta desmontar o pendrive e rebootar o computador com a BIOS configurada para carregar apartir do pendrive e curtir no ambiente. Trate-o como um netbook, pois o espaço é pouco.

Um detalhe importante, que me atrapalhou a testar o elive antes, é que ele não roda no Qemu(e KVM) por algum motivo, mas funciona no VirtualBox e VMWare, eu acredito.

Agora posso carregar meu lindo ambiente de programação para todo canto, combinado com controle de versão, e impressionar todo mundo com como o linux pode ser bonito :D

Last Updated on Saturday, 21 November 2009 19:50
 

Compartilhando internet pela rede sem fio no linux

E-mail Print PDF
Tutorial de como configurar sua placa de rede sem fio para compartilhar a internet, no linux.

Aqui vou explicar como configurar seu computador/notebook como hotspot wifi, para compartilhar a internet na rede sem fio, com o mínimo de "segurança" WEP apenas.

O Primeiro passo é saber qual a interface que chega a conexão com a internet, no geral se é internet discada, 3G ou se usa o pppoe a interface é ppp0, se a internet chega roteada pela rede é a mesma da interface de rede, eth0 ou outro. Aqui uso internet móvel 3G, então conecta em ppp0.

Temos então que mascarar o encaminhamento de pacotes dessa interface por um nat, usando as regras do iptables. Carregue o módulo de nat, definir a regra e ativar o encaminhamento no sistema, com os seguintes comandos:

# modprobe iptable_nat
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# echo 1 > /proc/sys/net/ipv4/ip_forward

O próximo passo é configurar a rede wifi, com os seguintes comandos:

# ifconfig wlan0 down
# ifconfig wlan0 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255
# ifconfig wlan0 up

Em seguida definimos as caracteristicas da rede sem fio, definindo o nome, o modo ad-hoc, a chave de encriptação e para apenas aceitar com encriptação, os comandos:
# iwconfig wlan0 essid "acer"
# iwconfig wlan0 mode ad-hoc
# iwconfig wlan0 key 's:diogo'
# iwconfig wlan0 key restricted

Para os clientes receberem as configurações devidas você precisará agir como cliente dhcp (ou configurar manualmente a rede nos clientes), você pode instalar o servidor com o seguinte comando:

# aptitude install dhcp3-server

Para configurar o servidor, edite o arquivo /etc/dhcp3/dhcpd.conf, conforme:

ddns-update-style ad-hoc;
option domain-name "home.org";
option domain-name-servers 208.67.222.222, 208.67.220.220;
default-lease-time 600;
max-lease-time 7200;
authoritative;
log-facility local7;
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.10 192.168.0.254;
option routers 192.168.0.1;
option broadcast-address 192.168.0.255;
}

Com o dhcp configurado, basta ativa-lo na interface da rede sem fio.

# dhcp3d wlan0

Agora os clientes podem se conctar a sua rede e navegar na sua internet. Você pode tentar configurar outro meio mais seguro que WEP, mas eu não sei ainda :P e definir regras no dhcp e iptables limitando os MACs e IPs, mas isso fica para próxima.
 

Downgrade de versão no Debian

E-mail Print PDF

Sabe, sou um feliz usuário de Linux. Mesmo tendo um hardware complico, isso melhorou com o tempo.

A história deste post está no primeiro link.

Vou explicar aqui o simples passo-a-passo para fazer o downgrade de versão do debian, sem reinstalar o sistema ou fazer algo mais complicado que o apt-get costumeiro. Se você usa o debian, sabe que pode fazer isso com a consciencia limpa.

O debian tem um sistema de "pinning" para o apt, que permite, entre outras coisas, definir preferencias de versões de pacotes, e vamos usar isso para fazer o downgrade, já que por padrão o apt escolhe os pacotes mais novos.

Primeiro devemos acertar os repositórios desejados, eu estou voltando do unstable(Sid) para o testing(Squeeze), então meu /etc/apt/sources.list ficou assim:

# deb ftp://ftp.br.debian.org/debian/ unstable main contrib non-free 
# deb ftp://ftp.br.debian.org/debian-multimedia/ unstable main

#deb ftp://security.debian.org/ testing/updates main contrib non-free
deb ftp://ftp.br.debian.org/debian/ testing main contrib non-free
deb ftp://ftp.br.debian.org/debian-multimedia/ testing main

#deb http://apt.wicd.net/ sid extras

Eu apenas comentei os "unstable" e adcionei as linhas do "testing".

Agora vamos configurar o tal "pin", para editar suas preferências do apt e dpkg você pode editar o arquivo /etc/apt/preferences, ou criar um arquivo em /etc/apt/preferences.d/ para cada configuração, no caso para o downgrade para o testing, fiz um assim:

X-comment: Force downgrade to testing.
Package: *
Pin: release a=testing
Pin-Priority: 1100

Veja que facilmente podemos criar outros, para escolher versões especificas de cada pacote, bastando acerta o "pin-priority" para isso.

Após configurado, basta atualizas a lista de pacotes e instala-los:

# dselect update
# aptitude dist-upgrade

E Pronto, seu sistema está "atualizado", é só reiniciar o X, se não mudou o Kernel nem precisa reiniciar. Se você acha que mudou muitos módulos do kernel em uso pode fazer um "depmod" e depois um "modprobe" nos módulos desejados.

Seja feliz com seu sistema "novo" :)

 

Introdução a linguagem Lua, você vai querer aprender também.

E-mail Print PDF

Em busca de uma programação poliglota, e entender as vantagens da cada linguagem oferece, iniciei meus estudos na linguagem Lua.

Histórico 

 Lua é uma linguagem de extensão, criada nos laboratórios da PUC-RJ, com o objetivo de ser simples de ser embarcada. Isso é, ele é extremamente pequena, sucinta, de sintaxe simples, esta presente praticamente em qualquer sistema. É uma verdadeira "write once, run everywhere"(bem mais que java). O pacote de Lua, com documentação, código fonte e exemplos tem cerca de 800KBs, apenas o runtime compilado(no linux) tem 150KBs. São 1700 linhas de código C portável, o mesmo código compila em várias plataformas.  

Roda em Unix, Linux, Windows, e em várias plataformas embarcadas, como celulares e setop boxes, robôs entre outros. Pode ser incluída em qualquer aplicação feita em outra linguagem , com quase nenhum overhead. Para ter melhor noção, um interpretador Lua completo em puro Java (tanto J2ME quanto J2SE), tem cerca de 150KBs. É usada como linguagem de extensão em produtos da Adobe, roda no Android, esta no Ginga (da TVDigital), e é muito usada em Jogos, como o sempre citado World of Warcraft.

E por que não fazer tudo em Lua então? Lua foi pensada em extensão de aplicativos, então a biblioteca básica é bem limitada, não possui as milhares de funções para tudo como teria em Java ou PHP ou Ruby ou Python ou Outra. Seus 150KBs incluem apenas o necessário, muito tem disponível em módulos externos, como os do LuaRocks. Embora seja possível para certas aplicações, mas não é foco.

Enfim, vendido o peixe de Lua. Agora é demonstrar, afinal “Show me the code”.

Exemplos 

Primeiro o essencial, lua é Imperativo, tem funções como cidadão de primeira classe(ah, deu para entender) e tudo é armazenado em tabelas. Tabelas são como arrays, mas são tabelas, depois eu explico. É tipagem dinamica, essencialmente não é orientada a objetos(pode ser simulado), possui escopo e é modular. Vamos ao exemplo.  

  -- rss.test.lua

local xml = dofile("xml.lua")
local sample = "<?xml ?><channel><rss><title>Lua Rock!</title>"
sample = sample .. "<item><title>Item 1</title></item>"
sample = sample .. "<item><title>Item 2</title></item>"
sample = sample .. "</rss></channel>";
local rss = xml.parse_rss(sample)
assert(rss[1].title == "Item 1","Invalid Item 1 title")
assert(rss[2].title == "Item 2","Invalid Item 2 title")
print("rss tests ok")

Esse simples exemplo é o arquivo de testes de uma biblioteca de parser de rss que uso. O uso do modificador "local" indica o escopo mais fechado possível dessa variável. O não uso de "local" implica numa variável "global", visível em toda a aplicação.  

A função "dofile" carrega um arquivo (como se fosse um include), esse arquivo carregado pode retornar uma ou mais variáveis, no caso o xml.lua me retorna uma tabela.

A chamada de função é normal, no caso o xml é uma tabela, e um dos seus índices (parse_rss) é uma função que recebe um argumento e retorna uma tabela.

  Fato interessante sobre tabelas em Lua, é que os índices numéricos começam em 1, e não em 0 como estamos acostumados.

  Em "rss[1].title", eu pego o item de índice 1(o primeiro), da tabela "rss" e o item de índice title dentro desta. No "assert" eu garanto que a expressão retorne True, do contrário levanto o erro no segundo argumento. 

  O arquivo de rss é assim: 

  -- rss.lua
local xml = dofile("utils/xml.lua")
xml.parse_rss = function (str)
local rss = {};
local t = xml.parse(str)
local channel = t[2][1]
for k,v in pairs(channel) do
local label = v['label']
if label == "item" then
local item = {}
for k,v in pairs(v) do
local label = v['label']
if label and v[1] then
item[label] = v[1]
end -- if label and value
end --for pairs in v
table.insert(rss,item)
end -- if is item
end -- for item in channel
return rss
end
return xml

 

Novamente eu carrego um parser xml externo, e na tabela xml eu adcione um índice, o parse_rss. Nesse índice eu ligo uma função, que recebe um argumento. Veja que não tem tipo fixo, eu poderia usar assert para garantir o tipo.

Eu defino então a variável “rss” como uma tabela vazia. Então faço um loop for nos itens retornados pelo parser xml. A função “pairs” retorna as chaves (k) e os valores(v) de uma tabela.

Temos então um IF padrão, nova tabela e mais um for. Então eu uso o “insert”, “table”, que é uma tabela embutida no core do lua. E retorno o RSS, o arquivo então retorna a tabela com as funções.

O parser XML é deveras grande, não vale a pena passa-lo aqui, e isso tudo foi apenas para dar um visão geral na estrutura da sintaxe da linguagem. Vamos agora no passo-a-passo de verdade.

Tutorial 

Em Lua, funções são objetos de primeira classe, então podemos por exemplo ter funções “curried”, como no exemplo abaixo:

  -- curry.lua

function soma(n)
return function(n2)
return n + n2
end
end

local f2 = soma(2)
local soma2e3 = f2(3)
assert(soma2e3 == 5)

 

Podemos levar um pouco alem:

  
-- curry.lua
local somador = function(n)
local soma = n
function f(n2)
if type(n2) == "number" then
soma = soma + n2
return f
else
return soma
end
end
return f
end

local total = somador (1) (2) (3) ()
print(total)

local somador = function (itens)
assert(type(itens) == "table")
local soma = 0;
for k,v in pairs(itens) do
soma = soma + v
end
return soma, #itens
end

local total,n = somador {
1,2,3
}
print(total,n)

local somador = function(```)
local soma = 0;
for k,v in pairs(arg)do
if type(k) == "number" then
soma = soma + v
end
end
return soma
end

local total = somador(1,2,3)
print(total)

 

São as várias formas de fazer a mesma coisa, veja no penúltimo somador uma característica legal, uma função pode retornar mais de uma variável.

Agora que você conhece como fazer funções, loops e condicionais, vamos tratar das tais tabelas.

  --tabelas.lua
local tab = {
"um","dois",
x="3",
y=function() return "hello" end
}
table.insert(tab,"cinco")
table.remove(tab,2)
local final = table.concat(tab," , ") -- apenas numéricos
print(tab[1], tab[2], tab["x"],tab.y,tab["y"](),tab[5],final)

 

Entendeu?

A ultima parte que quero tratar nesse texto é sobre coroutines, que são as “threads” do lua, incluído no core da linguagem, exemplo geral:

  --co.lua
local hello = coroutine.create(function(name)
print ("hello "..name)
end)


coroutine.resume(hello,"diogo")

local hello2 = coroutine.create(function(name)
repeat
print("hello you, "..name)
name = coroutine.yield(name)
until not type(name) == "string"
end)

local h2 = coroutine.resume(hello2,"diogo")
local h3 = coroutine.resume(hello2,"diego")
local h3 = coroutine.resume(hello2)
local h4 = coroutine.resume(hello2)

 

Acho que com esses exemplo já dá para decidir se quer ou não aprender Lua. Caso queira, o melhor lugar é a wiki da documentação de lua.

  Termino com um exemplo de uso real, uma função que realiza uma busca na wikipedia e retorna o resultado, o JSON eu achei na internet, e o http usa o Lua Socket, o wikipedia.lua.  

Last Updated on Monday, 21 September 2009 13:22
 


Page 2 of 20