Archive for IN PORTUGUESE
PyConBrasil 2008 e Rails Summit Latin America, eu vou!
September 10th, 2008 • IN PORTUGUESE
Tags: eventos, python, rails
PyConBrasil 2008
Na semana que vem marcarei presença na PyConBrasil 2008. Essa é a 4ª edição do evento que cresce de ano em ano.
Vai ser uma boa oportunidade para conhecer profissionais que só conheço virtualmente, além de aprender um pouco mais sobre Zone, Plone, DJango, entre outras tecnologias relacionadas a Python.
Meu principal interesse nesse evento é trocar idéias sobre desenvolvimento para aparelhos móveis, que anda bem quente na comunidade de Python.
Rails Summit Latin America
Na semana do meu aniversário (mais precisamente no dia do meu aniversário), estarei na Rails Summit Latin America.
Um evento desse porte já estava sendo esperado pela comunidade brasileira faz algum tempo. A cada nova versão da RailsConf, era um sofrimento para os desenvolvedores Rails que não tinham oportunidade de comparecer ao evento.
Agora chega ao Brasil um evento de grande porte, nos moldes da famosa RailsConf. Será sem dúvida uma boa oportunidade para exibir ao mundo a comunidade brasileira que se formou em volta do famoso framework para Ruby.
Meus principais interesses nesse evento são conhecer gente que só conheço virtualmente, trocar idéias sobre melhores práticas de desenvolvimento utilizando Ruby on Rails, e desenvolvimento de ferramentas. O evento contará com um espaço para que desenvolvedores se unam para desenvolver o que desejarem. Com certeza estarei por lá para propor um monte de idéias e programar!
Nos vemos por lá ![]()
[off-topic] Jaime Lerner talking about sustainable cities
September 5th, 2008 • IN PORTUGUESE
Tags: empreendedorismo, off-topic, sustentabilidade
Jaime Lerner, famoso ex-prefeito de Curitiba deu um show no TED.
O video é relativamente antigo, mas vale cada segundo. Da aula, ficam os ensinamentos:
1) Trabalhe rápido e coloque algo no ar logo. Quanto mais tempo você demorar, mais chances tem de falhar e acabar não lançando nada.
2) A criatividade começa quando você corta um ou dois zeros do seu orçamento.
Effective Scaffold for Rails
September 3rd, 2008 • IN PORTUGUESE
Tags: generators, rails, scaffold
Generators são importantes ajudantes na maneira como desenvolvemos aplicações Ruby on Rails. Facilitam muito o trabalho, além de agilizar tarefas repetitivas.
Scaffold é um generator bastante conhecido, principalmente por railers iniciantes. Através deste é possível criar toda a sistemática de um CRUD para a sua aplicação
Algum tempo atrás, o script padrão foi alterado para o scaffold RESTful, que quando utilizado gera toda a estrutura para um CRUD RESTful.
Porém, nem todo o código gerado é utilizado. Um bom exemplo disso são as chamadas RESTful envolvendo XML. Caso os recursos da sua aplicação devam se comunicar em XML pode ser interessante utilizar o scaffold para gerar este código, porém a grande maioria das aplicações utilizam somente a interface HTML. Não oferecem nenhum tipo de API de acesso aos dados. Com isso o código gerado pelo scaffold - para comunicação via XML - fica inutilizado, porém ativo. Servindo apenas para cair no esquecimento e servir de acesso a usuários maliciosos atrás de alguma vulnerabilidade do seu sistema.
Nos meus últimos projetos em Ruby on Rails, percebi que eu já não utilizava mais o scaffold, para evitar o excesso de código gerado e diminuir as minhas preocupações com segurança.
Resolvi então criar o meu próprio generator, baseado nas minhas necessidades. E só agora tive tempo para publicá-lo no Github.
Para instalar é muito simples:
script/plugin install git@github.com:felipemesquita/effective_scaffold.git
Para utilizar o generator:
script/generate effective_scaffold MODEL
Espero que possa ser útil a você. Sinta-se a vontade para adaptá-lo conforme suas necessidades.
RubyOnda Widget
August 31st, 2008 • IN PORTUGUESE
Bruno Miranda e Roberto Soares desenvolveram o RubyOnda, um website onde a própria comunidade pode contribuir com as últimas novidades sobre Ruby, Rails, e diversas outras tecnologias relacionadas.
Resolvi então colaborar um pouco, e desenvolvi um pequeno widget para o site. Com isso, agora é possível embedar as últimas notícias do RubyOnda no seu próprio site, basta que adicione a instrução abaixo:
< script src="http://rubyonda.com/widget-embedded.js" type="text/javascript">
Aparecerá assim na sua página:
A doce ilusão da alta cobertura em testes
August 28th, 2008 • 1 comment IN PORTUGUESE
Tags: tdd, tests
Há tempos atrás - quando eu trabalhava em grandes empresas de desenvolvimento de software - tinhamos em nosso workflow a prática de enviar nossos códigos para a equipe de QA realizar uma “extensa” bateria de testes. O código que passava nos testes era considerado de qualidade. Para os que não passavam, os programadores responsáveis eram alertados sobre a vulnerabilidade e tinham a missão de corrigí-los.
Lembro-me de participar de reuniões por motivos de falha encontrada no sistema após a entrada em produção. Os motivos de existir a falha eram estudados e na grande maioria das vezes, os testers acabavam sendo apontados como culpados por “não terem realizados testes suficientes”. Não me lembro de presenciar nada sobre “fazer testes ruins”, testes que em si, pouco testavam.
Após a expansão de TDD e dos frameworks que permitiram automatizar testes, medir a cobertura em testes de um determinado projeto foi uma evolução natural para quem utiliza testes automatizados. Diversas ferramentas, para diversas linguagens/plataformas, começaram a aparecer e a facilitar a monitoração deste indicador.
Porém, tenho visto em alguns projetos, que o índice de cobertura em testes tem sido encarado como um fim, ao invés de uma consequência. Valores para o índice de cobertura em testes tem sido estipulados no início do projeto, e o código - consequentemente a equipe - passa a ser encarada como “de qualidade”, caso mantenha o valor inicialmente estipulado.
Coincidentemente - ou não - alguns códigos de testes desses projetos não são tão bem escritos. Testam pouca coisa, ou absolutamente nada. Mas mesmo assim, a avaliação que o código recebe é de “auto grau de qualidade”, já que apresenta um elevado índice de cobertura em testes.
Resolvi então, escrever alguns exemplos para ilustrar esse post. No trecho abaixo, temos uma classe NumberUtil, que possui 2 métodos: 1) humanize_array - onde dado um array é retornado um outro array, porém com os números em forma de string - por extenso; 2) humanize - onde dado um número retorna a sua string - por extenso;
Olhando atentamente ao trecho acima, percebemos que existe um bug na linha 10. Isso faz com que dado o número 1, a string retornada seja “zero”.
Logo em seguida temos a sua classe de teste, chamada NumberUtilTest. Esperamos que essa classe possua uma boa cobertura em testes para que possa identificar o problema no trecho anterior.
Os dois métodos de NumberUtil são testados, a cobertura está boa, mas se executarmos os testes, nenhuma falha é apresentada. Exatamente o contrário do que imaginávamos, já que existe um bug na classe.
Isso acontece porque o método test_should_humanize_array não está bem escrito. Existe uma falha básica nele, que faz com que não identifique o bug. Ele deve esperar o valor “one” ao invés de “zero”, já que a primeira posição do array dado, tem valor 1.
Temos aqui um bom exemplo de alta cobertura em testes, mas com pouca qualidade em código, já que os testes não identificam um blug relativamente simples.
Outros tipos de falha em sistema, ocorrem por falta de implementação, falta de código. Isso é realmente mais difícil de ser capturado em testes automatizados. Vamos dar uma olhada no trecho a seguir:
Acima temos uma classe chamada Person, onde o programador esqueceu de retirar o comentário em uma validação para o atributo username. Isso faz com que, mesmo que nenhum valor para username seja informado, o objeto será salvo no banco de dados.
Vamos então verificar a sua classe de teste, chamada PersonTest.
Podemos verificar que o método test_should_create_person realiza um teste simples para a criação de um objeto Person, sem informar valor para o atributo username. Esse teste será executado com sucesso, mesmo que não seja desejável ter um objeto Person sem username preenchido.
Para isso, o mais interessante seria termos uma classe de teste um pouco mais robusta, conforme podemos visualizar abaixo:
Acima, testes são realizados para identificar falhas em código existente e em códigos não existente.
Com base nesses exemplos simples, podemos verificar que ter um alto índice em cobertura em testes não é razão para ter um código de qualidade escrito.
Fixar valores para esse indicador, não fará com que código de qualidade seja escrito. É preferencial que a escrita do bom código seja estimulada, assim como bons testes. Com isso, a alta cobertura em testes se apresentará como consequência e não como fim.
Tenho certeza que você já se deparou com código de teste mal escrito. Código que no final das contas, nada ou pouco testava. Caso tenha esse exemplo, mande para mim
Envie para o meu e-mail (fmesquitacunha @ gmail), cole o código no Gist ou Pastie e me mande a URL. Ou ainda, faça um post no seu blog e link para cá. Quem sabe consigo fazer uma série sobre *Testes que nada testam* ![]()
Pilares para o sucesso de aplicações web
August 21st, 2008 • 1 comment IN PORTUGUESE
Tags: aplicacoes-web, produtos
Saber o que faz com que alguns produtos tenham mais sucesso que outros não é das tarefas mais simples. Na maioria das vezes, eles possuem basicamente as mesmas características, parecem oferecer as mesmas sensações, mas mesmo assim, uns são mais aceitos que outros.
São pequenos detalhes que passam despercebidos que fazem a diferença entre a receptividade de um produto ser maior entre os demais concorrentes.
Usuários quando questionados do porquê utilizam um produto e não outro, muitas vezes se encontram sem respostas para tal.
Posso me tomar como um exemplo. Utilizo aplicações web diariamente para gerenciar projetos, para me comunicar, para me organizar sobre o que será feito no meu dia-a-dia e para diversas outras coisas. E afirmo, existem excelentes opções de aplicações web para todas essas necessidades.
Elas não possuem muitas funcionalidades diferentes entre si. Basicamente fazem o que se propõem a fazer, variando apenas na maneira como fazem. Se é uma aplicação de gerência de projetos, controla tarefas, o que foi finalizado, o que está em andamento, etc. Todas fazem isso, variando apenas no como fazem.
Então o que leva a uma aplicação web ser tão mais divulgada do que outras do mesmo contexto? O que possuem de tão diferente dos seus concorrentes, que faz com que grande parte dos usuários as prefiram?
Jesse James Garrett escreveu um bom livro onde ele cita os elementos básicos da experiência do usuário. Ele menciona que o sucesso do produto não está só relacionado ao exterior, a como ele se apresenta. O autor defende que o processo de desenvolvimento de um produto é tão importante para o sucesso do mesmo, quanto o trabalho após o lançamento. O sucesso começa internamente, dentro da própria equipe que o constrói, que o elabora.
E para isso, ele defende que 9 disciplinas são de extrema importância para o desenvolvimento de aplicações web de sucesso.

1 - User Research: Projetar focado no seu usuário significa entender o que o seu usuário precisa, como pensa e se comporta. É importante também incorporar o que foi aprendido, sobre os usuários, dentro de todos os aspectos do seu processo.
2 - Site Strategy: Aqui é sobre definição de metas. Sobre a importância de possuir metas para sua aplicação web e sobre saber medir corretamente para que possa ser avaliado se a aplicação está cumprindo ou não com as metas pré-estabelecidas. Essa tarefa pode ser extremamente complicada.
3 - Technology Strategy: Aplicações web são tecnologicamente complexas. É importante estabelecer uma estratégia de tecnologia para sua aplicação, como: plataforma, padrões, tecnologias e como estas podem trabalhar em conjunto.
4 - Content Strategy: Conteúdo é a razão principal pelo que o usuário utiliza a sua aplicação web. Mas qual conteúdo oferecer para satisfazer as expectativas dos usuários? Quanto de conteúdo? E de que forma? Antes de você produzir conteúdo você precisa fazer esses questionamentos.
5 - Abstract Design: Arquitetura de Informação e Design de Interação são disciplinas importantes para expressar em um framework conceitual, a experiência final do usuário. Essas duas disciplinas já possuem seu valor reconhecido dentro de um processo de desenvolvimento de uma aplicação web.
6 - Technology Implementation: Desenvolver sistemas é uma tarefa dificil e envolve muito trabalho. Linguagens, protocolos, bancos de dados, testes, tudo precisa bem trabalhado. Quanto mais complexo for sua aplicação web, mais complexo será sua plataforma tecnológica.
7 - Content Production: Saber qual conteúdo você precisa não é o suficiente. Você precisa saber como produzi-lo.
8 - Concrete Design: Aqui você precisa determinar os detalhes específicos da interface, navegação, posições, disposição das informações e o design. Isso é fundamental para o produto final.
9 - Project Management: Esta disciplina é um elo de ligação para todas as outras. É importante manter em dia o gerenciamento de projeto para o desenvolvimento de sua aplicação web. Assim como manter atualizada técnicas de gestão.
Raramente dentro das empresas possuímos profissionais diferentes para cada disciplina, geralmente possuímos profissionais que ficam responsáveis por mais de uma disciplina. Não há problema nisso. Mas precisamos estar atentos se estamos aplicando essas disciplinas no desenvolvimento de nossas aplicações web.
Independente do tamanho da empresa, se é uma grande empresa de Internet ou uma startup, o mínimo de planejamento é necessário para que seja bem aproveitado o investimento para o desenvolvimento de um novo produto.
Sobre testes e TDD
January 11th, 2008 • 2 comments IN PORTUGUESE
Tags: tdd
Muito tem se falado e se escrito sobre a realização de testes no processo de desenvolvimento de software. Bastante coisa interessante vem acontecendo neste cenário e isso é muito interessante, pois testes são de extrema importância para a qualidade de software.
Automatizar testes (sejam eles unitários, de integração ou aceitação) é uma tarefa que tem se tornado cada vez mais simples devido aos frameworks de testes e ferramentas que oferecem suporte para os mesmos. As IDEs estão cada vez mais completas e possuem suporte para integração com os frameworks, o que facilita e agiliza o ato de testar software. Também temos as ferramentas de integração contínua, que podem ser configuradas para trabalhar em conjunto com os frameworks de teste, o que torna a automação bastante completa.
Uma sigla já bem conhecida e divulgada no cenário de desenvolvimento de software é TDD. Test Driven Development (TDD) significa guiar o desenvolvimento de software através de testes. Na prática, primeiro é escrito o teste para que posteriormente seja escrito o código que vai atender a determinada funcionalidade. O teste valida se o código está em conformidade com a funcionalidade que se propõe implementar, caso esteja, diz-se que o código passou no teste, caso contrário, não. Ou seja, após definir qual funcionalidade será implementada, escreve-se um teste onde o código que passe neste teste estará, consequentemente, implementando a funcionalidade. Diversos autores já escreveram sobre TDD, dando sua importante colaboração para o cenário de desenvolvimento de software.
Porém, em minha opinião, vejo na TDD uma “técnica” muito mais importante para o design de software do que propriamente para testes. Tendo como objetivo escrever código que passe em um teste, muitas vezes o desenvolvedor “se vê obrigado” a utilizar técnicas de programação que diminuem o acoplamento entre classes e que cada classe e seus métodos tenham seus papéis muito bem definidos, fazendo com que cada teste específico possa ser realizado sem a preocupação de testar outras tantas funcionalidades. Com isso técnicas como refactoring e dependency injection acabam sendo amplamente aplicadas, o que torna o design limpo e coeso.
Mas com todo esse movimento em torno de testes de software e TDD, algumas coisas tem se confundido. Testar software é executar os diversos testes em cima de código escrito. Ou seja, depois de escrito uma determinada funcionalidade, executa-se os testes e checa-se o resultado. Caso o código escrito tenha passado nos testes diz-se que está em conformidade com a funcionalidade que se propõe a implementar, livre de bugs, e apto à produção. TDD é desenvolvimento guiado por testes, ou seja, a partir de testes se escreve código.
Quando utilizamos TDD consequentemente testamos software, e isso é bom! Aplicando TDD garantimos um design limpo, coeso, e ao executar os testes efetivamente testamos o software, logo temos as duas abordagens sendo utilizadas. Mas não necessariamente quem testa software faz TDD. Nem mesmo quem automatiza teste necessariamente faz TDD. Um exemplo que tenho visto bastante é de equipes que escrevem código e depois os testes para atestar a qualidade do código anteriormente escrito. Isso não é TDD. Pode até parecer que não existe diferença entre escrever o código e depois o teste ou o teste depois o código, já que o importante é o teste existir, mas é como eu disse anteriormente, TDD não está só relacionado a teste está relacionado a design. E, em minha opinião, está muito mais relacionado a design do que a teste. Quando se escreve um teste antes do código, a intenção no momento em que vai se escrever o código é de passar no teste, e a intenção do teste é aplicar regras para que a funcionalidade seja implementada e que esteja correta.
Hoje pela manhã li um bom post escrito por Uncle Bob, onde ele comenta sobre testes gerados automaticamente e TDD. Testes que são gerados automaticamente, são gerados a partir de código escrito! E se o código foi escrito antes do teste, não foi feito TDD. Isso não invalida o que foi feito, afinal, foi aplicado um teste, porém não foi feito TDD.
Concluindo, TDD para mim está muito mais relacionado a design do que a testes, já que o design é feito de maneira diferente quando se aplica TDD do que quando simplesmente se realiza testes depois do código escrito.
Abaixo um pequeno trecho do post que mencionei do Uncle Bob.
In TDD, programmers state their intent twice; once in the test code, and again in the production code. These two statements of intent verify each other. The tests, test the intent of the code, and the code tests the intent of the tests. This works because it is a human that makes both entries! The human must state the intent twice, but in two complementary forms. This vastly reduces many kinds of errors; as well as providing significant insight into improved design.
Using a test generator breaks this concept because the generator writes the test using the production code as input. The generated test is not a human restatement, it is an automatic translation. The human states intent only once, and therefore does not gain insights from restatement, nor does the generated test check that the intent of the code was achieved. It is true that the human must verify the observations, but compared to TDD that is a far more passive action, providing far less insight into defects, design and intent.
É basicamente isso, espero que tenham gostado do meu primeiro post ![]()
