terça-feira, 16 de dezembro de 2014

Trabalhando nas nuvens, integrando o SDK da AWS para S3 com PHP

Olá pessoal. Nesse artigo vamos mostrar algo que anda sendo bem utilizado no dia a dia dos desenvolvedores em geral, que é a integração com a nuvem. Nesse caso em específico com os percusores dela a toda poderosa Amazon.
Legal, mas ai você pergunta o que é o S3?
Aqui vai uma pequena descrição:
"O Amazon S3 é o armazenamento para a internet. Ele foi projetado para facilitar a computação de escala na web para os desenvolvedores.
O Amazon S3 fornece uma interface simples de serviços da web que pode ser usada para armazenar e recuperar qualquer quantidade de dados, a qualquer momento e de qualquer lugar na web. Ele concede acesso a todos os desenvolvedores para a mesma infraestrutura altamente escalável, confiável, segura, rápida e econômica que a Amazon utiliza para executar sua própria rede global de sites da web. O serviço visa maximizar os benefícios de escala e poder passar esses benefícios para os desenvolvedores." (http://aws.amazon.com/pt/s3/)
Pois bem, por onde eu começo a fazer a integração?
A Amazon desenvolveu um SDK PHP para todos os serviços da AWS sendo assim, vamos utilizar esse client para desenvolver nossa integração.
Talvez você esteja dizendo nesse momento "Vai ser díficil integrar esse SDK no meu framework, será que não existe um client da S3 feito por ele?". Bem minha resposta sobre isso é que existe sim, no meu caso eu fui fazer a integração em um sistema legado que foi feito em Zend Framework 1.12 e então pensei em utilizar o client desse framework "Full Stack", e o que eu conclui depois de 1 dia integrando é que eu NÃO devo utilizar esse client extremamente descontinuado e com vários metódos não implementados. A verdade é que a Zend reconheceu quando lançou o ZF2 que não são eles que devem fornecer esse client, pessoas especializadas nisso já vão fazer, deixa o pessoal focado em Amazon cuidar disso, e tem mais, com o composer tudo fica mais fácil então relaxa :).
"Pow, mas composer no ZF1? Por que não? Basta adicionar a vendor no autoload e toca o barco".

Claro que a proposta desse artigo não é falar sobre arquitetura de sistema pq se fosse eu provavelmente não utilizaria o meu legado e partiria para outra abordagem. Mas a questão aqui é que eu precisava em pouco tempo alterar a implementação nesse sistema legado, que utilizava as funções de file do php e fazia a persistencia dos arquivos em uns diretorios no mesmo servidor da aplicação (DEUSSS PERDOE QUEM NÃO IMPLEMENTOU UMA APLICAÇÃO FLEXIVEL O BASTANTE, NÃO CONHECIAMOS AS NUVENS).

Pois bem então a primeira abordagem no meu caso foi colocar o composer no ZF1 e isso foi algo bem simples, em 2 minutinhos eu ja tinha tudo funcionando com o SDK prontinho para meu framework utilizar.


continua...

segunda-feira, 8 de setembro de 2014

Iniciando com o Docker

Acredito que precisamos estar ligados em tudo aquilo que acontece no mundo da TI, precisamos ser cuidadosos com as novidades mas acima de tudo ter uma opinião bem fundamentada sobre as coisas. Eu comecei esse post com essa frase pois tenho passado por um processo profissional em que tenho conhecido muita coisa nova (principalmente aquilo que se refere a ferramentas para escalabilidade), sempre que posso eu ainda leio sobre qualidade de código, design e arquitetura até porque, é disso que eu gosto e acredito que seja meu minha melhor qualidade. Mas, como eu já disse precisamos estar ligado no mundo e pensando nisso vou tentar iniciar uma serie de posts (não quero prometer nada) em que eu falo sobre ambiente de desenvolvimento, tanto em dev como live. A principio eu queria ter uma versatilidade em meus ambientes de desenvolvimento sem estar muito atrelado a uma unica máquina, e ai eu fui pesquisar sobre a Vagrant que, é uma forma de virtualizar um ambiente bem feito, mas que no fim das contas é muito pesado para aquilo que eu preciso fazer e para meu hardware em alguns momentos. Foi então que no PHP Conference 2013 eu vi a grande figura Elton Minetto falando sobre Docker, ele deu apenas uma pincelada mas já me interessou ir pesquisar pois a proposta dele me pareceu bem interessante. Mas espera ai, qual é a proposta dele afinal?

Segundo o próprio site o Docker é uma plataforma aberta para aplicativos distribuídos para desenvolvedores e administradores de sistemas.  Ele é uma abstração, que adiciona recursos e simplifica o uso dos linux containers (LXC), que são uma forma de isolamento de processos e sistemas, é quase uma virtualização, porém mais leve e integrada ao host. Linux-only. O Docker te permite criar pequenas aplicações chamadas de "containers", que isolam o Sistema Operacional base e toda a pilha de dependência de sua app de forma leve em espaço e consumo. Muitas pessoas dizem que ele é o Vagrant para produção pois são VMs muito leves, que podem rodar em cima de outras VMs. Imagina o seu uso? Podemos aplica-lo em diversas aplicações com ambientes diferentes (apache, nginx, tomcat...) em uma mesma maquina ou vm e sem perder muito em recursos.


Alem de resolver o nosso problema em ambientes dev/live ele tem mais(tipo vendedor hein). O Docker trabalha com um sistema de arquivos empilhaveis, que permite que os passos para configuração do container funcione de forma incremental. Tipo os o versionamento do git/mercurial. Então imagine o processo, atualizou uma lib: commit. Mudou a versão do php: commit, terminou uma nova versão: Tag. E depois de tudo isso é só dar um push, temos uma atualização compartilhada dentro das pessoas que participam do seu projeto ;) .



Ok, estou convencido o Docker é fóda! Como eu começo?

Antes de começar, o Docker é para Linux então, se vc não usa linux vai ter que virtualizar ;)
1º Instalando

No meu caso, eu estou usando o Ubuntu 14.04, então é mais do mesmo, instale o docker.io via apt-get e crie um link para usar docker, caso vc queira usar a ultima versão sempre de uma olhada aqui:

$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
2º Em seguida, adicione a chave do repositório Docker para o seu chaveiro local.
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
3º Agora adicione o repositório Docker ao seu sources list, atualize e instale o pacote lxc-docker 
$ sudo sh -c "echo deb https://get.docker.io/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker
4º Adicioner seu usuario no grupo do docker
Assim vc nao vai precisar ficar fazendo sudo docker lalala.
sudo gpasswd -a myusername docker

5º Autentique-se no docker hub (se n tem conta crie uma aqui)

docker login

6º Suba um container do docker que eu fiz com php-fpm e nginx em sua maquina, a primeira vez que vc rodar esse command vai demorar um pouco pois será feito um pull da imagem.

docker run -v /var/www:/usr/share/nginx/www:rw --expose=80 --dns=127.0.0.1 -i -t pvgomes/php /bin/bash

Preste atenção em algumas coisas desse commando, primeira fazemo um docker run (executar o container) depois passamos um diretorio /var/www fazendo um link com /usr/share/nginx/www e dando premissão de leitura e escrita (rw), isso significa que vamos fazer um link de um path do container com a sua máquina (assim na configuração do nginx apontariamos para /share/nginx/www/seuprojeto), depois expomos a porta 80 e passamos o dns. Pronto vc tem um container do docker rodando :)

Meu objetivo nesse post foi apenas introduzir o Docker, no próximo vamos passar a utilizar o container de fato.

Valeu!


terça-feira, 8 de abril de 2014

Processo de desenvolvimento de software de maneira simples

Fala pessoal tudo bem? Hoje vou ser bem clássico pois vou falar de um assunto que envolve parte seu conhecimento universitário e parte o seu conhecimento na prática. Para aqueles que só tem a teoria eu recomendo a prática e para os analistas desenvolvedores da prática eu recomendo uma pausa para a leitura de hoje que é sobre o "processo de desenvolvimento de sofware".

Ok mas como eu defino o processo de desenvolvimento de software?


O processo de desenvolvimento de software é entre outras definições um conjunto de ações parcialmente ordenadas, com a finalidade de obter um sistema informatizado. Ele é estudado principalmente na área de Engenharia de Software, sendo considerado um dos principais mecanismos para a entrega de um sistema coeso que atenda as necessidades de seus usuários. A qualidade e velocidade para entregar um software é determinante dentro dos estudos da engenharia de software, mas não se engane ela não é uma métrica exata.

Dentro do processo do desenvolvimento de software existem diversas etapas e vou falar um pouquinho de cada uma que são:

1 - Análise de requisitos
2 - Especificação
3 - Arquitetura de Software
4 - Implementação
5 - Testes


OBS: Saiba que com o movimento ágil utilizando SCRUM e XP esse processo não necessáriamente é tão burocrático pois o manifésto agil prega a agilidade (Recomendo fortemente essa leitura aqui sobre o manifesto agil).


Ainda assim o processo clássico não será descartado e vamos mostrar suas responsabilidades.


1 - Análise de requisitos

Quando se trata do entendimento dos requisitos para um sistemas sendo uma parte importante do processo de projeto de sistemas, no qual o analista de negócio, aliado com outros participantes de software identificam as necessidade ou requisitos de um usuario. 
Uma vez que os requisitos do sistema tenham sido identificados, os projetistas de sistema (entenda-se o carinha que vai pensar no business) estarão preparados para projetar a solução.
Existe a divisão de requisitos sendo Requisito funcional e Requisito não-funcional, esta parte do processo o analista faz as primeiras entrevistas com os clientes e/ou usuários do software para conhecer as funcionalidades do sistema que será desenvolvido. Mas atenção é aqui que acontece a maior parte dos erros, pois a falta de experiência dos clientes ou usuários faz com que eles nem sempre tenham claro em sua mente quais funcionalidades o software necessita.

A grande questão da analise de requisitos é: como como saber se as necessidades do domínio do sistema foi captada? O objetivo dessa fase é justamente levantar os requisitos e garantir o amadurecimento deles, gosto muito de adicionar o básico diagrama de classes da UML nessa fase pois pelo menos eu consigo ter algo "palpavel" rsrs. Pois bem já deu para perceber que essa fase é imprescindível não é? E depois disso como eu começo a pensar no meu "ecosistema"?.


2 - Especificação

A especificação é a definição do que se espera que um software faça. Ela pode ser informal, neste caso ela pode ser considerada como um blueprint ou manual de usuário do ponto de vista do desenvolvedor, ou formal, no caso de ela ser definida principalmente em termos matemáticos ou programáticos.

Na prática, as especificações mais bem sucedidas são escritas para a compreensão e ajustes em uma aplicação que já se encontra bem desenvolvida, embora sistemas de sistemas de segurança críticos sejam cuidadosamente especificados antes do desenvolvimento da aplicação. Especificações são mais importantes para interfaces externas que devem permanecer estáveis. Aqui na especificação é que acontece o tão "famoso" prototípo que costumam chamar de fase de prototipação, sinceramente não curto muito essa montagem "coxinha" da especificação pois na minha opinião usando UML e criando pequenos wireframes já conseguimos abordar muita coisa, e como eu disse antes as coisas devem ser feitas em pequenos trechos, imagine que vc vá desenvolver um e-commerce vão não vai especificar TUDO não é? melhor começarmos pelo catalogo, depois carrinho, logística do armazém e etc, assim garantimos mais exatidão na hora da entrega :D.


3 - Arquitetura de Software

A arquitetura de software é a fase que o desenvolvedor da as cartas, claro que se pensarmos no Domain Driven Design o desenvolvedor participa de TUDO, mas veja bem, é aqui que ele decide os componentes de software, sua regras básicas internas, suas propriedades externas, e seus relacionamentos com outros softwares. Essa fase tem como objetivo manter o sistema organizado no quesito estrutural e comportamental, garantindo que os dados tratados pelo software tenham comportamento coeso e definido, permitindo também mudanças lógicas sem afetar seu funcionamento. A arquitetura de software é necesserária para definir padrões e o design de uma aplicação, é aqui por exemplo que iriamos falar de Hexagonal Architecture, mas não vou falar sobre isso hoje pois eu me alongaria muito e tbm n tenho conhecimentos soloidos sobre isso rs.

Vou pegar um trecho que escrevi no segundo ano da faculdade sobre a arquitetura de software (que trabalho para copiar do caderno kkkkkk)
"O campo da ciência da computação tem lidado com problemas associados, como a complexidade da informação, desde sua criação. Os primeiros problemas de complexidade foram resolvidos pelos desenvolvedores através da escolha da estrutura de dados, do desenvolvimento de algoritmos e pela aplicação de conceitos de separação de escopos. Embora o termo arquitetura de software seja relativamente novo na indústria, os princípios fundamentais deste campo vêm sendo aplicados esporadicamente pela engenharia de software desde o início dos anos 80. As primeiras tentativas de capturar e explicar a arquitetura de software do sistema foram imprecisas e desorganizadas – freqüentemente caracterizadas por um conjunto de diagramas. Durante o decorrer da década de 90 houve um esforço concentrado para definir e codificar os aspectos fundamentais desta disciplina. Inicialmente um conjunto de padrões de projeto, estilo, melhores práticas, descrição de linguagens, e lógica formal foram desenvolvidas durante este período."


4 - Implementação

Analistas falem o que for essa é a parte mais PICA de todas, todo software é escrito em uma linguagem de programação, embora seja possível, com alguma dificuldade, escrevê-lo diretamente em linguagem de máquina. Diferentes partes de um programa podem ser escritas em diferentes linguagens, diferente do que o processo de software comum prega nessa fase também testamos o nosso código como prega o processo TDD 
"TDD é o desenvolvimento de software orientado a testes. Entenda mais detalhes e como usá-lo! TDD é o desenvolvimento de software orientado a testes, ou em inglês, Test Driven Development. Mas mais do que simplesmente testar seu código, TDD é uma filosofia, uma cultura.".

Diferentes linguagens de programação funcionam de diferentes modos. Por esse motivo, os programadores podem criar programas muito diferentes para diferentes linguagens; muito embora, teoricamente, a maioria das linguagens possa ser usada para criar qualquer programa.
Há várias décadas se debate se a programação é mais semelhante a uma arte (Donald Knuth), a uma ciência, à matemática (Edsger Dijkstra), à engenharia (David Parnas), ou se é um campo completamente novo. Ao meu ver desenvolvimento é uma mescla de arte com engenharia mas isso é minha opinião.

Para alguma tecnologias OPEN SOURCE o desenvolvedor precisa fazer tudo, TUDO mesmo, subir ambiente, banco de dados, então eu acredito que essa fase precisa de MUITA mas muita atenção e cuidado.

5 - Testes

O teste de software é a maneira de verificar a qualidade do fotware em relação ao contexto em que ele deve operar. Isso inclui o processo de utilizar o produto para encontrar seus defeitos.
O teste é um processo realizado pelo testador de software, que abrange outros processos da engenharia de software, e que envolve ações que vão do levantamento de requisitos até a execução do teste propriamente dito.
Segundo a DEVMEDIA:
Teste de software é o processo de execução de um produto para determinar se ele atingiu suas especificações e funcionou corretamente no ambiente p$paymentFormara o qual foi projetado. O seu objetivo é revelar falhas em um produto, para que as causas dessas falhas sejam identificadas e possam ser corrigidas pela equipe de desenvolvimento antes da entrega final. Por conta dessa característica das atividades de teste, dizemos que sua natureza é “destrutiva”, e não “construtiva”, pois visa ao aumento da confiança de um produto através da exposição de seus problemas, porém antes de sua entrega ao usuário final” 

Existem alguns conceitos básicos associados ao teste de software que são: defeito, erro e falha.
A figura 1 expressa a diferença entre esses conceitos. Defeitos fazem parte do universo físico (a aplicação propriamente dita) e são causados por pessoas, por exemplo, através do mal uso de uma tecnologia. Defeitos podem ocasionar a manifestação de erros em um produto, ou seja, a construção de um software de forma diferente ao que foi especificado (universo de informação). Por fim, os erros geram falhas, que são comportamentos inesperados em um software que afetam diretamente o usuário final da aplicação (universo do usuário) e pode inviabilizar a utilização de um software.

Existem alguns conceitos bem conhecidos de teste que são;

A - Caixa Branca
Também chamada de teste estrutural ou orientado à lógica, a técnica de caixa-branca avalia o comportamento interno do componente de software. Essa técnica trabalha diretamente sobre o código fonte do componente de software para avaliar aspectos tais como: teste de condição, teste de fluxo de dados, teste de ciclos, teste de caminhos lógicos, códigos nunca executados.
Os aspectos avaliados nesta técnica de teste dependerão da complexidade e da tecnologia que determinarem a construção do componente de software, cabendo portanto avaliação de mais aspectos que os citados anteriormente. O testador tem acesso ao código fonte da aplicação e pode construir códigos para efetuar a ligação de bibliotecas e componentes. Este tipo de teste é desenvolvido analisando o código fonte e elaborando casos de teste que cubram todas as possibilidades do componente de software. Dessa maneira, todas as variações relevantes originadas por estruturas de condições são testadas.
Um exemplo bem prático desta técnica de teste é o uso da ferramenta livre JUnit para desenvolvimento de classes de teste para testar classes ou métodos desenvolvidos em Java. Também se enquadram nessa técnica testes manuais ou testes efetuados com apoio de ferramentas para verificação de aderência a boas práticas de codificação reconhecidas pelo mercado de software. A aderência a padrões e boas práticas visa principalmente a diminuição da possibilidade de erros de codificação e a busca de utilização de comandos que gerem o melhor desempenho de execução possível. Apesar de muitos desenvolvedores alegarem que não há ganhos perceptíveis com essa técnica de teste aplicada sobre unidades de software, devemos lembrar que, no ambiente produtivo, cada programa pode vir a ser executado milhares ou milhões de vezes em intervalos de tempo pequenos. É na realidade de produção que a soma dos aparentes pequenos tempos de execução e consumo de memória de cada programa poderá levar o software a deixar de atender aos objetivos esperados. A técnica de teste de caixa-branca é recomendada para as fases de teste de unidade e teste de integração, cuja responsabilidade principal fica a cargo dos desenvolvedores do software, que por sua vez conhecem bem o código fonte produzido.

B - Caixa Preta
Também chamada de teste funcional, orientado a dado ou orientado a entrada e saída, a técnica de caixa-preta avalia o comportamento externo do componente de software, sem se considerar o comportamento interno do mesmo.4 Dados de entrada são fornecidos, o teste é executado e o resultado obtido é comparado a um resultado esperado previamente conhecido. Como detalhes de implementação não são considerados, os casos de teste são todos derivados da especificação.
Quanto mais entradas são fornecidas, mais rico será o teste. Numa situação ideal todas as entradas possíveis seriam testadas, mas na ampla maioria dos casos isso é impossível. Outro problema é que a especificação pode estar ambígua em relação ao sistema produzido, e como resultado as entradas especificadas podem não ser as mesmas aceitas para o teste. Uma abordagem mais realista para o teste de caixa-preta é escolher um subconjunto de entradas que maximize a riqueza do teste. Pode-se agrupar subconjuntos de entradas possíveis que são processadas similarmente, de forma que testar somente um elemento desse subconjunto serve para averiguar a qualidade de todo o subconjunto. Por exemplo, em um sistema que aceita um inteiro como entrada, testar todos os casos possíveis pode gerar pelo menos dezenas de milhares de casos de testes distintos. Entretanto, a partir da especificação do sistema, pode-se encontrar um subconjunto de inteiros que maximizem a qualidade do teste. Depende do propósito do sistema, mas casos possíveis incluem inteiros pares, inteiros ímpares, zero, inteiros positivos, inteiros negativos, o maior inteiro, o menor inteiro.

Essa técnica é aplicável a todas as fases de teste – teste unitário, teste de integração, teste de sistema e teste de aceitação. A aplicação de técnicas de teste leva o testador a produzir um conjunto de casos de teste (ou situações de teste). A aplicação combinada de outra técnica – técnica de particionamento de equivalência (ou uso de classes de equivalência) permite avaliar se a quantidade de casos de teste produzida é coerente. A partir das classes de equivalência identificadas, o testador construirá casos de teste que atuem nos limites superiores e inferiores destas classes, de forma que um número mínimo de casos de teste permita a maior cobertura de teste possível.
Uma abordagem no desenvolvimento do teste de caixa-preta é o teste baseado na especificação, de forma que as funcionalidades são testadas de acordo com os requisitos. Apesar de necessário, esse tipo de teste é insuficiente para identificar certos riscos num projeto de software

C - Unitários

Fase em que se testam as menores unidades de software desenvolvidas (pequenas partes ou unidades do sistema). O universo alvo desse tipo de teste são as subrotinas ou mesmo pequenos trechos de código. Assim, o objetivo é o de encontrar falhas de funcionamento dentro de uma pequena parte do sistema funcionando independentemente do todo. Para as linguagens de programação mais sofisticadas existem os chamados frameworks xUnit, criados com o intuito de facilitar e padronizar os testes de unidade, normalmente o prefixo é substituido por alguma identificação da linguagem como por exemplo PhpUnit para PHP, jUnit para java, entre tantos outros, fornecem a estrutura para os testes e também podem criar métricas de cobertura de teste.


D - Teste de Integração
Na fase de teste de integração, o objetivo é encontrar falhas provenientes da integração interna dos componentes de um sistema. Geralmente os tipos de falhas encontradas são de transmissão de dados. Por exemplo, um componente A pode estar aguardando o retorno de um valor X ao executar um método do componente B; porém, B pode retornar um valor Y, gerando uma falha. Não faz parte do escopo dessa fase de teste o tratamento de interfaces com outros sistemas (integração entre sistemas). Essas interfaces são testadas na fase de teste de sistema, apesar de, a critério do gerente de projeto, estas interfaces podem ser testadas mesmo antes de o sistema estar plenamente construído.

E - Teste de Sistema
Na fase de teste de sistema, o objetivo é executar o sistema sob ponto de vista de seu usuário final, varrendo as funcionalidades em busca de falhas em relação aos objetivos originais. Os testes são executados em condições similares – de ambiente, interfaces sistêmicas e massas de dados – àquelas que um usuário utilizará no seu dia-a-dia de manipulação do sistema. De acordo com a política de uma organização, podem ser utilizadas condições reais de ambiente, interfaces sistêmicas e massas de dados.

F - Teste de Aceitação
Geralmente, os testes de aceitação são realizados por um grupo restrito de usuários finais do sistema, que simulam operações de rotina do sistema de modo a verificar se seu comportamento está de acordo com o solicitado. Teste formal conduzido para determinar se um sistema satisfaz ou não seus critérios de aceitação e para permitir ao cliente determinar se aceita ou não o sistema. Validação de um software pelo comprador, pelo usuário ou por terceira parte, com o uso de dados ou cenários especificados ou reais. Pode incluir testes funcionais, de configuração, de recuperação de falhas, de segurança e de desempenho.


Pois bem amiguinho,  basicamente o desenvolvimento de software segue esses processos, dúvidas, sugestões ou críticas é só falar!

quinta-feira, 13 de março de 2014

Seminário PHP: Show me The Code!

Se alguém ainda acessa meu blog para acompanhar artigos sobre desenvolvimento aqui vai um convite para um evento em Porto Alegre - Rio Grande do Sul , sobre qualidade de software. O evento é promovido pela Tempo Real Eventos e tem o nome de "Show me The Code" e vai acontecer no dia 12 de abril de 2014.

Ontem (dia 12 de Março) fizemos um Hangout com alguns palestrantes falando sobre o evento, o video segue abaixo: