Archive for the ‘perolas’ Category

Gerencie como um pr0n star!

Friday, May 15th, 2009

Se você não entendeu a piada com o título clique aqui.

Então tivemos o Scrum Gathering Brazil esta semana. Infelizmente eu não estava por lá mas acompanhei bastante a movimentação via twitter e conversando com amigos nos instant messengers da vida. Agora estou lendo a cobertura dos blogs.

A que mais me chamou atenção –e eu já previa isso tendo conversado com o autor durante a evento- foi a do Rodrigo Yoshima. Entre diversos comentários sobre apresentações que deixaram pontos de interrogação e exclamação na cabeça do autor eu destaco:

Usando Scrum com o Visual Studio Team Systeam - Fabio Camara [...]
- Ele acha incrível como a Regra de Pareto se aplica a projetos de software: 20% dos desenvolvedores fazem 80% do trabalho.
- Ele se questiona se vale a pena o programador testar. Para ele, o programador só deve verificar e um testador, que é mais barato, testa efetivamente. Na mesma linha ele questiona TDD para projetos que ele denomina “time-driven”. Não achei referências para esse termo, mas ele classifica como os projetos onde tudo é para ontem. Nesses projetos não há tempo para pensar em testes unitários.
- A maior divergência porém, é o papel do ScrumMaster na visão do Fabio Camara. Para ele o ScrumMaster Monta o Plano, Distribui Atividades, Obtém Feedback e Refaz o Plano. Ele deixou claro na palestra que essa é a opinião dele. Quando questionei a respeito da auto-organização do Scrum ele disse que também não acredita na auto-organização.

E o grande sumario disso (desculpe o hotlink, Rodrigo!):

Este é o tipo de coisa sobre a qual eu falei aqui, aqui, aqui, aqui e, principalmente, aqui.

Quanto mais as metodologias ágeis ganham o mainstream mas nós vamos ver este tipo de coisa. O fato de que Scrum possui certificações e selinhos só piora tudo já que dá credibilidade imediata a uma informação errada no seu princípio básico.

Isso me lembrou alguns casos. Uma vez uma amiga foi para um cliente que havia implantado Scrum há pouco tempo. Todos fizeram o cursinho e tinham selinho de CSM. O diretor do programa tem o selinho melhor, CSP, e estava no caminho do seu CST, o selinho máximo.

Ela é uma analista de negócios e quando chegou foi levada imediatamente para uma sala com todos os stakeholders e desenvolvedores. Eles olharam seriamente para ela e disseram algo como:

- Precisamos muito da sua ajuda. Precisamos de aconselhamento em como deixar a informação visível. Agora com Scrum nós precisamos deixar claro o que está acontecendo aqui no desenvolvimento para todos.
- Uh. Ok, então acho que vocês podem começar me explicando o processo de negócios, acho que posso ficar algumas horas vendo como vocês trabalham e como o sistema é usado. Depois queria conversar um pouco com o time de desenvolvimento, podemos fazer uma mini-retrospectiva e uma futurospectiva para tentar entender porque a comunicação é um problema. A partir daí nós traçamos um plano, pode ser necessário conseguirmos coaches técnicos e, talvez, um gerente de projetos com experiência em métodos ágeis…
- Er… ahm. Ta. Mas… não era bem isso que estávamos pensando. Sabe, nós já fizemos tudo isso. Tivemos uma grande reunião, acertamos os fluxos de trabalho e tal.
- É? Mas… pelo que eu vi conversando com pessoas durante as últimas semanas vocês ainda têm problemas, os desenvolvedores estão reclamando de que tudo muda o tempo todo, o pessoal de negócios reclama que vocês estão quinze meses atrasados…
- Sim, sim, sabemos disso tudo. Mas nós sabemos que com o Scrum eventualmente essas coisas vão se resolver, não estamos preocupados. O que nós não conseguimos entender é como otimizar a radiação de informações utilizando kanbans distribuído pelo chão de fábrica.
- “Otimizar..kanban…” peraí, vocês querem que eu ajude você a decidir onde colocar seu story wall?
- É, acho que você pode colocar deste jeito…
- Você tem alguma idéia do quanto vocês estão pagando por hora pra eu estar aqui?!?

Eventualmente o cliente percebeu que onde posicionar o story wall era o menor dos seus problemas. Um dos principais problemas deles é que estavam fazendo exatamente o que o Fabio Câmara sugeriu: tinham um Scrum Master que criava, gerenciava e ajustava o plano. Os desenvolvedores estavam sempre atrasados porque eles nem sabiam qual era o plano, apenas sabiam das atividades. Discussão típica:

- Estamos atrasados!
- Você está atrasado, meu time está em dia.
- Como assim?
- Eu falei que precisava de dois dias para colocar o back-end em produção, bom estamos terminando agora, com o mínimo de atraso.
- Mas o front-end não está pronto, qual a diferença?
- Isso é com o time do Beltrano. Nós aqui estamos certos. Sprint goal atingido, vamos para o bar.

Ou, na “obtenção de feedback”:

- Ok, esta tarefa aqui está demorando muito então vamos acabar entregando aquela ali atrasada.
- Você está dizendo que o projeto vai atrasar?!
- Não, não. Você me entendeu mal. Meu time está OK, nós vamos entregar em dia, não se preocupa não.
[dois dias depois]
- E aí, tudo certo?
- Tudo.
- Aquela tarefa ali… está meio atrasada, não?
- Não, não. Veja bem, ela já vai estar pronta… já já.
[final do sprint]
- Então, como estamos?
- Bom. Aquela tarefa ali atrasou. Isso fez com que o Fulano ficasse preso ajudando o Beltrano e não fizesse o trabalho dele. Mas não tem tanto problema porque ele não ia conseguir fazer o trabalho dele mesmo já que esta tarefa depende da outra.
- Então… o que vocês estão entregando hoje?
- O Domain Model, todas as classes no lugar. Ta pronto. Só falta testar.

A solução neste caso específico teve que ser meio drástica. O que queríamos fazer era remover todos os Scrum Master e devolvê-los a sua posição original (geralmente gerente de projetos e desenvolvedores sênior) mas vimos que isso ia causar problemas políticos demais. A solução mais viável foi manter os Scrum Masters -pelo menos o título- e usarmos “Gerentes de Iteração”. Iteration Manager é o termo que usamos para um papel equivalente ao Scrum Master –gerente de projetos é outra coisa- e estes caras atuavam como lideres dos times e gerentes de iteração.

Os gerentes de projeto -ainda chamados Scrum Masters por razões históricas- tinham ainda o “plano”, algo em extremo alto nível que dizia que considerando a situação atual de escopo e velocidade a funcionalidade X vai ser entregue dia Y, a Z dia W e assim por diante. Arrastar barrinhas no Microsoft Project não mudava o plano, ele era apenas um retrato da situação real e para mudar a situação real você tem que resolver seus impedimentos. Sem truques.

Outro problema foi o tal do testes. Nós sabemos que desenvolvedores profissionais testam mas neste cliente eles compartilhavam da idéia do Fábio de que testar é coisa pra recurso barato. Resultado? Os recursos caros ficavam dias produzindo código caro que não funcionava. Apos um sprint inteiro de código caro produzido se tinha que reescrever boa parte. Como é aquela história de “o barato sai caro mesmo”?

Nada disso, qualidade é algo muito caro para ser produzido por “recursos baratos”. Como o Jason Yip diz: controle qualidade é responsabilidade do time todo -ele sugere o termo “Inspetor de Qualidade” para o que normalmente chamamos de QA- e para isso os desenvolvedores precisam entrar na dança.

Sendo extremamente sincero, eu não consigo entender como um desenvolvedor experiente assume que uma metodologia ágil consiga funcionar sem testes. Você não tem sequer uma especificação dizendo o que vai construir!

A única maneira que eu vejo disso meio que funcionar é se ao invés de uma metodologia ágil você utilizar apenas mini-waterfalls a cada sprint. Fica um tempo especificando o que vai ser feito, um tempo fazendo, um tempo testando. Enxágüe e repita. Mas isto não é uma metodologia ágil, o ciclo de feedback é muito longo!

E este foi só um dos múltiplos exemplos que tivemos nos últimos dois anos. É preciso ter cuidado, muito cuidado. Scrum vêm crescendo muito como hype e é um framework, cheio de lacunas por definição. Quando alguém com bastante bagagem vê as lacunas no Scrum ele logo assume que basta enfiar o que já se usa em desenvolvimento “tradicional” e acaba criando um híbrido de modelos quase sempre extremante ineficiente.

Scrum não diz como desenvolver software? Sem problemas, nós sabemos fazer isso: escreve uma especificação no wiki, codifica, testa. Scrum não diz como compartilhar conhecimento sobre o código? Sem problemas, nós sabemos como fazer isso: antes do código ser enviado para o SCM ele tem que ser aprovado por um membro mais sênior do time. Scrum não diz como integrar código? Sem problemas: cada um cria seu branch e nós integramos no final do Sprint.

É bom notar que mesmo com as lacunas citadas o framework tem princípios bem definidos. A opinião de que o Scrum Master é o dono do plano vai de encontro com o que o Scrum prega. Pode ser a opinião de alguém experiente, você pode achar que faz sentido… só não pode dizer que isso é Scrum.

E se você soma isso ao fato de que não é preciso muita coisa para ter um certificado em Scrum o problema toma proporções gigantescas. Scrum em si não diz que é errado, digamos, escrever um documento de caso de uso de vinte páginas para cada item de backlog. E se, ainda por cima, a pessoa que sugeriu isso ainda possui um selinho dizendo que ele sabe Scrum?

Se você não tem um time experiente em metodologias ágeis então comece seguindo todas as práticas de XP. Após ganhar experiência decida o que funciona e o que não funciona –mas teste todas antes, e por um tempo considerável.

Não comece apenas por Scrum. Como falei antes você vai encontrar muitos buracos e sempre a solução mais fácil vai ser fazer o que já se fazia antes.

Repetindo um tema freqüente neste blog: eu posso programar FORTRAN em qualquer linguagem. Eu posso gerenciar waterfall e/ou comando-e-controle em qualquer metodologia.

Programadores Profissionais Escrevem Testes, Ponto Final.

Wednesday, October 31st, 2007

O tópico já tem oito páginas. Acho que chega à 10. Por mais que minha mão coce para comentar lá eu não vou, simplesmente porque já tive problemas demais com o pessoal do Mentawai.

De qualquer forma sempre me preocupa a possibilidade de algum desenvolvedor ler o tópico e pensar “Poxa, se esses caras que fazem todos estes frameworks não usam testes por que eu vou usar?”.

Desenvolvedores profissionais escrevem testes. Simples assim.

Uma pessoa que não ganha milhões de dólares mas escreveu uma das obras mais clássicas deste ramo deixa bem claro em sua primeira aula que programar é gerenciar complexidade. Nós precisamos gerenciar complexidade o tempo todo, por isso criamos funções, objetos e tudo mais. Não adianta, mesmo Einstein teve que provar que suas fórmulas e execuções estavam corretas, que poderiam ser verificadas. Na faculdade aprende-se isso desde as cadeiras básicas (e o fato de ser esquecido como “coisa teórica inútil” me faz novamente perguntar sobre o valor do ensino formal).

Existe uma grande diferença entre fazer Test-Driven Development e testar. TDD é sobre modelagem de objetos e especificações, não sobre testes (tanto que Behaviour Driven Development está se consolidando como algo mais eficiente que TDD) apesar de que no final você acaba ganhando uma suíte de testes de graça.

É muito difícil achar um projeto open-source relevante que não tenha testes. Na verdade os projetos decentes só aceitam um relatório de bug ou um patch se vier acompanhando por um caso de testes. Imagine uma aplicação feita colaborativamente por diversas pessoas, como saber que o que eu acabei de fazer commit não vai quebrar o que você modificou ontem? Boas práticas de orientação a Objetos? Não se iludam, OO não foi feita para este tipo de verificação! Com boas práticas você consegue minimizar o impacto de mudanças diminuindo dependências mas você não vai ter certeza disso.

Eu sinceramente não sei que técnica é essa que faz programação defensiva evitar testes. Eu já li bastante sobre Orientação a Objetos e programação defensiva e não vi nada deste tipo, pelo menos não vindo de uma fonte com um mínimo de credibilidade. Um exemplo simples, imagine que o framework web imaginário Pagai possui um código parecido com este:


Acao acaoSendoExecutada = controladorPrincipal.acao(requisicao.acaoDesejada());

Simples, não? Agora imaginemos que o código do método acao(String) seja algo assim:


public Acao acao(String pathInvocado){
//verifica se acao possui o formato desejado, deve ter uma barra e deve ter dois itens separados por barra apenas
if((pathInvocado.indexOf("/") == -1) || (pathInvocado.split("/").size < 2)) throw new IllegalArgumentException("Path invocado ["+pathInvocado+"] nao possui o formato adequado (consulte a documentacao XYZ)");
//lógica...
}

Isso é programação defensiva: eu não estou aceitando o que me passam, eu verifico se é o que deveria e se for eu continuo, se não eu paro ali mesmo e deixo alguém tomar conta do problema, seja a classe em questão ou alguma outra mais acima.

Imagine que eu por engano commitei um código que utilize “” em vez de “/” nesta requisição. Se for numa parte central do código é bem possível que uns testezinhos peguem mas imagine que é utilizado apenas em um caso específico e que, por um acaso, eu baseei meu sistema de controle de jatinhos particulares 9meu chefe tem muitos jatinhos) nele. Quando eu fiz o comit não alertou. Quando eu fiz o build não alertou. Quando eu fiz meus testezinhos não alertou. Quando foi para a produção eu tive erro.

Ok, acontece. Programadores de qualquer tipo cometem erros. Eu vejo o problema muito rapidamente e o corrijo, temos uma versão beta em 15 minutos no ar, fantástico. Aí daqui há um mês outro programador comete o mesmo erro. Quando fizer o build não vai alertar. Quando fizer seus testezinhos não vai alertar. Quando for para a produção… Isso não é profissionalismo.

O que eu preciso é de uma suite de testes, unitários e de integração, que me digam que o sistema está incorreto já no processo de build, sem lançar jars beta, alfa ou gama.

Mas se tem um argumento nessa história toda que realmente me irrita é quando as pessoas dizem que “num mundo capitalizado não há tempo para testes” ou que “o cliente não quer saber como é feito, ele quer que funcione”. O cliente realmente não quer saber como funciona, ele quer que funcione. Mas ele também não vai querer saber que você alterou uma classe que usava barra para barra invertida e tudo parou de funcionar, ele quer que o problema não aconteça e se acontecer que seja corrigido rapidamente. Se seu sistema não tem qualidade -e testes fazem parte de qualidade- você não consegue isso. TI gasta fortuna das empresas reescrevendo sistemas simplesmente porque não foram feitos por profissionais, e profissionais se preocupam com a qualidade do que fazem. E isso inclui testes.


Não seja um amador.

Testando Constantemente

Thursday, June 28th, 2007

O Guilherme Chapiewski e eu vivemos hoje um diazinho de cão. Ao contrário do que muitos pensam, aqui no trabalho nós temos algumas dezenas de sistemas, todos necessários para o processo de criação, codificação, decodificação e oferta de vídeos na Internet. É coisa pra caramba. E um destes sistemas é um legado de três anos, em vias de se aposentar, que todas as pessoas da empresa já passaram por, mas ninguém é dono ou admite que tem código seu ali. Eis que após uma subida para produção o sistema apresenta lá seus problemas. Nada funciona.

Neste cenário caótico, após quase 10 horas de crise, alguém acaba achando um daqueles trechos de código que fazem você querer ter virado sacerdote em vez de desenvolvedor. Um arquivo de constantes Strings. E alguém resolve fazer algo como:


if(resultSet.getString("USUARIO_TXT").equals(Constantes.PARAMETRO_ADMINISTRADOR){
facaTudoDeMaisImportanteQueOSistemaFaz();
}

Que já é uma pérola por si só, mas não bastante isso o conteúdo da constante é ainda mais legal:


public static Constantes.PARAMETRO_ADMINISTRADOR = "Usuário Administrador Básico";

Percebeu algo errado? Acentos! Primeira regra de hoje:

  • Se você precisa de acentos no código fonte, numa literal String ou algo do tipo, sempre escape os acentos.

Por quê? Porque a possibilidade de alguém corromper seus acentos com um encoding diferente é enorme. No nosso caso identificamos nos logs co CVS o momento exato em que um desenvolvedor fez checkout do arquivo, alterou outros arquivos e fez o commit dele no meio dos legitimamente alterados. O arquivo passou de ISO para UTF-8 (que aliás, é o padrão do departamento) nesta operação e todas as Strings com acentos viraram coisas aleatórias. Como as Strings do banco não foram alteradas a comparação acima falhava miseravelmente e o resultado foi um sistema dando problemas em produção e dez horas de trabalho para descobrir isso.

Ainda falta uma medida básica de segurança neste exemplo: testes unitários. Se você é do time que não acredita em testes unitários, um simples teste em JUnit poderia pegar o problema na hora da geração do build que foi para produção. A menos que déssemos o azar de que todas as classes que envolvem esta constante tenham sido alteradas o teste ia falhar e acusar o erro.

Ah, mas e se dermos este azar e o teste unitário não pegar? Teste de integração. Com um servidor de integração contínua você faz com que a cada commit seu código seja baixado, compilado, testado unitariamente e, no final, seja feito um teste que envolve outras partes. O Fit é ótimo para isso.

Não julguem o processo ou ambiente mal: existem responsáveis pela homologação do sistema e eles cumpriram seu papel. Infelizmente não é viável testar manualmente todo o sistema para saber que uma mudança na ponta de cá causou uma mudança acidental na ponta de lá, ainda mais com um sistema deste histórico.

O problema é que ao contrário do que é senso comum testes não são apenas parte da homologação. testes são parte de todo o ciclo de desenvolvimento, tanto na criação como na manutenção de produtos. Ou isso ou você faz como eu e perde sua quinta-feira.

Seria Cômico se não fosse…real

Monday, May 7th, 2007

O Hugo Vidal me mandou um mail sobre seu novo projeto: http://www.codecomics.com.

codecomics

A idéia é simples: quadrinhos feitos pelo próprio com textos rápidos e precisos sobre desenvolvimento de software. Fantástico.

Comendo Exceções com Farinha

Wednesday, November 1st, 2006

Há alguns meses eu passei por dias bem corridos. Precisávamos fazer a entrega de um grande produto e, como sempre, tudo resolve acontecer nos últimos dias, resultando numa lista de bugs que precisam ser corrigidos. O maior problema desta lista era um bug aparentemente simples, um include JSP que não funcionava. Acotnece que este código foi herdado de uma famosa empresa indiana CMM nível 5 e, como tal, está uma porcaria.

Como não havia tempo para refatorar o sistema (diria que 90% dele precisava mudar, isso caracteriza reescrita ou ainda posso chamar de refactoring?), tivemos que trabalhar com o que tínhamos em mãos. E o que tínhamos em mãos era: enderecodosistema.empresa.com.br, o endereço do próprio servidor. Essa era aúnica mensagem de erro, na verdade era algo assim que aparecia no log:

javax.servlet.ServletException: enderecodosistema.empresa.com.br
at atg.portal.framework.taglib.RenderPreparedGearTag.doStartTag()
at jsp_servlet._templates._claclacal._html.__full._jspService()
at weblogic.servlet.jsp.JspBase.service()V(Optimized Method)
at weblogic.servlet.internal(Optimized Method)
...

Detalhe que o erro só ocorria no servidor de produção, justo o que não podíamos manipular sem preecncher 15 formulários em várias vias. Após olhar o código (cada mais fundo que eu ia mais palavrões soltava e minha cara de espanto atraía os transeuntes) eu percebi que o sistema era baseado num padrão de projeto muito famoso em empresas, principalmente as consultorias com CMM, chamado “Vamos-Comer-Esta-Exceção-Com-Farinha”.

O código era mais ou menos assim (claro que isso era copiado e colado algumas milhares de vezes por todo o código, modularidade para quê?):


try{
algumaCoisaQualquer();
}
catch(Exception e){
String msg = e.getMessage();
throw new BussinesRuleException(msg);
}

Muito bom! Nossa mensagem simplesmente podia ser QUALQUER coisa. O tipo da exceção foi perdido, a stacktrace foi perdido… a única coisa que ficou foi o CMM nível 5.

Solução? Primeiro tentamos adicionar mais debugging. Isso podia dar certo mas ia demorar uma semana para conseguirmos colocar o sistema em produção com um log decente (i.e. StackTraces), fora o tempo de correção após termos descoberto o que acotnecia. Como o problema só ocorria em produção, um bom ponto de partida seria verificar se tudo que está neste servidor está em outros (o pessoal de infra sempre diz que tá, maaaas…).

Compara daqui, compara de lá e… dezenas de biblitoecas com versões diferentes. Uma coisa interessante é que haviam duas versões do Jalarta Commons HttpClient, removemos a versão anterior, consolidamos todas as bibliotecas, configurações e DataSources e… nada!

Após a derrota na hipótese das versões de bibliotecas, estava almoçando com meu chefe enquanto fazíamos uma chamada para os gerentes que podiam autorizar nossa versão com log melhorado ir para produção quando me deu um estalo. Ora, se tem HTTP client neste sistema e se a mensagem de erro é o hostname… ELE ESTA TENTANDO FAZER UMA CONEXÃO HTTP LOOPBACK! Acontece que o sistema estava em pré-produção, logo seu DNS não estava registrado. Aquela exceção só podia ser algo do tipo new HostNotFoundException("enderecodosistema.empresa.com.br");.

Relendo todo o código, suspeita confirmada. Uma linha no /etc/hosts e o sistema estava pronto para entrar em produção.

Agora, por que raios ele se conectava a ele mesmo? Lendo direito eu percebi que um dos programadores CMM nível 5 utilizava uma JSP para gerar um arquivo XML que era transformado via XSLT em HTML. Ou seja: ele precisava se conectar novamente para dar um GET na página JSP que retornava o arquivo! Ele usava uma tecnologia utilizada para criar HTML (JSP) apr agerar um XML que era transformado em HTML!

Qualquer API de XML meia-boca vai te dar um método que retorna o XML gerado como uma String mas acho que nosso amigo CMM nível 5 não sabia ler JavaDocs em inglês.

Eu poderia tentar concluir com uma reflexão sobre o design de aplicações, umas dicas básicas para trabalhar com XMl em uma aplicação web ou sei lá o que, mas em vez disso eu vou terminar com uma lição simples: cuidado com as mensagens das suas exceções, você nunca vai saber quando uma consultoria CMM nível 5 vai utilizar seu código.

Faça sua mensagem de exceção contêr pelo menos alguma coisa de útil caso não haja stacktraces nem o tipo da exceção esteja disponível. Eu sei que no caso reportado o problema não foi da API (afinal, HostNotFoundException: “host not found enderecodosistema.empresa.com.br” é, no mínimo, prolixo) mas pense que nem todas as pessoas que vão usar seu código são programadores, alguns são apenas CMM nível 5.

Windows Inovando Como Sempre…

Tuesday, January 24th, 2006

Essa é imperdível :)