Por: Marcelo Palladino
9637 visualizações
Tempo leitura: 13 min
Introdução:
A ideia do “pensamento enxuto” (Lean Thinking) é algo que de uma forma ou de outra está aí desde 1990. No entanto, quem viveu esta época no desenvolvimento de software teve que conviver com análise estruturada, processo de desenvolvimento em cascata, espiral e outras diversas práticas de engenharia de software que vão contra alguns princípios do pensamento enxuto. O foco muitas vezes estava em entregar artefatos, documentar e especificar todo o software antes desenvolver.
Desde a criação do XP (~1997) e posteriormente do manifesto ágil, por volta de 2000, muita coisa tem mudado no mundo do desenvolvimento de software. Por exemplo, o pensamento pragmático com foco na entrega de valor tem tido cada vez mais espaço nas corporações e, com isso, diversas abordagens surgiram com o objetivo de alinhar processos de produção, que já existiam, às novas tendências de desenvolvimento de software. Uma das abordagens resultantes deste processo foi o Lean Software Development, apresentado por Mary Poppendieck e Tom Poppendieck, o qual mostra como os princípios Lean originais podem ser aplicados/adaptados em abordagens de desenvolvimento de software ágil.
7 princípios Lean aplicados ao desenvolvimento de software
- Elimine desperdícios
- Inclua a qualidade no processo
- Crie conhecimento
- Adie decisões e comprometimentos
- Entregue o quanto antes
- Respeite as pessoas e a equipe
- Otimize o todo
Como desenvolvedor da Lambda3, é impossível para mim não fazer conexões com estes princípios, uma vez que na Lambda somos constantemente forçados a pensar de forma pragmática em qualidade e entrega de valor. Toda conversa, seja ela sobre arquitetura de software, tecnologias a serem empregadas nos projetos ou metodologias, sempre tem como alvo a qualidade e a entrega de valor real para os clientes, de forma constante e ágil.
Sendo assim, este artigo tem o objetivo de compartilhar algumas coisas que fazemos na Lambda3 e que se relacionam com os princípios estabelecidos por Mary e Tom. Mais especificamente falarei sobre o segundo princípio que trata sobre a inclusão da qualidade no processo.
Pensamento pragmático: O triângulo das restrições
Temos que ter um cuidado especial ao falar de qualidade. Já vi muitos times falharem por não saberem definir o que é qualidade e/ou levarem esta discussão para o âmbito puramente passional. As perguntas são simples: qual o conceito de qualidade em seu projeto? O time sabe exatamente o que significa qualidade para o projeto em questão?
Uma boa forma de definir a meta de qualidade de um projeto é usar o triângulo das restrições, também conhecido pelas alcunhas de trângulo de ferro, triângulo do projeto, triângulo das triplas restrições, triângulo das dependências e por aí vai.
As partes deste triângulo se relacionam de forma que não há como alterar um lado sem afetar os outros dois e isso está totalmente conectado ao conceito de qualidade do projeto. Esta conexão é tão forte que uma forma bastante honesta de representar o triângulo pode ser esta aqui:
A qualidade é afetada por mudanças em qualquer lado do triângulo e isso tem que estar bem claro para todos no time.
Pensamento pragmático: Uma história real sobre (in)definição de qualidade
Certa vez trabalhei em uma empresa cujo gerente de projeto entendia que os três lados do triângulo das restrições eram sagrados e nunca deveriam ser alterados após o aceite do cliente. Uma típica estrutura em cascata. A equipe de levantamento de requisitos trabalhava no início para viabilizar o projeto junto ao cliente e coletava todos os requisitos funcionais. Depois disso, o gerente de projeto orçava o software e definia um prazo baseado em sua experiência e nos requisitos funcionais documentados por sua equipe.
Quando o projeto chegava ao time de desenvolvimento, já havia diagramas de caso de uso, modelos de dados, diagramas de classes e protótipos de tela. Além disso, havia um documento bem bonito no MS-Project estipulando todos os prazos e atividades. Os prazos e os custos normalmente não estavam alinhados com a definição de pronto * do time de desenvolvimento. Nós gostaríamos de incluir o máximo de testes automatizados, especialmente aqueles de aceitação, os quais idealmente deveríamos contar com o apoio do time de analistas para escrevê-los. No entanto, isso normalmente ia de encontro com as expectativas de prazos/custos. Nossas definições de qualidade eram diferentes: o time de desenvolvimento queria testes como apoio para entrega íntegra, a gerência achava que isso não influenciava a qualidade externa, que era uma questão de purismo técnico. No final isso nos colocava em uma constante e desgastante queda de braço, na qual nunca havia um vencedor de fato. Todos perdíamos, inclusive os clientes.
* Definição de pronto A definição de pronto de um time de desenvolvimento está ligada aquilo que deve ser feito em uma funcionalidade para que ela possa ser considerada “pronta”. Isto pode envolver desde o aceite da história por parte do usuário até aspectos mais relacionados ao apoio do time. Um exemplo de definição de pronto poderia ser: -A funcionalidade deve possuir testes de aceitação -A funcionalidade deve possuir testes de unidade -O código deve ter sido revisado por outra pessoa -Todos os testes devem estar passando no build -A funcionalidade deve ter sido publicada em homologação |
O cliente tinha uma planilha na qual ele definia as relações e parâmetros entre os diversos centros de lucro da empresa. Esta planilha estava enraizada na cultura da empresa e todos a utilizam há anos. Parte do nosso trabalho era levar aqueles dados para dentro de um módulo do software de forma a aumentar sua visibilidade, permitir o versionamento e sua utilização em outros módulos. Fora alguns problemas na modelagem, o requisito previa a criação de várias telas (não me lembro do número, mas passava de 10), as quais deveriam ser utilizadas pelos usuários para criar e manter exatamente as mesmas informações que ele mantinha em um único documento do MS-Excel. Aquilo não parecia certo, de maneira que a equipe de desenvolvimento alterou o requisito. Criamos uma única interface que tratava a planilha como uma entrada de dados, validando seu conteúdo, alimentando as entidades do banco de dados e tratando adequadamente suas versões. O modelo ficou um pouco mais complexo, pois a alteração do requisito entregava mais valor. Além disso, escrevemos diversos testes de unidade para as rotinas de leitura e validação, cobrindo na totalidade as regras de negócio impostas pela planilha.
Para tornar curta uma história que é longa, o cliente adorou. Era exatamente o que ele esperava e nós o encantamos. No entanto, mudamos todos os lados do triângulo sem que isso gerasse mais receita para o projeto, já que o cliente não aceitou pagar mais por algo que era exatamente o que ele queria desde o começo.
O gerente do projeto entendeu o ponto da equipe de desenvolvimento, mas defendeu a ideia que deveríamos ter feito “errado”, mantendo as restrições para depois vender uma provável requisição de alteração. Esta história mostra bem como uma clara definição de qualidade devidamente compartilhada é importante. Além disso, esta história mostra como um time mal organizado pode comprometer a integridade do projeto, o que vai nos levar ao ponto central deste artigo.
Qualidade é inegociável
Desenvolvendo software há muitos anos, tive a oportunidade de trabalhar em empresas de vários tamanhos, times dos mais variados tipos e clientes dos diversos ramos de atividade. Independente de todas as circustâncias variáveis, pelo que consigo me lembrar, a busca pela qualidade sempre foi uma meta constante e inegociável.
Neste tocante, Mary e Tom Poppendieck determinaram que há dois tipos de integridade no processo de desenvolvimento de software: integridade percebida e conceitual. A integridade percebida é aquela em que o software alcança um equilíbrio entre funções, usabilidade, confiabilidade, economia, etc, ou seja, exatamente aquilo que o cliente precisa e espera. Integridade conceitual é aquela na qual os conceitos e partes centrais do sistema trabalham harmonicamente, de forma coesa, como um todo. Os componentes ou módulos se integram e trabalham bem conjuntamente. É fácil perceber que como a integridade conceitual é fator crítico para a entrega de integridade/qualidade percebida.
A pergunta é: como um time de desenvolvimento de software, que entrega funcionalidades de forma ágil, pode garantir a integridade daquilo que está sendo entregue?
Ferramentas e práticas visando integridade
Desenvolver software é um processo complexo, o que torna a tarefa de entregar software com integridade bem difícil. Tendo isto em vista, o que você pode fazer para controlar a complexidade e aumentar suas chances de entregar software íntegro?
Testes automatizados
Testes automatizados são obrigatórios! Se seu projeto não possui uma boa bateria de testes, com cobertura de código, como você pode garantir que seu sistema continua funcionando a cada nova submissão de código? Em outras palavras, como você pode garantir a integridade do seu software?
O quadrante do testes ágil
Já que falamos em testes automatizados, vale estendermos um pouco mais esta leitura e falarmos sobre outros tipos de testes. Brian Marick cunhou uma série de termos para as diversas categorias de testes conforme seu objetivo e os organizou em um quadrante denominado “Quadrante de testes ágil”.
Quadrante 1 (suporte ao time): Dentro deste quadrante podemos agruprar os testes de unidade (que validam métodos) e os testes de componentes (que podem validar classes ou grupos de classes). Estes testes se caracterizam por serem executados muito rapidamente e por darem um ótimo feedback sobre a qualidade do código.
Quadrante 2 (suporte ao time): Ainda visando o suporte ao time, neste quadrante ficam os testes que envolvem a qualidade externa do software. Normalmente estes testes são focados no negócio e também podem ser automatizados. Outra possibilidade aqui é termos especialistas em UX criando wireframes e protótipos para validação junto ao cliente.
Quadrante 3 (crítica ao produto): Assumindo que seus testes de unidade e testes funcionais estejam passando 100%, mesmo assim pode ocorrer de seu software não atender realmente a necessidade do usuário. Neste quadrante os testes irão criticar o produto e normalmente serão feitos por usuários reais. Estes testes podem fazer parte da definição de pronto de uma funcionalidade.
Quadrante 4 (crítica ao produto): Os testes neste quadrante são mais técnicos e criticam o produto em termos de performance, carga e segurança. Ou seja, cada parte do seu código foi testada (unidade e componente) e você criou testes para garantir que seu software entrega o que o usuário precisa. Legal! Agora, seu software funciona adequadamente para a quantidade de usuários esperada?
Code review / code inspection
Em alguns projetos da Lambda3 temos a prática de revisão de código definida no fluxo de desenvolvimento. Esta é uma atividade em que um desenvolvedor analisa um código que não é seu em busca de defeitos e/ou corrupção de padrões e/ou oportunidades de melhoria. Esta prática funciona especialmente bem quando seu time não está tão equilibrado em termos de conhecimentos dos participantes. Ou seja, você pode determinar que os membros mais experientes revisem as requisições de submissão daqueles que possuem menos experiência no ambiente. No entanto, mesmo que seu time seja composto apenas pelos melhores especialistas, ainda sim você pode encontrar vantagens em colocar esta prática para funcionar. Desenvolvedores profissionais adoram receber feedback sobre seu código.
Integração contínua
Integração contínua é obrigatória! Ok, seu time trabalhou duro criando testes automatizados, então vocês devem possuir um ambiente de integração contínua. Este ambiente irá maximizar as vantagens de possuir uma boa bateria de testes automatizados para seu software.
Martin Fowler define integração continua da seguinte forma:
“Integração Contínua é uma pratica de desenvolvimento de software onde os membros de um time integram seu trabalho frequentemente, geralmente cada pessoa integra pelo menos diariamente – podendo haver multiplas integrações por dia. Cada integração é verificada por um build automatizado (incluindo testes) para detectar erros de integração o mais rápido possível. Muitos times acham que essa abordagem leva a uma significante redução nos problemas de integração e permite que um time desenvolva software coeso mais rapidamente.”
Dependendo do tamanho do seu projeto, a execução dos testes (especialmente os testes de aceitação) pode demorar alguns bons minutos e este é um dos sinais que devem levá-lo a pensar em um servidor de IC (integração contínua). Este servidor será o responsável por baixar todos os fontes a cada commit e realizar os testes. Em caso de sucesso do build, opcionalmente, o processo ainda poderia realizar o deploy em um ambiente de desenvolvimento/homologação com a última versão do código. Isso pode ser feito a cada commit, uma vez por dia ou da forma como for mais apropriado para seu time.
Conclusões
Este artigo apresentou rapidamente algumas práticas que podem ser utilizadas para incluir qualidade/integridade em seu processo de construção de software. Também falamos do triângulo das restrições e como ele pode ser uma boa ferramenta para apoiar uma discussão sobre ações que visam aumentar qualidade no processo de desenvolvimento de software.
Data da publicação:
25/06/2014
-
Marcelo Palladino
Lambda3
public class Palladino: SerHumano, Pai, Esposo, EmpreendedorNasHorasVagas, Gamer, Programador, Lambda { }.