É melhor focar no problema? ou na solução?

Cabra-cega – Imagem Retirada de http://fadadacaixinhademusica.blogspot.de/

Cabra-cega é uma brincadeira de criança onde alguém coloca uma venda nos olhos e fica com uma vara na mão para tentar acertar um vaso de barro (cheio de doces e gostosuras) e quebrá-lo, dessa forma não só você ganha os doces, quanto todos ao seu redor tb correm para os doces e assim todos saem ganhando! Não sei no restante do Brasil, mas pelo menos em Recife essa é uma brincadeira bem comum. O detalhe dessa brincadeira é que todos os outros ao seu redor ficam dando dicas apra vocês chegar mais perto, e eventualmente acertar o vaso.

Trazendo isso para nossa realidade de TI, um ponto que venho percebendo com uma certa frequência  é que geralmente estamos fechando projetos e contratos onde nosso cliente chega até nós com uma “solução” para o problema dele, e nós geralmente vamos direto atacar essa pseudo-solução! Isso acontece mais frequentemente em casos onde o cliente tem um certo conhecimento de TI, de desenvolvimento de software, então ele já chega com a solução bolada na sua cabeça! E como cada vez mais temos gente que entende [um pouco que seja] de TI, temos essa situação acontecendo cada vez mais.

Me sinto um pouco jogando cabra-cega. Estamos lá, escutando as dicas e as direções dos outros, mas não sabemos exatamente ONDE está o problema! Estamos com uma venda nos olhos tentando caminhar na direção que os outros estão gritando! E eis que chega o grande conselho desse post (que até parece um pouco óbvio):

Tire a venda dos olhos!!

Faça isso, por favor! Procure entender sempre o problema que está por trás de uma solução proposta, entenda o porquê por trás daquilo e procure identificar outras possíveis saídas para aquele problema. Talvez a solução proposta inicialmente pelo cliente seja realmente a melhor, mas talvez seja a pior também. E você só vai saber se tirar a venda dos olhos! TI é pensar! Muitas vezes somos pagos não para implementar algo para o cliente, mas para PENSAR na situação dele e identificar saídas viáveis!

Vale salientar que isso se aplica a diversos contextos dentro do desenvolvimento de projetos, e ainda mais, se aplica a diversas outras áres além de TI!

Anúncios

Cargo cult, eXtreme go horse e afins

Depois de alguns anos escrevendo código, e também, observando códigos de outras pessoas, meus códigos antigos e código legado percebi alguns comportamentos e padrões entre o aptidão e/ou tempo de experiência X design do código das pessoas.

Investigando esses padrões, consegui entender melhor os “porquês” da incidência, em projetos grandes e bem financiados, de fenômenos como Cargo cult, eXtreme go horse, programação orientada a gambiarra e afins.

Contextualizando – Cargo Cult, descrito por Steven C. McConnell no livro Code Complete, é o fenômeno cultural observado em tribos indígenas/aborígenes, durante a segunda guerra mundial, que envolviam impactos entre duas civilizações, sendo uma moderna em aspectos tecnológicos e outra primitiva. Durante a guerra, soldados americanos necessitavam pousar em ilhas desertas para recarregar combustíveis ou armar mísseis, entretanto muitas dessas ilhas visitadas eram habitadas por esses povos. Ao ocorrer o choque das civilizações, os primitivos imaginavam que os soldados, com todo seu aparato, fossem deuses. Depois da partida da civilização moderna, os indígenas costumavam fazer rituais em determinados períodos do ano com o intuito de invocar os supostos deuses soldados, mudando assim o comportamento cultural/religioso do local.

Ao trazemos esse conceito para computação temos situações clássicas que vivemos no nosso dia a dia, talvez a mais popular seja : Ao perguntar a um desenvolvedor/gerente/engenheiro: – Para que serve esse pedaço de código? Ele te responde: – Não sei, mas não mexe aí! Pode parar de funcionar! Em outras palavras o desenvolvedor possui um tipo de ritual para realizar determinadas tarefas, como inserir código legado, bibliotecas, classes que não necessariamente são úteis para a implementação do mesmo, acarretando a incompreensão sobre o sistema de forma geral.

Para falar de eXtreme go horse temos que esquecer de qualquer boa prática, Scrum, Kanbam, Pair Programming ou qualquer coisa que lembre engenharia de software, isto é, se focar em escrever código e vencer o prazo. Infelizmente é uma realidade triste do mercado, que muitas vezes pode indicar falta de comprometimento do time e falta de alinhamento de interesses entre equipe/empresa ou má gestão do líder.

A verdade é que o caminho para esses cenários(caóticos) são convergentes podendo ser resumidos em falta de maturidade da parte do líder ou desenvolvedor, insegurança, pressão, contratos com prazos irreais, falta de comprometimento da equipe, etc. Muitas vezes esses motivos também podem acarretar um efeito dominó, piorando a situação exponencialmente.

Claro, podemos determinar inúmeras hipóteses para a solução do problema de desenvolvimento de software, entretanto, é fato que a solução está bem longe de determinar metologias rígidas ou mudar conceitos das mesmas. Temos que ir além, precisamos mudar conceitos, quebrar paradigmas, criar um time com determinação e com aptidão, mensurar e explorar potenciais, trabalhar com dificuldades, amadurecer a equipe e acima de tudo cair na real.

BdB Recomenda – Aprenda a programar online e sem custos

O BdB Recomenda de hoje apresenta um projeto muito interessante, chamado Codeacademy – Learn to Code. O projeto criado a partir das frustrantes experiências enfrentadas por Zach Sims e Ryan Bubinski. Cansados de vídeos e tutorias pouco eficientes, eles criaram o Codeacademy, como uma maneira extremamente interativa de aprender a programar, através da prática direta da programação.

Codeacademy

Para começar o aprendizado basta se cadastrar no site (pode utilizar a própria conta do facebook) e começar a realizar os exercícios. Os exercícios são conduzidos de maneira gradual, apresentando os conceitos fundamentais para aprender a programar de maneira prática, além disso, o ambiente possui um fórum de ajuda bastante participativo e dicas para ajudar na resolução dos problemas.

Code Year - 2012

O projeto é audacioso e deseja ensinar programação a pessoas de diferentes áreas de atuação. Segundo o próprio Zach “As pessoas têm um desejo genuíno de compreender o mundo que vivemos. Eles não querem apenas usar a Web; Eles querem entender como ela funciona.”

O custo para começar o aprendizado é ZERO. Atualmente estão disponíveis cursos de JavaScript e HTML.

E não esqueça de nos seguir no Twitter e juntar-se a nós no Facebook para ser informado das novas atualizações do blog!

Como Automatizar Testes de aplicações Android – Parte 1 (O desafio)

Olá pessoal,  este ano vou começar com uma pequena série de posts e um pouco DIFERENTE dos posts habituais para falar mais uma vez de teste na prática. Obviamente para ser diferente eu vou deixar este primeiro post um desafio para todos assim como eu tive um desafio no final do ano passado para  preparar e ministrar uma disciplina de teste de software para uma turma de desenvolvedores que estava participando de um curso de desenvolvimento para Android. Preocupado em deixar as aulas de teste mais interessantes,  eu arrisquei adaptar meu material para algo que fosse bastante prático e relevante para essa turma e por isso dei uma estudada no Android e como desenvolver aplicações e criar testes automáticos para o mesmo e acabei descobrindo algumas coisas que o SDK disponibiliza que gostaria de compartilhar com vocês.

Antes de começarmos a desenvolver testes para o Android, preciso passar  algumas informações relevantes para que todos possam conseguir ter um entendimento completo de como automatizar alguns testes para aplicações em Android e também consigam completar o desafio que deixarei neste post.

Para podermos automatizar testes para aplicações Android, precisamos entender alguns de seus componentes básicos, que são: Activities, Services, Content Providers e Broadcast Receivers.

Activities – Uma activity é um dos componentes do Android mais usados nas aplicações pois ele é que  fornece uma tela com a qual os usuários podem interagir. Por exemplo dicar um número de telefone, escrever uma sms, ou visualizar um mapa. Para cada activity é dada uma “janela” na qual “desenhamos” uma  interface de usuário. As “janelas” normalmente preenche toda a tela, mas também podem ser menores do que a tela e flutuar em cima de outras “janelas”.

Services – São componentes de aplicação que podem executar operações de longa duração em segundo plano, portanto não fornecem uma interface de usuário. Um serviço pode ser iniciado por uma aplicação e ele continuará a ser executado em segundo plano, mesmo se o usuário trocar para outra aplicação.

Content Providers – Como o nome já explica, Content Providers é componente responsável por armazenar e recuperar os dados e torna-los acessível para todas as aplicações, ou seja são os provedores de conteúdo. A única forma de compartilhar dados entre aplicações no Android é através de content providers, pois não existe área de armazenamento comum que todos os pacotes Android podem acessar.

Broadcast Receivers – É um componente que responde a anúncios de todo o sistema de broadcast. Muitos brodcast provenientes do sistema, como um broadcast anunciando que a bateria está fraca ou uma sms foi recebida. As aplicações também podem iniciar os broadcast, por exemplo, para permitir que outras aplicações saibam que alguns dados foram disponibilizados para eles usarem. Os broadcast receivers também não possuem interface de usuário, mas eles podem criar uma notificação de barra de status para alertar o usuário quando um evento de broadcast ocorreu.

Bem , depois desta uma breve introdução, vamos por a mão na massa e desenvolver uma calculadora bem simples para que depois possamos automatizar alguns testes para essa aplicação. Quem quiser se aprofundar um pouco mais sobre como desenvolver aplicações para Android pode dar uma olhada neste site para desenvolvedor da Google.
Essa calculadora que desenvolvi possui algumas restrições para cada uma das operações básicas (somar, subtrair, multiplicar e dividir) com o objetivo de exemplificar o uso de algumas técnicas de criação de teste para os alunos da turma e essas técnicas de criação de testes não vem ao caso neste post nem nos seguintes que virão, o nosso objetivo aqui é explicar como desenvolver e automatizar testes para aplicações Android. Outro fator relevante que devo deixar claro é que eu utilizei o eclipse com o plugin ADT para desenvolver meu projeto em Android. Para saber como configurar seu ambiente, veja aqui.
Após configurar o ambiente vamos ao nosso desafio:
Vou deixar alguns requisitos básicos da nossa calculadora para que você possam tentar desenvolver e no próximos post  disponibilizarei o nosso código e explicarei passo a passo como o desenvolvi.  Logo abaixo segue os requisitos da aplicação que vamos automatizar os testes mais na frente:

Nome: Aplicativo Calculadora Fajuta 

[REQ001] Tela principal deve possuir dois campos (EditTexts) para inserir valores e um botão (Button) de cada  funcionalidade da calculadora, que são:
– SOMAR
– SUBTRAIR
– MULTIPLICAR
– DIVIDIR

[REQ002] A operação SOMAR  só efetua soma de números entre 0 e 10, pois a calculadora é fajuta. O resultado deve ser mostrado em um texto (TextView) no canto inferior da tela.

[REQ003] A operação SUBTRAIR é um pouco mais evoluída e consegue efetuar a subtração de números entre 0 e 50. O resultado deve ser mostrado em um texto no canto inferior da tela e caso seja um resultado negativo, o mesmo deve estar na cor vermelha.

[REQ004]  A operação MULTIPLICAR  deve multiplicar  apenas números pares.

[REQ005] A operação DIVIDIR, da mesma forma da operação Somar, só efetua a divisão de números entre 0 e 10.

E claro que qualquer dúvida por mais simples que seja, podem comentar aqui neste post e terei o prazer de responder o mais rápido possível. Para os mais tímidos, podem me mandar um email que tem no meu perfil aqui do Bdb.  Boa sorte a todos !!! 🙂

Imagine um mundo SEM bugs no software

Na indústria de software estamos habituados a ideia de que todo software possui defeitos e que pouco podemos fazer para mudar isso. No vídeo a seguir, de apenas 9 minutos, Jeff McKenna, co-fundador do Scrum apresenta uma visão radical: um mundo sem bugs no software. O vídeo foi extraído de seu próximo livro “Conscious Software Development.”

O vídeo é excelente e nos faz pensar principalmente na atitude em relação aos bugs que temos em nossos projetos. Segundo Jeff, não basta corrigirmos os defeitos encontrados precisamos entendê-los e aprender com eles, só assim construiremos sistemas SEM defeitos.

Assista ao vídeo. Em seguida, destaco os principais pontos abordados por McKenna.

 

Temos sistemas de gerenciamento de defeitos, realizamos triagens, mas será que em algum momento pensamos sobre o que eles são? ou como surgiram? como fazer para não surgirem mais?”

Segundo Jeff, temos sido muito complacentes com os defeitos, acreditamos que existem muitos, e que os mesmo são parte de todos os sistemas. Porém, o autor não acredita nisso e nos convida a imaginar um mundo SEM bugs de software.

“Podemos atingir números bem menores do que as pessoas consideram razoável, e isso pode ser feito de maneira simples”

McKenna indica que, a simples conscientização a respeito dos bugs já possibilita imensos ganhos. Precisamos entender porquê eles estão presentes e agir para evitar novas falhas.

Como diminuir a quantidade de bugs?

– Reduzir o tempo entre a introdução de um bug e sua correção

A medida leva em conta o momento no qual o bug foi introduzido no sistema e não o momento em que o mesmo foi detectado. Para isso é necessário utilizar as ferramentas de controle de código, assim, após identificado o motivo do defeito podermos voltar versões do código e identificar o momento em que ele ocorreu.

Olhando para o exato momento em que o erro aconteceu podemos aprender a escrever menos bugs. Porque esse é o verdadeiro objetivo.”

O objetivo não é encontrar mais bugs e a função dos analistas de qualidade não se resume a isso.

“Classificação e triagem de feitos são uma perda de tempo, em termos de aprendizado sobre como escrever menos bugs”

Segundo McKenna, pouco importa a severidade do defeito e suas características, pois geralmente o critério de correção está diretamente ligado a questões de negócio, como a importância de um determinado cliente. Logo, se estamos tentando aprender a escrever menos bugs, não há diferença entre os mesmos, sejam eles de alta ou baixa prioridade todos são comportamentos não esperados do sistema.

“Corrigir os defeitos era a atividade de maior prioridade”

Jeff, exemplificou suas recomendações com as seguintes práticas executada em um de seus projetos:

1- Sempre que um bug surgisse, a primeira pessoa que estivesse livre passaria a trabalhar no defeito. Onde, um profissional era considerado livre quando terminava a tarefa que estava executando no momento. Bugs possuem prioridade mais alta, que todas as demais tarefas ainda não realizadas. Desse modo, no máximo em alguns dias o defeito era analisado.

2 – Corrigir e entender o problema. A mais alta prioridade era a correção do defeito, associado a criação de novos testes automáticos. Porém, o mais importante é você falar porquê aquele bug estava lá, a razão do mesmo ter ocorrido.

“O que queremos fazer é encontrar o bug o quanto antes para que possamos consertá-lo o mais cedo possível e provar o aprendizado”

Para McKenna, temos o prazo máximo de até 6 meses da introdução de um defeito, para podermos aprender algo através de sua correção, após isso a oportunidade de aprendizado terá sido desperdiçada.

“O objetivo real é escrever software SEM defeitos.”

E para atingir esse objetivo, a principal característica que temos que desenvolver é a de olhar sempre para frente. Se ficamos sempre olhando para trás 6 meses, 1 ano, analisando um código que não vemos a muito tempo, isso literalmente é perda de tempo. Então, o que queremos fazer é olhar para frente a todo o momento e ter a atitude de ZERO defeitos.

“Um bug é algo que você esmaga imediatamente.”

Ao eliminar rapidamente os bugs encontrados acabaremos com tarefas, como a priorização de defeitos. Afinal, a quantidade de bugs pendentes será sempre pequena e desse modo o foco poderá ser maior no que está sendo construído.

Este é um vídeo para ser visto diversas vezes, e se conseguirmos absorver sua ideia central, penso que, poderemos melhorar ainda mais nossos processos e principalmente nossa atitude.

Conheci esse vídeo primeiramente no Software Testing Club, uma excelente fonte de informações para testadores, com bons textos e vídeos sobre a área. Espero que tenham gostado.

…………………………………………………………………………………………………………………………………………..

Agora você já pode acompanhar as novidades do BdB pelo Facebook, acesse e curta nossa página.

Cobertura de código, como ?

No meu ultimo post falei sobre a importância da cobertura de código e o quanto ele é comumente utilizado com critério de saída nas primeiras fases de um projeto de software. Lá eu falei das duas técnicas de medição de cobertura de código mais usadas, são elas a Statement Coverage e Decision Coverage. Agora venho escrever este post para cumprir a promessa que deixei no ultimo post, que é mostrar na prática como utilizar uma ferramenta para fazer a medição da cobertura dos testes, neste exemplo, unitários.

A ferramenta que utilizei para exemplificar as duas técnicas acima foi um plugin para o Eclipse chamada CodeCover.
CodeCover é uma ferramenta de teste glass-box grátis e desenvolvido em 2007 na Universidade do Stuttgart.

Para iniciarmos o exemplo, vou mostrar uma classe (Example.java) com dois métodos bastante simples para facilitar o entendimento das técnicas utilizadas.

public class Example {

	public void firstExample(int a, int b) {
		int c =  a + (2*b);
		if (c>50){
			System.out.println(c);
		}
		System.out.println("Fim 1");
	}
}

Abaixo temos os primeiros testes unitários escritos na classe ExampleTest.java para verificar o funcionamento do método firstExample(int a, int b).

	@Test
	public void testFirstExample() {
		try {
			ex.firstExample(20, 15);
		} catch (final Exception e) {
			Assert.fail();
		}
		Assert.assertTrue(true);
	}

	@Test
	public void testFirstExample1() {
		try {
			ex.firstExample(20, 25);
		} catch (final Exception e) {
			Assert.fail();
		}
		Assert.assertTrue(true);
	}

Para medir a cobertura dos testes acima apenas precisamos marcar as classes Example e ExampleTest para ser usado pela ferramenta de Medição de Cobertura ( Figura 1)

Tela 1 - Clique para ampliar

Após marcar as classes envolvidas (classe de teste e classe a ser testada), iniciamos a execução dos testes no modo CodeCover para JUnit. Ao finalizar a execução dos testes, aparecerá uma aba chamada Test Sessions, no qual podemos marcar os teste unitários executados e visualizar as linhas de código da classe testada que foram exercitado pelo teste. Na tela 2 abaixo podemos ver que o teste testFirstExample exercitou apenas 3 linhas de código de um método que possue 4 linhas de código.

Tela 2 – Clique para ampliar
Tela 3 – Clique para ampliar

Na tela 3, quando marcamos apenas o teste testFirstExample1, verificamos que o mesmo possui uma cobertura completa do método firtExample(int a, int b). Isso quer dizer que apenas o segundo teste (testFirstExample1) é suficiente para se ter 100% de Statement Coverage, ou seja todas as linhas de código foram exercitadas.

Mas se prestar atenção na tela 3 a linha de código numero 8 da classe: if (c>50) {”  está pintada de amarelo, isto quer dizer que essa linha de código não está completamente exercitada, ou seja, esta estrutura condicional ainda precisa ser estimulada por mais teste para que outro fluxo seja tomado, e isso a gente consegue garantir quando testamos esse método com os dois teste anteriores. Olhando para tela 4 abaixo, percebemos que quando marcamos os dois testes (testFirstExample e testFirstExample1), temos 100% de cobertura  de Decision Coverage, pois ambos os teste exercitaram a linha 8 para que o fluxo fosse tomado tando para que C fosse maior que 50 e C fosse menor que 50, exercitando assim a estrutura condicional (if) pode completo.

Tela 4 – Clique para ampliar

Analisando direitinho, podemos perceber que toda suíte de teste que cobre 100% de decision coverage, também cobre 100% de statement coverage, no entanto o inverso nem sempre  é verdade.

Espero ter esclarecido melhor o conceito de Statement e Decision coverage com os exemplos acima. O que vocês acharam ? Caso tenham dúvidas relacionadas a este tema, por favor utilizem o espaço de comentário para que possamos discutir mais sobre o assunto.

Obrigado e até breve !!!

A Metáfora da Dívida Técnica: O preço das gambiarras

O XP (eXtreme Programming) tenta se utilizar de metáforas no desenvolvimento de software para trazer o entendimento de todos para mais próximo do mundo real. Metáforas são um instrumento poderoso.

Recentemente compareci na QConSP, e no meio de tantas palestras uma me chamou a atenção em particular, e se tratava justamente da explicação de uma metáfora (que acredito ser maravilhosa para se comunicar com a gerência ou clientes).

Todos nós sabemos o que é uma dívida no mundo real, e todos nós eventualmente entramos em dívidas, seja um financiamento de um imóvel que você vai pagar por 300 meses, ou um carro que você vai ficar endividado por 60 vezes. O pior de tudo é que além da dívida normal, você irá pagar um montante de juros absurso dependendo do tamanho da dívida que você está assumindo.

Existem as dívidas responsáveis ou conscientes como as citadas acima mas também existem dívidas inconscientes ou não responsáveis que são piores, pois surgem de uma hora para a outra sem te dar tempo para pensar se desejava assumir essa dívida ou não (ex: alguém gastando desordenadamente no cartão de crédito e quando vai ver a fatura fica surpreso).

Pois bem, no desenvolvimento de software é a mesma coisa!

Você tem que adicionar uma funcionalidade no seu sistema. Nesse momento  você enxerga duas formas de fazer isso: Uma forma é rápida de fazer, mas é meio bagunçada e com certeza você iria ter mais trabalho ainda no futuro para modificar aquilo. A outra forma é mais elegante e organizada, porém vai demorar mais. Isso lhe parece familiar?! Esse trade-off acontece o tempo todo no desenvolvimento de sistemas, mas o que esquecemos é das dívidas que assumimos quando escolhemos a forma mais rápida e mais bagunçada (ex.: gambiarras)!

Parece que não temos ciência que todas as vezes que assumimos uma dívidas técnicas no sistema, mais lento o desenvolvimento se torna, mais difícil de modificar as funcionalidades existentes, mais difícil adicionar funcionalidades novas (como mostra o primeiro gráfico) e muito mais provável que uma mudança qualquer tenha impactos indesejados e desconhecidos. Temos que estar cientes das dívidas que assumimos no dia-a-dia do desenvolvimento de software.

Ah, então é por isso que não conseguimos aumentar a velocidade do time depois de tantas sprints??

Talvez! Aí nasce a  questão importante que é o momento que iremos pagar nossas dívidas, ou ao menos parte delas. A grande maioria dos times conhecem os lugares no sistemas que estão com dívidas, e é preciso separar um tempo para PAGAR essas dívidas caso contrário os juros só fazem aumentar. Enquanto as dívidas não são pagas, nós nos deparamos com o cenário onde sprint após sprint, vamos fazer menos coisas (vide o segundo gráfico) pois agora é muito mais difícil modificar o sistema com tantas dívidas do que era no início do desenvolvimento quando não tínhamos dívida ou as poucas dívidas que tínhamos eram controláveis.

Cuidado com suas dívidas técnicas ou elas vão afundar você e seu projeto!