A importância da qualidade interna

A primeira vez que percebi o quanto a qualidade interna é importante, foi quando li o livro Scrum e XP direto das Trincheiras. Nele o Henrik Kniberg destaque que a qualidade interna do sistema é mais importante que a qualidade externa, tanto que ela é de responsabilidade da equipe e nunca (quase nunca) negocíavel com os clientes. E realmente é difícil discordar, uma vez que a qualidade interna irá acabar refletindo na qualidade externa do sistema, tanto que segundo o próprio Henrik: “[…] um sistema com baixa qualidade interna raramente terá uma qualidade externa alta.”

Mas qual a diferença entre qualidade interna e externa?

Em suma, qualidade interna é o sistema visto da perspectiva técnica, enquanto a qualidade externa é a visão do sistema, da perspectiva funcional.

Uma analogia seria a de uma montagem de um computador, você pode montar um computador com peças de vários fabricantes, e para o usuário pouco importará se a placa mãe é uma Asus, ou uma PCChips. O que o usuário verá será a qualidade externa, se o gabinete tem um design atraente se o computador não trava, essas coisas. Ele pouco irá importar se a memória RAM é Kingston ou não. O que importa na perspectiva funcional é realmente o funcionamento do computador e não como ele foi montado.

O que ocorre muito, é que há uma forte tendência no desenvolvimento do sistema ser guiado pelo “funcionou”, sendo que o “funcionou” pode ser um estado ainda crú da implementação da funcionalidade.

Monalisa

Citei a Monalisa no post anterior, desta vez ela será útil para nós, para entender como o processo de desenvolvimento de um software, é muito mais próximo do processo de pintura de um quadro, do que de um processo de construção civil.

Pesquisando na Internet encontrei informações de que a Monalisa foi pintada entre 1503-1514. Nesse período de mais de 10 anos, boa parte do tempo investido no quadro, foi em alterações técnicas, a base sempre foi permanecida.

Em outras palavras, podemos dizer que Leonardo Da Vinci levou 11 anos para finalizar o seu projeto, e boa parte do tempo, foi investido na manutenção do quadro, realizando refatorações e correções de bugs.

Uma característica que suponho que seja comum no processo de pintura de um quadro, principalmente quando ele é uma demanda, é a mudança constante. E mudança é uma das poucas certezas que temos no desenvolvimento de software, afinal um bom software está “sempre” em constante evolução/melhoria e quanto mais fácil for inserir mudanças no software, melhor será.

Mudar software é mais difícil do que mudar hardware

Vamos fazer uma breve viagem no tempo, o ano é 1946 e você está de frente ao ENIAC (foto abaixo). Se você perguntar para a pessoa na foto: o que é mais fácil mudar, o hardware ou o software? Ele com certeza, irá responder que é o hardware, e ainda irá achar a sua pergunta estúpida.

Agora voltando a 2010. O que é mais difícil, mudar o software ou o hardware?

Não há dúvidas que o software, não é? Hoje obter harware é MUITO fácil e barato, comparado a 1946. E com as VPSs da vida, ficou fácil obter hardware e uma ótima infraestrutura, você nem precisa sair de casa para ter o seu servidor rodando.

Monalisa, ENIAC, computação em nuvem e qualidade interna

Onde eu quero chegar com tudo isso?

Acredito que ficou claro que um dos grandes desafios para se desenvolver um software é conseguir mudar ele com o menor esforço necessário, mantendo o seu bom funcionamento. Costumo até dizer, que desenvolver software é fácil, comparado a manter o software.

Mas eu estou errado, pois desenvolver o software deveria ser mais difícil do que manter ele. Porém, seja por motivos externos (mudança frequente/drásticas de funcionalidades pelo cliente) e/ou motivos internos (pouca cobertura de testes, design fraco, falhas de comunicação, etc), manter o software acabou se tornando um tarefa mais difícil, do que a criação dele.

Voltando ao exemplo da Monalisa, vimos que Leonardo Da Vinci passou boa parte do tempo fazendo correções e melhorias no quadro, porém a sua essência foi mantida. Supunho que ele tenha feito um bom “design”, que permitiu inserir as correções e melhorias sem ter enfrentado maiores problemas.

O caso do ENIAC é interessante, pois mostra como as coisas mudaram MUITO do início da computação até hoje. Naquela época, e por um bom tempo, o hardware era o mais valorizado. Já hoje o software passou a ser o mais valorizado. E se antes os softwares eram escritos em cartões perfurados e pouquíssimas pessoas eram capazes de desenvolver software, hoje escrevemos software em linguagens quase naturais e conseguimos aprender a “desenvolver” por meio da Internet e de graça.

E a qualidade interna é peça fundamental para podermos conseguir alterar o código de forma “indolor”. E essa é apenas uma das vantagens que desenvolver software com uma boa qualidade interna traz. E vamos concentrar nela no próximo tópico.

Qualidade Interna

Qualidade interna também poderia ser traduzida em “fazer a coisa da forma certa”. Porém, essa tradução é muito simples e faz parecer que obter qualidade interna é fácil. Afinal seria só saber como fazer a “coisa” da forma certa, não é mesmo?

No entanto, há várias formas de fazer da forma certa no mundo do desenvolvimento de software. Por isso, uma das tarefas do desenvolvedor é fazer escolhas, e serão essas escolhas que irão influenciar diretamente a qualidade interna do software.

Os retornos com o investimento em qualidade interna ocorrem a médio e longo prazo, por causa disso, muitos acabam fazendo as escolhas “certas” a curto prazo, mas esquecem de avaliar o impacto que elas terão a médio e longo prazo.

E uma vez que escolhemos o caminho mais fácil, por exemplo adicionar mais um if, para atender uma alteração que o cliente pediu, ao invés, de extrair o comportamento para outro método, a tendência é acabar sempre escolhendo o caminho mais fácil.

Esse hábito, acaba sendo passado para os outros é acaba virando uma “cultura”. E aí, o caminho fácil será sempre tomado, e a possibilidade de tomar outras direções poderá nem passar pela cabeça mais. Sendo que essas direções diferentes, muitas vezes não representam um caminho difícil (ex.: escrever testes unitários), mas a mudança em si, é a parte difícil.

Desta forma, a qualidade interna acaba sendo colocada de escanteio. Porém, ao longo do desenvolvimento irão aparecer os sinais de que ela está muito baixa. Por exemplo: lançar uma nova versão demora cada vez mais tempo.

Como Obter Qualidade Interna

Algumas ações podem ajudar a desenvolvermos um software com uma boa qualidade interna:

  • Refatoração: alterar o código sem alterar o seu comportamento, focando na melhoria do código para favorecer a manutenibilidade dele;
  • Conhecer e utilizar boas práticas: princípios como o SOLID, ajudam a resolver os problemas com menos ruído e com soluções que favorecem a manutenção do software;
  • Comunicação: uma boa comunicação é essencial para o desenvolvimento do software, tanto externa (cliente), como interna (equipe). Muitos bugs acabam sendo inseridos e códigos duplicados, simplesmente porque houve falha na comunicação;
  • Estressar as soluções: geralmente, costumamos implementar a primeira solução que nos vem na cabeça, porém esquecemos que a primeira solução costuma não ser a melhor, por isso é importante pensar em outras formas de solucionar o mesmo problema e/ou conversar com alguém sobre;
  • Aprendizado contínuo: é importante estar sempre nos aperfeiçoando, se você for olhar algo que fez há 6 meses atrás e achou que não tem nada a ser melhorado, é sinal que você não aprendeu muito nos últimos 6 meses;
  • Saber quando parar: saber o momento de parar de ficar refatorando o código, é tão importante quanto saber quando é preciso melhorar ele, objetive a perfeição, mas não fique cego por ela;
  • Valorize o seu tempo: a vida é muito curta para ficar gastando tempo tentando entender aquele método com mais de 30 linhas que você escreveu há 3 meses atrás, ou ficar corrigindo bugs que poderiam ter sido encontrados antes com testes. Só nestes momentos, que você realmente percebe, o quanto a qualidade interna é importante;
  • Testes: por último e não menos importante, escreva testes. Além deles auxiliarem você a pensar melhor sobre as funcionalidades (se você usar TDD), eles irão te dá a tranquilidade necessária para refatorar o código. Afinal, refatorar sem testes, é algo muito difícil e arriscado, e isso incentiva a não refatoração e por consequência a uma baixa qualidade interna, portanto, escrever testes é fundamental para obter uma boa qualidade interna.

Conclusão

Enquanto a qualidade externa é a percepção do cliente para o software, a interna é a percepção dos desenvolvedores em relação a ele.

Devemos nos preocupar em manter uma boa qualidade interna, pois ela é essencial para a manutenção do software, e em cenários onde há entrega contínua do software (ex.: SaaS), a qualidade interna acabará sendo uma diferença competitiva. Afinal, uma das únicas certezas que temos no desenvolvimento de software, é que haverá mudanças, portanto, conseguindo reagir à tempo a elas, é fundamental para conseguir atender as demandas.

Os testes mais uma vez, representam um papel importante, pois é através deles que teremos a segurança necessária para refatorar o nosso código, implementar as alterações e novas funcionalidades.

Como anda a qualidade interna dos projetos que você está participando? A equipe tem consciência da sua importância?

Fique por dentro das novidades, assine o feed do QualidadeBR.

Processo Incremental x Iterativo

Monalisa e o Desenvolvimento de Software

A figura abaixo é bem famosa atualmente, provavelmente você já viu várias vezes.

A sua empresa deve (ou deveria) usar um processo incremental e iterativo para desenvolver os softwares.

Trabalhar de forma incremental e iterativa é bem comum em tarefas criativas, por exemplo: escrever esse post.

Estou no tópico Monalisa e o Desenvolvimento de Software, e este é o tópico onde irei falar sobre o processo incremental e iterativo, no final pretendo juntar esse assunto com o de qualidade interna, focando em refatoração. Também pretendo falar sobre o papel dos testes num processo incremental e iterativo. E quando comecei o post eu não tinha definida a estrutura dele, só sabia que ia escrever sobre qualidade externa e interna, por isso já tive que retirar várias partes e refatorar outras.

A figura apresentada mostra de uma forma bem clara a diferença entre um processo incremental para um iterativo. No primeiro já temos melhor definido o que queremos, já no segundo temos apenas uma ideia genérica do que queremos.

Na prática o processo iterativo acaba sendo também incremental, e vice-versa, pois ao desenvolver as partes no processo incremental, iremos fazer uma iteração. Meio confuso neh? Vamos para um exemplo:

O Joãozinho pegou o post-it da funcionalidade de enviar e-mail de confirmação do cadastro. Joãozinho implementou essa funcionalidade realizando os seguintes passos:

  1. Implementou o envio de e-mail;
  2. Implementou a ativação do usuário, apenas quando ele tiver acessado o link de confirmação da conta;
  3. Adicionou a implementação do envio de e-mail no cadastro do usuário;
  4. Adicionou o corpo do e-mail com as informações de bem-vindo e ativação da conta.
  5. Joãozinho percebeu que o envio de e-mail estava demorando, e deixou ele de forma assíncrona;
  6. Houve uma melhora no corpo do e-mail, pois o Joãozinho não gostou muito do primeiro layout.

Podemos observar que o Joãozinho já sabia como seria essa funcionalidade, e foi desenvolvendo ela de forma incremental. Porém, ao finalizar a implementação ele teve que ainda realizar algumas iterações, de acordo com o comportamento que a funcionalidade teve. Se o Joãozinho não tivesse percebido tais comportamentos, ele teria apresentado essa funcionalidade para o cliente, e esse poderia ter pedido a alteração do envio de e-mail de forma assíncrona e a melhora do layout.

Ou seja, no processo incremental já sabemos bem o que queremos (ex.: um bolo de chocolate), já no processo iterativo temos apenas uma vaga ideia, e iremos descobrir mais detalhes do que queremos, ao longo do desenvolvimento (ex.: um portal de Internet).

P.S.: Como notaram, retirei a parte sobre qualidade externa e interna, fica para o próximo post. Acabei me alongando muito no assunto do processo incremental X iterativo, e então optei por deixar apenas essa parte no post. Essa é uma das vantagens de usar um processo incremental e iterativo, com a mentalidade ágil. 😉

Vamos testar e desenvolver?

Caros(as) leitores(as),

O que vocês acham de testar e desenvolver uma aplicação?

Isso mesmo, testar e desenvolver uma aplicação na prática, colocar a mão na massa! 🙂

Como seria isso? Bem o formato que estive pensando (podemos refinar depois), é que primeiro vocês escrevem um teste e me enviam (pelos comentários), daí eu implemento o código para passar naquele teste, e depois a gente troca. E assim vai indo, até a nossa aplicação ficar pronta.

Em qual linguagem?

Qualquer uma. 😀

A intenção não é aprender a sintaxe de determinada linguagem e sim exercitar as suas habilidades para testar e desenvolver.

Mas eu não sei programar Fabrício

Sem problemas também, pode enviar a implementação do código em pseudocódigo.

Só é preciso saber lógica de programação e ter vontade de aprender para participar. 🙂

OBS.: A “tradução” para alguma linguagem de programação eu faço depois, para podermos ir evoluindo a aplicação.

Como iremos testar?

A ideia é utilizando testes automatizados, usando alguma ferramenta Xunit ou até de testes de aceitação. E se você não conhecer nenhuma ferramenta, poderá enviar o teste no estilo do cenário do BDD.

Como iremos desenvolver?

Utilizando TDD, ou seja, primeiro vamos escrever o teste para depois escrever o código. Indo bem baby steps.

Ou seja, acaba sendo “parecido” com um dojo, só que online.

Qual aplicação iremos desenvolver?

Uma aplicação simples, a primeira seria uma para descobrir que tipo é um triângulo. Praticamente a mesma que o Camilo Ribeiro escreveu em Java.

Topam?

Se você estiver interessado em participar, basta fazer um comentário (não doí rs). O mínimo para essa ideia maluca ser colocada em prática é um participante hehe. Se tivermos mais, o que seria muito legal, melhor ainda, pois poderemos aprender mais e ter soluções implementadas de forma diferente e usando ferramentas e linguagens diferentes também. 🙂

Depois maiores detalhes de como será a dinâmica de trabalho eu explico depois (pensando em usar os próprios comentários do blog ou criar uma lista de e-mail).

Update 18/11/10

Pessoal, irei fechar as “inscrições” para essa dinâmica no dia 30 de novembro. Portanto, se você quiser participar, deixe um comentário que eu entrarei em contato.

Fique por dentro das novidades, assine o feed do QualidadeBR.

Você precisa de Agile?

Parece que de repente, “todo mundo” começou a buscar ser ágil.

A primeira vista isso pode até ser visto como bom, uma vez que vários métodos ágeis são bem mais sensatos do que os métodos tradicionais. Porém, infelizmente, muitos estão apenas indo na “onda do Agile”, e esses correm um alto risco de morrer na praia.

Por experiência própria, posso dizer que Agile não é pra qualquer empresa/equipe.

E dentre as várias coisas que aprendi (a duras penas), foi que nem sempre precisamos de Agile, ou melhor, nem sempre o que mais precisamos é Agile.

Para ilustrar esse aprendizado, vou utilizar o exemplo da famosa XPTO Solutions.

A XPTO Solutions também conheceu o Agile, por meio de materiais de terceiro é claro (uma dica: busque primeiro o conhecimento da fonte original). E após ver que os seus concorrentes já estavam utilizando métodos ágeis, decidiu adotar também. E como a maioria, começou com Scrum.

No começo tudo parecia uma maravilha, vários post-its coloridos na parede, o gráfico burn-down correndo bem, etc. Porém, após algumas sprints, percebeu-se que tinham finalizados várias funcionalidades, porém nada tinha ido para a produção, e nem o cliente tinha visto o software que estava sendo desenvolvido, pois estava distante, e o máximo de participação que ele tinha na sprint, era feita por e-mail ou telefone com o Scrum Master.

Outro problema que apareceu, foi que muitas tarefas eram retrabalhos e resoluções de bugs, pois eles não faziam testes unitários e 70% dos desenvolvedores ainda eram juniores, e não conheciam práticas como TDD e ainda não tinham uma base sólida na linguagem de programação que é usada na XPTO.

O problemas que aconteceram na XPTO não são incomuns. E se formos analisar muitos desses problemas não têm nenhuma relação com o Agile, e iriam acontecer independente da metodologia utilizada.

Problemas como equipe inexperiente, cliente distante, gestão de conhecimento ineficiente, falta de motivação, acomodação, etc são comuns em qualquer empresa. E a solução ou medidas que poderiam amenizar os seus efeitos não estão numa metodologia de desenvolvimento de software.

Por isso que eu enfatizo, que antes de implementar Agile, precisamos analisar o ambiente a nossa volta, assim como um agricultor verifica o terreno para saber o que pode plantar nele. Não adianta forçar ser Agile, o seu desenvolvedor não irá testar só porque agora é Agile, o seu cliente não irá participar mais e/ou aceitar o contrato de escopo negociável, só porque agora a sua empresa é Agile.

E é bom lembrar, que Agile não é um fim, e sim um meio para você construir software com mais eficiência e qualidade, ter uma equipe mais motivada e um cliente mais satisfeito.

É importante ter em mente, que Agile não é apenas uma questão de mudança de hábito, mas também cultural . Vários paradigmas precisam ser quebrados quando implementamos Agile, e alguns deles já foram quebrados por pessoas como o Ricardo Semler, muito antes do Manifesto Ágil surgir, como por exemplo: uma participação mais democrática da equipe no dia-a-dia e nas decisões da empresa e valorizar mais pessoas do que processo.

Podemos fazer uma implementação de Agile de forma mais harmoniosa e sensata, ao buscar saber o que realmente precisamos antes do Agile em sí, uma vez que muitos dos problemas que enfrentamos, não estão relacionados com a metodologia que está sendo usada. Lembre-se, que “para que a semente dê frutos, é necessário preparar a terra.”

Fique por dentro das novidades, assine o feed do QualidadeBR.

Fonte imagens:

http://bit.ly/aevP0r

http://bit.ly/c2t8zd

http://bit.ly/a8Y15t

Por que os desenvolvedores não fazem testes de unidade e integração?

A 27ª Mesa Redonda DFTestes teve como tema “Por que os desenvolvedores não fazem testes de unidade e integração?”. A discussão gerou 8 respostas e 7 pessoas participaram, sendo elas: eu, Janaina Trilles, Sarah Pimentel, Maria Meire, Edwagney Luz, Felipe Silva e Bruno Augusto.

Abaixo segue um resumo da discussão, baseado nas duas perguntas principais da mesa redonda. Quem quiser acessar a discussão na íntegra, pode acessar por meio deste link.

Por que os desenvolvedores não fazem testes de unidade e integração?

A Sarah Pimentel deu a sua resposta baseada na sua experiência, dizendo que:

Alguns casos que vivenciei era mais uma questão de conversar não com os desenvolvedores, mas com os gerentes. Nem sempre é “má vontade” dos desenvolvedores, em alguns casos é falta de tempo mesmo. O gerente não prevê a criação/execução de testes unitários e se o desenvolvedor aumentar a estimativa dele de desenvolvimento para englobar os testes unitários o gerente vai cair em cima e cortar o tempo da estimativa.

A aplicação de testes, de uma forma geral, não só os unitários, mas também os de sistema, está sempre envolta em muitas questões culturais.

O Edwagney fez um comentário bem interessante sobre a questão, colocando que a acomodação é um dos motivos para que os desenvolvedores não realizem testes de unidade e integração.

Esse é um tema bastante interessante e um grande indício de que o ser humano é sim acomodado e gosta de entrar numa zona de conforto e para não sair de lá jogar a culpa no tempo. Explico!

As tecnologias de hoje permitem ganhar muito mais tempo com desenvolvimento do que anos atrás. Quem foi desenvolvedor nas décadas de 80 e 90 sabem do que estou falando. Nessa época não tínhamos ainda o conceito de teste formal de software, como temos hoje e TODA a execução do teste era feito pelos próprios desenvolvedores. Já ouviram falar em “teste de mesa”? Para quem nunca ouviu falar disso, esse é um teste que era feito “à mão” usando papel e caneta onde os desenvolvedores simulavam a entrada de dados nas suas estruturas condicionais e de repetição, e verificavam se essa estrutura iria funcionar da forma como eles imaginavam para o desenvolvimento.
Esse era o teste unitário. Ele era feito por qualquer bom desenvolvedor. Era a forma de garantir que ao menos as principais funcionalidades estavam funcionando de forma isolada.

Esse método também era bastante usado nos testes de integração, onde os próprios desenvolvedores se viam na necessidade de testar seus módulos de forma integrada. O ambiente era direcionado a esse teste. Quem faria isso? Ninguém… Éramos nós mesmos.

Quando começaram a surgir as novas tecnologias, reduzindo o tempo de desenvolvimento e os conceitos de teste, os desenvolvedores entraram em uma tamanha acomodação que hoje nem mesmo os testes básicos eles fazem mais. Como assim? Há não… Vou perder meu tempo testando pra quê, se existe uma equipe só pra fazer isso?

Minha reflexão em relação a tudo isso é, existe culpa dos desenvolvedores por não mais executarem os testes?

Penso que atribuir culpa a alguém ou a alguma área é a forma mais fácil de taparmos o sol com a peneira. Não é assim que funciona. Antes de botar culpa em alguém façamos algumas reflexões:

Qual a política de testes foi adotada pela empresa? Todos na organização conhecem essa política? Todos a conhecem e sabem falar dela para outras pessoas (com propriedade)?

Essa política atribui papéis e responsabilidades bem definidos? A equipe de desenvolvimento sabe exatamente qual teste é executado pela equipe de teste?

O que aconteceu com os desenvolvedores que os fizeram a não executarem mais testes é simples. ACOMODAÇÃO.

De novo, culpa deles, não. Isso é natural do ser humano. Os desenvolvedores se acomodaram, pelo fato de acharem que, se existe uma equipe de teste, eles VÃO executar todos os testes no software. Só que em nenhum momento falaram para eles que não é bem assim. Cada um tem o seu escopo e sua participação no processo, isso É OBRIGAÇÃO DA ORGANIZAÇÃO em comunicar todos e todas as areas na empresa.

Para o Felipe Silva vários fatores contribuem para que o desenvolvedor não realize tais testes:

1. Penso na primeira como sendo a desvalorização de tais testes primeiramente por quem cobra os desenvolvedores (aquele que fica pondo pressão) e consequentemente pelos desenvolvedores (que se mostrarem baixo desempenho – por estarem testado tudo que supostamente deveriam testar – podem acabar perdendo o emprego),
2. O segundo ponto é a cultura de trabalho reativo acomodada na organização, que sem perceber (as vezes por que se negam a aceitar que isso ocorre sempre) preferem fazer duas vezes do que fazer o certo na primeira vez,
3. O terceiro ponto é os desenvolvedores não saberem que o processo de testes é composto por vários testes e que a equipe de teste não faz todos (não ainda), se eles não sabem disso é porque não deram condições para isso.

Em nenhum dos 3 casos eu os culpo (desenvolvedores) por isso, pois acho que a coisa começa em cima e reflete em baixo.

Na minha opinião alguns motivos para que o desenvolvedor não realize testes unitários e de integração são:

  • Existe uma rede de proteção chamada equipe de Testes;
  • Não tem
    • motivação;
    • conhecimento sobre testes;
    • noção do quanto dos benefícios de ter testes de unidade e integração;
  • São uns bundões e/ou imaturos;
  • Auto-confiança em excesso, “para que testar fui eu que desenvolvi”;
  • Dão manutenção em sistemas legados;

O grande problema é quando dois ou mais motivos juntam, o que é comum.

O que podemos fazer para incentivar/ajudar os desenvolvedores a realizar tais testes?

A Janaina Trilles compartilhou a sua dificuldade, que acredito que também seja a de muitos, mas acredito que o caminho seja tendo persistência mesmo, tentando ir mudar aos poucos.

Eu tenho grande dificuldade de fazer os desenvolvedores ter a cultura dos testes unitários, é sempre um problema na empresa .Não sei como eu posso mudar esse conceito, já falei que fazendo isso dimínui bastante defeitos e gera menos retrabalho.

Segundo o Felipe Silva, podemos ajudar sim, mas é algo que irá dá trabalho e demorará, uma vez que o problema muitas vezes está na cultura da equipe/empresa.

1. Ter no cronograma condições de se fazer estes testes, e fazer sem ser atropelado. Ter essas condições no cronograma não necessariamente significa aumenta o tempo do cronograma, pode-se pensar em N soluções para otimizar o tempo gasto em certas tarefas ou automatizar as que forem possíveis,
2. A organização, precisa ser “testadora”, digo, ser do mesmo time que nós, não somos “aqueles que apontam os defeitos”, somos “um de nós”, somos amigos do sucesso organizacional (pois tais testes ajudam tanto a ter melhor qualidade no produto entregue quanto ajuda reduzir o tempo gasto com testes funcionais), isso aqui não é da noite pro dia, mas tem que ser trabalhado incansavelmente a nível macro (todos envolvidos no projeto).
3. Alguma estratégia de divulgação da cultura de testes, do dia a dia, do que é feito e o que não é feito pelos testadores, seja por treinamento ou por qualquer outra forma que consiga atingir o objetivo de levar os opressores (líderes) e oprimidos (desenvolvedores) ao conhecimento do efeito negativo de se trabalhar reativamente.

Fácil falar e trabalhoso e não tão rápido de se conseguir, pois é humano, é cultural, é organizacional, envolve métricas, envolve dinheiro, envolve o cliente, envolve o emprego de cada um.

Eu penso, que podemos ajudar divulgando conteúdos relacionados ao assunto, dá uma palestra na empresa sobre esses testes, etc.

Se você tiver conhecimento/domínio sobre alguma linguagem de programação, pode conversar com o desenvolvedor para combinar um dia de sentar junto para tentar escrever alguns testes de uma funcionalidade que ele for implementar.

Realmente, introduzir testes unitários e de integração no desenvolvimento é um processo que costuma ser demorado, não é fácil mudar a cultura dos desenvolvedores, principalmente, pelo fato que eles têm que sentir que testes são importantes, pois é algo que terá que ser mantido, caso contrário, iremos ver a teoria das janelas quebradas na prática.

Bem pessoal é isso. Até a próxima! 🙂

Fique por dentro das novidades, assine o feed do QualidadeBR.

BDD – Behavior Driven Development

Durante a Mesa Redonda do DFTestes sobre “Implementar BDD ou ATDD é possível na realidade?“, percebi que BDD e ATDD são duas siglas pouco conhecidas pela comunidade de Teste de Software brasileira. Portanto, acabei decidindo fazer dois posts para explicar o básico de cada técnica. 🙂

Neste primeiro irei falar sobre BDD, cuja tradução é: Desenvolvimento Direcionado por Comportamento.

Como disse no começo, ambos são técnicas e técnicas para a equipe de desenvolvimento de software, não de teste. Acredito que esse seja o motivo principal, do desconhecimento por parte do pessoal da área de Teste de Software dessas duas técnicas. Porém, é altamente recomendável o pessoal de teste também ter conhecimento sobre elas, uma vez que eles podem ajudar os desenvolvedores na implementação de tais técnicas,.

Mas antes de detalhar e dá algumas opiniões sobre BDD, vou contar um pouco de história.

Surgimento do BDD

Num certo dia, um tal de Dan North estava refletindo sobre as dificuldades dos programadores ao usar TDD:

  • Saber por onde começar;
  • O que testar e o que não testar;
  • Até onde testar;
  • Como chamar os testes;
  • E entender porque um teste falha.

E essas dúvidas e mal entendimentos eram observados com uma certa frequência pelo nosso amigo Dan North.

Foi aí que o Dan North viu a necessidade de criar algo para apresentar TDD de uma maneira direta ao lado iluminado da força. Evitando todas as armadilhas que podem levar o jovem aprendiz a ser tentado pelo lado negro da força.

Dan North então respondeu essa necessidade com a criação do BDD, que possui três princípios básicos:

  • Tudo é comportamento: A área de negócios e a de Tecnologia devem se referir para o sistema da mesma forma;
  • Onde está o valor do negócio: Todo sistema deve ter comportamentos que sejam um verificador do valor para o negócio;
  • Faça o suficiente: Analisar, projetar e planejar tudo de cima para baixo, evitando o detalhamento prematuro.

O BDD evoluiu a partir de práticas ágeis e foi desenvolvida para tornar elas mais acessíveis e eficazes para os times que estão iniciando a entregar software de forma ágil. Com o tempo, o BDD cresceu para abranger também a análise ágil e a automação dos testes de aceitação.

Mas afinal o que é BDD?

Em poucas palavras, o BDD é uma técnica de desenvolvimento de software, onde os programadores desenvolvem o software direcionados por comportamentos. Tais comportamentos são a nível de negócio e ajudam o programador a entender melhor a funcionalidade que será desenvolvida.

Além disso, várias ferramentas (ex.: JBehave e Cucumber) permitem ao programador transformar esses comportamentos em verificações automatizadas.

Melhorando a comunicação

A técnica de BDD confia no uso de um vocabulário bem específico e pequeno, com o objetivo de minimizar a falta de comunicação e garantir que TODOS (stakeholders, desenvolvedores, testadores, analistas e gerentes), não estão apenas na mesma página, mas também estão usando as mesmas palavras. BDD pode ser considerada uma Ubiquitous Language (“Linguagem Onipresente”).

Essa é a grande sacada do BDD, pois permite que todos os envolvidos no projeto possam utilizar da mesma fonte, os comportamentos, para a partir deles realizar o seu trabalho.

Comportamento?

Um comportamento é descrito através de uma história, cujo modelo é:

Como um [X]
Eu quero [Y]
Então [Z]

Onde:

  • X- é a pessoa que será beneficiada;
  • Y- é alguma funcionalidade
  • Z- é o benefício ou valor da funcionalidade;

Esse é um modelo que foi criado pelo Dan e pelo Chris Stevenson. E foi evoluído por eles para algo mais flexível para não ser artificial ou restrito aos analistas e estruturado o bastante para que as histórias possam ser quebradas e possam ser automatizadas. E aí a seguinte forma foi definida para definir um cenário, que está associado a uma história:

Dado algum contexto inicial (entradas),
Quando um evento ocorre,
Então verifique alguns resultados.

hmmm… isso me parece com algo

Sim, se parece com um caso de teste não é?

Entradas, ações e resultado esperado. Essa é a estrutura básica de um caso de teste, e é também a do cenário, proposta pelo BDD. A diferença está nas palavras e forma descrita, afinal é bom lembrar que um caso de teste nem sempre é algo tão entendível para os clientes.

BDD na prática

Eu já utilizei um pouco o BDD usando o Cucumber. E para fechar o post deixo um exemplo de implementação do BDD com o Cucumber, mais a título de exemplo mesmo (não irei explicar como instalar, implementar as steps definitions, executar, etc quem sabe num próximo post). Acredito que com ele fique mais fácil para encaixar as ideias e conceitos apresentados anteriormente.

No Cucumber temos a seguinte nomenclatura básica:

  • Funcionalidade: igual ao modelo de história elaborado pelo Dan e Steve;
  • Cenário: igual ao cenário explicado anteriormente.

Um exemplo de fluxo de BDD seria: cliente defini a funcionalidade e cenários associados a ela > desenvolvedor entender a funcionalidade e cenários e implementar as steps definitions > desenvolvedor roda um comportamento, irá falhar > desenvolvedor implementar o código para o comportamento > desenvolvedor executa o comportamento, que deverá funcionar.

Lembrando que esse é apenas um exemplo de fluxo de BDD, a forma de implementação e pessoas envolvidas pode variar de empresa para empresa, mas o fluxo básico acaba sendo esse mesmo (elaborar e rodar o comportamento, que irá falhar > desenvolver o código para o comportamento > executar o comportamento, que deverá passar), ou seja, igual ao do TDD.

Abaixo um exemplo, mostrando uma funcionalidade e cenários associados a essa funcionalidade:


#language: pt

Funcionalidade: Gerenciar produtos
    Para gerenciar produtos
    Como um usuário
    Eu quero criar, editar, apagar e visualizar produtos

    Cenário: Visualizar os produtos
        Dado eu tenho os produtos iPad, iPhone
        Quando eu vou para lista de produtos
        Então eu devo ver "iPad"
        E eu devo ver "iPhone"
    Cenário: Criar um produto
        Dado eu não tenho produtos cadastrados
        E que eu esteja na lista de produtos
        Quando eu clico "New"
        E eu preencho "Name" com "iPad"
        E eu preencho "Price" com "499"
        E eu aperto "Create"
        Então eu devo ver "Product was successfully created."
        E eu devo ver "iPad"
    Cenário: Editar um produto
        Dado eu tenho o produto iPad
        E que eu esteja na lista de produtos
        Quando eu clico "Edit"
        E eu preencho "Name" com "iPhone"
        E eu preencho "Price" com "199"
        E eu aperto "Update"
        Então eu devo ver "Product was successfully updated"
        E eu devo ver "iPhone"
    Cenário: Apagar um produto
        Dado eu tenho os produtos iPad, iPhone
        E que eu esteja na lista de produtos
        Quando eu clico "Destroy"
        Então eu não devo ver "iPad"
        E eu devo ver "iPhone"

Saiba mais:

Alguns bons artigos em português:

Tradução do Danilo Sato do artigo original do Dan North.

Introduzindo Desenvolvimento Orientado por Comportamento (BDD)

Artigo do Ronaldo Melo Ferraz, onde ele faz algumas considerações sobre TDD e BDD.

Algumas considerações sobre TDD e BDD

Artigo do Urubatan, mostrando algumas diferenças entre TDD e BDD e também o Cucumber.

Cucumber e BDD – Vantagens para a empresa (Argumentos para o gerente, para o arquiteto, para o presidente da empresa, …)

Fique por dentro das novidades, assine o feed do QualidadeBR.

Fonte:

http://behaviour-driven.org/

http://blog.dannorth.net/introducing-bdd/

O modelo deveria ser flexível o suficiente para não parecer artificial ou restritivo para os analistas, porém estruturado o suficiente para que pudéssemos quebrar as histórias em pedaços que pudessem ser automatizados. Nós começamos a descrever os critérios de aceitação com base nos cenários, da seguinte fo

Disciplina * Habilidade = Artesão

Ontem li um artigo muito interessante no site do Jurgen. O artigo traz várias visões que também compartilho e acho importante, para quem trabalha com desenvolvimento de software conhecê-las e tirar as suas próprias conclusões.

Resolvi pedir a autorização e traduzir na íntegra o artigo do Jurgen (thank you Jurgen!).

Segue abaixo, a tradução do artigo, espero que gostem. 😉

Tenho certeza de que você reconhece esse problema. Você está com pressa, e ignora a rotina de verificar, ao sair de casa, se todos os seus pertences estão com você. Meia hora depois você está dirigindo de volta para casa, rosnando e xingando porque você esqueceu sua carteira, e agora está ainda com mais pressa do que estava antes.

Creio que a disciplina é uma das duas essenciais dimensões de um artesão. Qual impressão você teria de um piloto que se esquece de verificar regularmente os motores do avião? Ou um cirurgião que às vezes não tem tempo para lavar as mãos? Ou um ator em pleno palco, que às vezes não sabe as suas falas? Como consumidor, ou paciente, você aceitaria a desculpa: “Desculpe, eu estava com pressa?”

A importância da disciplina em qualquer ofício é evidente. Gerald Weinberg escreveu sobre o Efeito Boomerang nas pessoas que não seguem procedimentos: uma parte da garantia de qualidade é, simplesmente ignorada, o que acaba formando o seguinte efeito dominó:

  1. Aumento do número de problemas no produto que está no mercado;
  2. Aumento do número de problemas reportados pelos clientes;
  3. Sobe o número de interrupções de emergência;
  4. A pressão de tempo na equipe de desenvolvimento aumenta;
  5. E por fim mais procedimentos começam a ser ignorados.

Nós todos sabemos por experiência própria, que no fim das contas, ignorar a disciplina faz você ir mais devagar, não mais rápido.

No mesmo sentido, Mary e Tom Poppendieck descrevem que uma equipe de desenvolvimento de software não pode ser rápida, sem se preocupar em colocar qualidade em seus produtos. Ignorar checklists e procedimentos  só faz parecer que você está indo mais rápido, no início. Mas muito em breve, a falta de qualidade no seu produto, vai fazer você ir mais lento.

Weinberg descreveu seis níveis de maturidade para os seguintes processos:

  1. Perdido: “Nós nem sequer sabemos que estamos realizando um processo”;
  2. Variável: “Nosso trabalho depende de que como estamos no sentindo naquele determinado momento”;
  3. Rotineiro: “Seguimos nossas rotinas (exceto quando entramos em pânico)”;
  4. Guiado: “Escolhemos dentre as nossas rotinas, aquelas que trazem melhores resultados”;
  5. Premeditado: “Estabelecemos rotinas baseado nas experiências vividas com elas”;
  6. Coerente: “Todos estão envolvidos na melhoria de tudo o tempo todo.”

Weinberg usou esses seis níveis para classificar as organizações, mas eu prefiro qualificar somente os indivíduos de acordo com as suas atividades específicas. Qualquer coisa que acontece com uma organização é resultado emergente da interação entre as pessoas, muitas delas tem diferentes níveis de disciplina para diferentes atividades. Às vezes sou elogiado pela minha disciplina na escrita de um livro, que pode ser de nível 5 (premeditado) ou mesmo nível 6 (coerente). Mas, ao mesmo tempo, se você ouvir alguém xingando e gritando, pode ser que seja eu voltando para pegar a minha carteira, uma atividade que, aparentemente, está ainda no nível 1 (perdido). (Ou poderia ser meu esposo. Surpreendentemente, enquanto eu estava reescrevendo este parágrafo, ele voltou para recuperar sua carteira, depois de ter deixado a casa dez minutos antes …)

Uma combinação similar dos seis níveis foi introduzida por Ross Pettit da ThoughtWorks, que nomeou seus níveis: Regressivo, Neutro, Colaborativo, Operacional, Adaptável e Inovador. O significado dos seis níveis de Pettit é um pouco diferente, mas, como Weinberg, ele parece estar indicando níveis de maturidade na seleção e aplicação de processos.

A segunda característica essencial do artesão é a habilidade. Um desenvolvedor de software habilidoso pode ainda se dar ao luxo de ser indisciplinado, já um desenvolvedor disciplinado não é necessariamente habilidoso. Sendo assim, parece-me que o nível de habilidade da pessoa é uma outra característica que podemos utilizar para classificar a maturidade.

Há duas abordagens similares para indicar o nível de habilidade dos artesãos e artesãs: O sistema de guilda, que decorre da Europa medieval, especifica três níveis para as pessoas que treinam uma arte particular: aprendiz, artesão e mestre artesão. Este sistema é praticamente o mesmo que a variante japonesa Shuhari que descreve os três estágios dos praticantes de uma arte marcial: Shu, Ha, e Ri.

Em ambos os sistemas, as pessoas classificadas no primeiro nível estão aprendendo técnicas fundamentais, já as classificadas no segundo nível focam nas exceções e reflexões, enquanto não é necessário pensar muito, e tudo isso vem naturalmente, para as pessoas que estão no terceiro nível.

Nesta figura você pode ver que eu sou melhor como motorista, do que como escritor. Já faz 20 anos que eu dirijo, enquanto só faz 2 anos que escrevo. Mas a minha disciplina diária, como escritor, é melhor.

Quando desenhamos as duas características, disciplina e habilidade, chegamos a um diagrama bem útil para os artesões. O diagrama retrata bem que a maturidade pode ser medida em duas direções.

A habilidade pode ser perdida, com o envelhecimento, lesões físicas, ou avanços tecnológicos, já a disciplina pode ser perdida através da desmotivação ou distrações. Artesões necessitam de ambas características, portanto, os gerentes precisam se preocupar com as duas.

Revisado por André Pantalião.

Fique por dentro das novidades, assine o feed do QualidadeBR.

P.S.: Obrigado ao Fernando Fontes, por ter compartilhado o artigo no Google Reader. 🙂