Como priorizar as tarefas de um projeto ágil

100 trilhões de dólares do Zimbábue
100 trilhões de dólares do Zimbábue

Trabalho e ensino outros a trabalharem com Scrum desde 2010. Independente das empresas adotarem ou não a metodologia ágil mais utilizada (e com mais cases de sucesso conhecidos) no mundo, sempre há o que aprender com seus métodos inusitados e com a cultura que permeia este mundo ágil em geral. Um dos pontos-chave em qualquer projeto, seja com Scrum ou não, é a priorização de tarefas, tema do post de hoje.

Alguns especialistas que conheço dizem que basta perguntar ao cliente o que ele quer e depois, o que ele quer primeiro.

Pergunte ao seu usuário e/ou cliente tudo o que ele quer no software e você terá uma pilha de documentos com vários centímetros de altura e dezenas (talvez centenas) de páginas. Depois pergunte à ele o que é mais importante e ele vai lhe responder que tudo é importante. Pergunte o que é mais urgente e ele vai te responder que tudo é urgente. Esqueça, isso não funciona. Pelo menos dessa forma tão direta não.

Como fazer então?

Cortando o escopo

Simplesmente nunca teremos tempo hábil (e nem faz sentido) desenvolver tudo o que o cliente acha que precisa no software. Principalmente na primeira versão (já ouviu falar em MVP?) e é o seu dever ensinar isso a ele.

Gerentes de projeto tem de lidar com escopo, custo e prazo nos projetos. Dificilmente conseguimos equilibrar essas três variáveis e, na minha opinião, escopo é a que faz mais sentido cortar. Não apenas porque manter um equilíbrio nessa balança de três pratos é quase utópico mas porque é o mais inteligente a se fazer, pensando no sucesso do projeto como um todo.

Jason Fried fala no seu livro Getting Real que é melhor fazer meio-software do que um software meia boca. E eu concordo com ele.

É no escopo onde temos sempre a maior quantidade de desperdício em um projeto. E desperdício aumenta os custos e estoura os prazos, simples assim. A Toyota passou a GM com seu método Lean focando em apenas uma coisa: reduzir o desperdício.

Mas como reduzir o desperdício de escopo?

Princípio de Pareto

Use o Princípio de Pareto ou a “regra do 80/20”, como muito bem apontada por Tim Ferriss em seu best-seller Trabalhe 4h por semana. Pareto determina uma relação de 80/20 ou simplesmente maioria/minoria que é aplicada há muitas coisas em nosso cotidiano. Por exemplo, 80% do uso de um software se dá em apenas 20% das funcionalidades.

Isso quer dizer que apenas 20% de tudo que for desenvolvido será utilizado realmente. O restante cairá no esquecimento.

Scrum enfatiza o foco na geração de valor para o cliente a cada entrega e a chave para geração de valor é reduzir o desperdício priorizando muito bem o que deve ser DONE em cada Sprint. Ok, dentro do Scrum isso é uma tarefa para o Product Owner, mas se você leu até aqui é porque de alguma forma está envolvido com as decisões de produto também, certo?

Atualmente trabalho em um banco e como todo banco, temos alguns processos e projetos inchados, burocráticos e cheios de desperdícios. Alguns são culpa do Banco Central, outros são culpa nossa mesmo.Algumas vezes parece que Agile e Lean jamais andarão de mãos dadas com a palavra banco, mas essa é a minha função lá e tem sido um trabalho bem interessante.

Cito o case do banco pois lá eu tenho cuidado da priorização de tarefas para os times de desenvolvimento, além das minhas atribuições normais como Scrum Master. Um app de cartão de crédito, por exemplo, é cheio de features, por mais que pareça algo simples como comprar-e-pagar. É troca de senha, de data de vencimento, aviso de viagem, solicitação de mais limite, ajuste do limite atual, etc. Se deixar a equipe de negócio se empolga e quer um Nubank pronto em duas sprints. Quem nunca passou por isso?

Minha estratégia neste projeto foi bem simples: priorização. Não vamos entregar um Nubank em duas sprints, mas consegui priorizar as features baseado no que agregaria mais valor ao cliente o mais rápido possível. Assim, em três sprints teremos um app de cartão funcional com os 20% de features que trazem 80% dos benefícios. E sim, nós vamos entregar, pois falta apenas uma das três sprints e já estamos com boa parte das funcionalidades essenciais prontas.

Conhecendo seu produto

Mas como saber o que é mais prioritário dentre centenas de features que aparecem no backlog todos os meses?

O jeito mais óbvio é conhecendo o seu produto, o seu time e entendendo o seu mercado. Óbvio que isto não é algo simples de se alcançar e existem diversos outros fatores que impactam na priorização. Se você está lançando uma versão nova de um produto, olhar o que os usuários realmente usam na sua aplicação pode ajudar bastante a decidir o que deve entrar ou não em uma nova versão. Se está lançando um novo produto, tente entrevistar usuários de produtos concorrentes, vai lhe ajudar a entendê-los e fazer algo superior à concorrência.

Quais são as dores do seu usuário? Priorize o que “dói mais”. Se o que o usuário mais reclama é de não ter um bom limite de crédito nos cartões concorrentes, foque em fazer uma análise de crédito automatizada, eficiente e que forneça um crédito condizente com a realidade (e histórico) de cada cliente. Permitir que ele escolha a cor do seu cartão pode ficar pra depois.

O quê seu usuário mais utiliza no dia-a-dia? Entregue primeiro o que ele espera como “mínimo viável” em produtos do seu nicho. Se o usuário consulta o limite disponível no cartão todos os dias, mas apenas viaja para o exterior anualmente, o que você acha que deve ser feito primeiro: consulta de limite ou aviso de viagem? Se seu usuário troca de senha do cartão apenas uma vez por ano (no máximo), mas paga faturas todos os meses, qual funcionalidade deve ser o foco nas primeiras entregas?

Este tipo de raciocínio, sem muita técnica, ajuda bastante a priorizar o que é realmente importante e deve ser posto na frente em um projeto de software.

Buy a Feature Game
Buy a Feature Game

Buy a Feature Game

Obviamente existem diversas técnicas que podem ser utilizadas pra fugir do “achismo” e até mesmo lidar com conflitos de egos que muitas vezes irrompem em reuniões para priorização de backlog. Vou falar da minha favorita: a técnica Buy a Feature Game,  que é bem simples, lúdica e eficiente.

Primeiro, escreva as histórias ou features do seu projeto em cards e deixe-os todos espalhados em uma mesa. Não traga qualquer feature aqui, apenas aquelas que já estão no roadmap próximo e/ou são minimamente importantes ao projeto. Cada card postado na mesa deve ser lido, com a atenção de todos. O ideal é que cada card possua um “preço” também, que pode ser a estimativa de horas para desenvolvimento ou os story points, mas se não estiver tudo estimado, não invalida a dinâmica, apenas reduz um pouco a sua eficiência.

Para cada um dos envolvidos na priorização (de 4 a 7), geralmente stakeholders ou até mesmo usuários, entregue à eles um maço de notas falsas, tipo Banco Imobiliário. Se todas as tarefas estiverem estimadas e com “preço”, some os preços, divida o valor pelo número de participantes e distribua esta quantia em notas para cada participante (poucas notas grandes, muitas notas pequenas).

O dinheiro da dinâmica pode ser apenas post-its com os valores escritos ou dinheirinho de brinquedo, à venda em bazares. Apenas não permita a fabricação de dinheiro falso ao longo da dinâmica nem injeção ou lavagem de dinheiro aproveitado de outras dinâmicas. 🙂

Já se não estiver tudo estimado mas se você estiver trabalhando com story points ou horas e já souber quanto o seu time entrega por sprint, divida essa quantia entre os participantes em notas, seguindo aquela mesma lógica do Banco Imobiliário (poucas notas grandes, muitas notas pequenas). Você pode jogar o B-a-F Game uma vez para várias sprints, por exemplo, somando a capacidade das sprints na hora de distribuir as notas.

Se suas sprints são de 15 dias e você entrega 30 pontos em cada sprint, você pode priorizar uma vez a cada 30 dias, emitindo 60 pontos de notas para os participantes, por exemplo. Para que os valores não fiquem muito limitados, sugiro multiplicar story points por $10 ou até $100 mesmo, enquanto que horas geralmente não possuem esse problema.

Sem nenhuma regra, cada participante pode depositar o seu dinheiro sobre cada card, representando o seu interesse e/ou o quanto aquela feature vale a pena ser implementada. Aqui, cada um terá a sua própria percepção de prioridade, mas como o dinheiro é limitado, eles serão obrigados a trabalhar com esta limitação na hora de distribuir as notas.

Esta limitação de dinheiro ilustra bem as limitações reais de um projeto como a verba, as horas-homem, etc. Ajuda os stakeholders a “sofrerem” com as decisões difíceis que o gerenciamento de um projeto exige. Caso seus cards possuam outras limitações, como precedência, crie combos de produtos do tipo “para comprar esse, tem de comprar o outro primeiro”.

Quando todos terminam sem dinheiro (deixe que discutam e troquem as notas de lugar até o final da dinâmica), basta somar quanto cada card recebeu e os que receberam mais dinheiro são os mais prioritários. Opcionalmente, se estiver trabalhando com as estimativas, uma feature só vira de fato prioridade se ela recebeu um valor mínimo equivalente ao valor necessário para sua compra.

Se uma feature exige 100h de desenvolvimento, ela não entrará na próxima sprint se não alcançar $100 de ‘doações’ dos stakeholders, por exemplo.

Permita uma pequena discussão sobre o resultado da distribuição de notas logo após exibir os cards que se mostraram mais prioritário (i.e. que receberam mais $). Isso tende a gerar algumas movimentações de capital, o que é perfeitamente normal, mas ao término da sessão, o que ficou definido é o que será utilizado como prioridade do backlog e orientará os times nas próximas semanas.

Obviamente que nenhum método é perfeito, mas assim como o Planning Poker, este método baseia sua eficácia no consenso entre os envolvidos no projeto e o conhecimento que cada um tem do produto e do mercado para priorizar de uma maneira caótica, mas organizada.

E aí, o que achou desta técnica? Conhece alguma outra? Compartilhe nos comentários!

Quer saber mais sobre desenvolvimento ágil de software? Clique no banner abaixo e conheça o meu livro.

Webscrapping com Node.js: Parte 2

Este artigo é uma continuação do Webscrapping com Node.js que escrevi no início de outubro. Crawlers e webscrappers são peças fundamentais para a construção de mecanismos de busca e já há algum tempo que estava para escrever sobre eles a pedido de leitores e amigos.

Isso porque crio tais bots há uns 7 anos, desde que comecei o projeto do Busca Acelerada pela primeira vez e de lá para cá não parei, tendo lançado diversos projetos para diversas empresas (como o BuildIn para a Softplan), e até mesmo alguns projetos pessoais (como o SóFamosos).

Mas por que uma parte 2? Não ensinei tudo que tinha de ensinar na parte 1?

O grande problema do webscrapping

Quase. O webscrapper que ensinei a criar na primeira parte deste artigo é bem básico e sofre de alguns males bem comuns que quem já deve ter feito webscrapping antes deve conhecer: HTML dinâmico e execução de scripts.

Claro, existem outros problemas também, como o bloqueio do bot após crawling excessivo, mas considerando que quase a totalidade dos sites atuais possuem execução de scripts para tornar suas páginas dinâmicas, é quase certo que você mais cedo ou mais tarde terá problemas com o seu webscrapper enxergando um HTML x e você no navegador enxergando um HTML y, o que dificultará seu trabalho de capturar os dados corretamente.

Explicando melhor: quando você acessa um site via servidor, usando um script como o webscrapper do post anterior, você não executa o código front-end da página, não manipula o DOM final, não dispara as chamadas Ajax, etc. O seu robô apenas lê as informações que foram geradas no servidor do site-alvo, o que pode fazer com que seu robô nem tenha nada de útil pra ler na página caso a mesma se construa usando Ajax.

A solução: Headless browsers

Para contornar este problema usamos um tipo especial de browser chamado headless (“sem cabeça”).

Os browsers web como conhecemos possuem 3 tarefas principais:

  • dada uma URL, acessar uma página HTML (funcionalidade principal, o tronco do browser);
  • carregar o DOM e executar os scripts front-end (os membros);
  • renderizar visualmente o DOM (a cabeça);

Os primeiros browsers antigos, que eram em modo texto, só faziam o primeiro item. O browser que você está usando pra ler este post faz os três. Um headless browser faz somente os dois primeiros, ou seja, ele apenas não possui uma interface gráfica, mas carrega o HTML, o DOM e executa todos os scripts de front-end.

Esse tipo de browser é como se fosse um console application rodando em modo silencioso, apenas um processo no seu sistema operacional que age como um browser. No fundo ele é um browser, apenas não tem UI.

Muito útil para testes automatizados de interface, é comum os headless browsers exporem bibliotecas de manipulação do DOM como JQuery para permitir que através de scripts o programador consiga usar a página carregada pelo headless browser, como executar cliques em botões, preencher campos, etc; tudo isso sem estar enxergando uma UI ou sequer estar usando mouse e teclado.

Não é preciso ser um gênio para entender que podemos usar headless browsers para fazer webscrapping, certo? Com esse tipo de tecnologia conseguiremos que nosso bot leia a versão final do HTML, da mesma forma que um usuário “veria” no navegador, após a execução dos scripts de front-end. Não apenas isso, mas você consegue fazer com que seu bot não apenas leia conteúdo, mas que use a página em si, clicando em botões e selecionando opções, por exemplo.

Se DOM, HTML, front-end e outros termos utilizados aqui não forem de seu domínio, dificilmente você conseguirá criar um crawler realmente bom. Em meu livro de Programação Web com Node.js, cubro estes e outros aspectos essenciais da programação web, caso te interesse.

Escolhendo um headless browser

Existem diversas opções de headless browsers no mercado. A maioria é open-source e baseada no Webkit, a mesma base na qual o Apple Safari e o Google Chrome foram construídos, o que garante uma grande fidelidade em relação ao uso de web browser comuns para carregar o HTML+JS.

Algumas opções disponíveis são:

Destes, o SlimerJS usa a plataforma Gecko da Mozilla ao invés do Webkit, enquanto que o PhantomJS e o HtmlUnit são famosos por se integrarem ao Selenium, uma popular ferramenta de automação de testes. Além disso, o Phantom é o único que eu usei profissionalmente em uma startup que trabalhei que usava este headless browser para tirar screenshots de páginas web.

No entanto, meu intuito de escrever este post era justamente para aprender a usar outro headless browser que não o Phantom, pois este possui alguns problemas conhecidos como não-conformidade com ES6, obrigatoriedade de uso do JQuery e nenhuma novidade desde 2016 (o projeto está parado). Esses problemas (que não são o fim do mundo, mas que me motivaram a buscar outra tecnologia) são comentados neste excelente post do Matheus Rossi. Então se você realmente quer aprender a usar o PhantomJS, leia o post que acabei de citar.

Uma coisa que descobri recentemente é que desde a versão 59 do navegador Google Chrome que foi disponibilizada a opção de rodar o navegador do Google sem a interface gráfica funcionando, em modo headless. Usar o Chrome em modo headless é o sonho de muito testador por aí, pois representa rodar scripts de testes automatizados no navegador mais popular do mundo, com a maior fidelidade possível em relação ao que o usuário final vai usar.

Certo, headless browser escolhido, como fazer um webscrapper que use-o para carregar o mesmo DOM que um usuário do Chrome veria?

Manipulando o headless browser via Node.js

No mesmo Github do Google Chrome existe um projeto chamado Puppeteer, que em uma tradução livre seria um manipulador de marionetes, ou um mestre dos fantoches. Ele é essencialmente um módulo Node.js que permite manipular tanto o Headless Chrome quanto o Chrome “normal” para fazer tarefas como:

  • gerar screenshots e PDFs de páginas web;
  • fazer crawling em cima de páginas com Ajax e SPAs;
  • automatizar o uso de UIs web;
  • fazer webscrapping com alta fidelidade;

Para que o Puppeteer funcione você precisa ter o Node.js versão 8+ instalado na sua máquina. Depois que tiver o Node instalado, vamos criar um novo projeto Node.js chamado webscrapper2, criar um index.js vazio dentro dele, navegar via terminal até essa pasta e rodar um ‘npm init’ para configurá-lo com as opções default.

Se você nunca programou em Node.js antes, sugiro começar pelos tutoriais mais iniciantes de meu blog ou mesmo pelo meu livro, que pega o iniciante pela mão e ensina desde JS tradicional até diversos módulos do Node.

Agora rode o comando abaixo para instalar o Puppeteer no seu projeto, sendo que ele automaticamente irá baixar sua própria versão do Chrome, independente se você já possuir uma (ou seja, a instalação irá demorar um pouco mais que o normal para módulos NPM):

Usá-lo é muito simples, no seu index.js, inclua o seguinte código que representa a estrutura básica do nosso webscrapper:

Na primeira linha carregamos a dependência do módulo puppeteer. No bloco seguinte, criamos a função assíncrona que fará todo o trabalho de verdade, com a lógica de acesso à página e scrapping (comentado).

Neste primeiro momento, essa função scrape apenas executa o Headless Chrome, acessa uma nova página com a URL de um site fake de livros e espera 1 segundo antes de se fechar. Ainda não há a lógica de scrapping aqui.

No bloco final, executamos a função e quando ela terminar, o valor retornado pela função scrape será impresso no console.

Antes de fazer a versão completa da função scrape, temos de entender o que vamos capturar de informações da página em questão.

Fazendo HTML Scrapping

O site Books to Scrape serve para o único propósito de ajudar desenvolvedores a praticar webscrapping. Ele mostra um catálogo de livros, como na imagem abaixo:

Books to Scrape
Books to Scrape

Acesse ele no seu navegador Chrome e com o clique direito do mouse sobre a área do primeiro livro da listagem, mais especificamente sobre o título dele e selecione a opção Inspecionar/Inspect.

Isso irá abrir a aba Elements do Google Developer Tools onde você poderá entender como construir um seletor que diga ao seu web scrapper onde estão os dados que ele deve ler. Neste caso, vamos ler apenas os nomes dos livros. Se você não está acostumado com CSS e/ou seletores (no melhor estilo JQuery), você pode usar o recurso Copy > Selector que aparece no painel elements para gerar o seletor para você, como mostra a imagem abaixo.

Copiando o selector
Copiando o selector

Nesse caso específico não usarei a sugestão do Chrome que é bem engessada. Usarei um seletor bem mais simples: “h3 > a”, ou seja, vou pegar o link/âncora de cada H3 do HTML dessa página. Os H3 dessa página são exatamente os títulos dos livros.

Se analisarmos em detalhes este bloco que queremos extrair o título, veremos que o texto interno da âncora nem sempre é o título fiel pois, por uma questão de espaço, algumas vezes ele está truncado com reticências no final. Sendo assim, o atributo HTML que vamos ler com o scraper é o title da âncora, que esse sim sempre possui o título completo.

Vamos atualizar nosso código de scrapping para pegarmos esta informação:

Analisando apenas o bloco de código de scrapping, criamos uma função que executa um código JavaScript sobre a página que carregamos. A execução de scripts é realizada usando a função evaluate. Nesse código JavaScript, estamos usando a função querySelector no documento e o seletor que criamos anteriormente para acessar um componente do DOM da página. Sobre este componente, queremos o seu atributo title.

Se você rodar este código Node agora verá que ele retornará apenas o nome do primeiro livro, “A Light in the Attic”. Isso porque a função querySelector retorna apenas o primeiro componente que ela encontra com aquele seletor.

O código abaixo resolve isso:

Aqui, usei a querySelectorAll, sobre a qual apliquei um forEach. Para cada livro encontrado com aquele seletor, eu adiciono o title do livro em um array de livros, retornado ao fim do evaluate.

Com isso, se você executar novamente este script verá que ele retorna o título de todos os livros da primeira página do site, concluindo este post.

Qual seria o próximo passo? Navegar pelas demais páginas, coletando os títulos dos outros livros. Esta é a tarefa principal de um webcrawler ou webspider, to crawl (rastejar). Ao algoritmo de webscrapping cabe apenas coletar os dados.

Até a próxima!

Curtiu o post? Que tal aprender mais sobre como criar aplicações incríveis usando Node.js? Então clica no banner abaixo e dá uma conferida no meu livro sobre programação web com Node.js!

Lançamento do meu livro de MongoDB


Foi em 2015 que conheci MongoDB. Sim, eu estava bem atrasado considerando que a tecnologia havia sido lançada em 2009 e desde 2010 já existiam grandes projetos usando-a. Como sempre gostei de criar aplicações com massas grandes de dados, como meus mecanismos de busca, logo me interessei pelo approach baseado em documentos do Mongo e facilidade de consultar. E pela performance, é claro.

Assim como fiz em 2012, conforme ia iniciando meus estudos de Android, fui documentando tudo o que aprendia e testava sobre MongoDB, ao mesmo tempo que estudava e aplicava outra tecnologia em meus projetos: Node.js.

Obviamente não comecei meus estudos partindo do zero, uma vez que já trabalho com sistemas que usam bancos de dados há cerca de 10 anos. Todo o meu conhecimento de banco de dados (que engloba muito SQL Server e um pouco de outros bancos), aliado às boas práticas de Engenharia de Software, Gestão de Projetos, Testes de Software, etc formaram o profissional que sou hoje.

No uso de MongoDB eu tenho experiência de mais de dois anos na data que escrevo este post e uma meia dúzia de projetos entregues e funcionando.

Pois então que há alguns meses decidi escrever um novo livro. O segundo de 2017 (o primeiro foi sobre Node.js), justamente sobre todo esse conhecimento de MongoDB que possuo que já me renderam algumas ofertas de emprego bem interessantes e alguns milhares de reais em projetos entregues usando este banco de dados.

Esse livro chama-se MongoDB para Iniciantes, e está à venda desde essa semana na Amazon.

Apesar do seu tamanho, 120 páginas, é um livro bem completo. Ele não se limita a listar e explicar comandos para consultar e manipular o MongoDB. Ele parte do princípio que você quer entender como funciona a orientação à documentos, que quer saber como se gerencia minimamente um servidor Mongo. Com uma didática clara e objetiva, como todos livros de minha autoria (quem já leu os demais sabe do que estou falando), e que pega o leitor pela mão e ensina desde os conceitos mais básicos até tudo que é necessário para ter um banco modelado corretamente e rodando, pronto para suas aplicações se conectarem. Inclusive ensina como usar MongoDB com Node.js, ASP.NET Core e PHP, sem entrar em muitos detalhes destas linguagens.

Do primeiro insert até comandos mais elaborados para manipulação de campos multi-valorados, índices, relatórios de performance e subdocumentos, MongoDB para Iniciantes é para quem está começando a trabalhar com MongoDB e bancos relacionais e está completamente confuso com a quantidade de tutoriais, informações conflitantes e artigos fora de ordem. Nele, ensino a usar tudo o que deu certo em meus projetos com MongoDB nos últimos anos, um banco não-relacional que é bom, confiável e que possui grande mercado.

Neste livro você vai aprender:

  • introdução aos bancos não-relacionais e NOSQL;
  • execução do servidor MongoDB;
  • conexão usando o client nativo Mongo;
  • quando usar e quando não usar MongoDB;
  • comandos básicos e intermediários para consultas;
  • comandos básicos e intermediários para inserção, atualização e exclusão de documentos;
  • como extrair relatório de performance de suas queries;
  • criação de índices;
  • gerenciamento mínimo de servidor (backup, restore, import);
  • como modelar os seus documentos usando o paradigma do MongoDB;
  • como criar aplicações reais usando Node.js, PHP e ASP.NET Core;
  • dezenas de boas práticas com MongoDB;

Novamente, devido às atualizações constantes, optei apenas por ter somente versão digital, que você pode ler no Kindle, no PC usando o ler.amazon.com e no smartphone/tablet usando o app Kindle Cloud Reader. Livros de tecnologia impressos tendem a ficar obsoletos rapidamente, coisa que eu detesto.

Além disso, caso assine o Kindle Unlimited (primeiro mês grátis e depois R$20/mês), você pode ler o meu livro e milhares de outros títulos gratuitamente.

Se ainda não é cliente da Amazon, esta é uma excelente oportunidade de começar com o pé direito. Modéstia à parte. 😉

Leia a amostra grátis do livro abaixo e tire suas próprias conclusões: