Feeds:
Posts
Comentários

Bem, demorei mais do que havia planejado para escrever esse post. Nesse post eu vou falar sobre TDD com Test Doubles.

Para começar a apresentar os conceitos de Test Doubles, pedi para eles desenvolverem uma aplicação simples que deveria se conectar a um web-service que eu estava disponibilizando. Todos desenvolveram a aplicação utilizando TDD, so far so good. Então eu alterei o código do meu web-service, em um momento dei um sleep de 180 segundos e depois fiz ele lançar uma exceção.

Utilizei essas duas situações para mostrar um exemplo onde a utilização de Test Doubles: quando o sistema/classe depende de um recurso externo e/ou lento (acesso a rede ou disco por exemplo). Em seguida, eles fizeram outros testes, agora utilizando um mock e outro utlizando um stub que nós criamos.

Continuando comentei com eles outros benefícios de se utilizar Test Doubles, como o fato de você poder testar uma classe, sem que todas as classes do qual ela depende já estejam implementadas. Por exemplo, utilizando a idéia do web-service, se você está implementando uma classe que irá utilizar um cliente do web-service para pegar uma lista de tags para apresentar quais são as tags mais utilizadas. Abaixo um pedaço de código, demonstrando como a classe utiliza o cliente do web-service.

class TagsGenerator {
	private $client;
	public function __construct(WebServiceClient $client){
		$this->client = $client;
	}
	private function buildTagList(){
		$list = $this->client->getTagList();
                // código omitido
	}
        // demais métodos omitidos
}

Claro que você está sempre programando para a interface, então WebServiceClient é uma interface e não uma classe. Veja então que eu vou poder testar essa minha classe, antes mesmo que haja alguma implementação para a interface WebServiceClient. Aproveitei também esse exemplo para comentar mais sobre inversão de controle(IoC). Abaixo um exemplo de um método de teste.

	public function testShouldReturnMusicAsTopOneTag(){
        $stub = $this->getMock('WebServiceClient');
        $stub->expects($this->any())
             ->method('getTagList')
             ->will($this->returnValue(array('Music','Games','Videos')));
        // aqui, usando IoC e um stub eu posso testar
        // minha classe que constrói a lista de tags
        $generator = new TagsGenerator($stub);
        // resto do teste abaixo
	}

Outro benefício que pode ser alcançado com uma boa OO e test doubles é o isolamento entre testes. Além disso, comentei sobre o Mocks Aren’t Stubs do Fowler, que fala sobre as diferentes formas de se utilizar TDD, classicist ou mockist e citei que na minha opinião a melhor abordagem é saber utilizar bem as duas formas de TDD.

Final se semana escreverei outro post, comentando como foi feito o TDD com banco de dados.

Continuando o assunto do post anterior, dessa vez Uncle Bob resolve dar sua opinião sobre o booom de projetos ágeis” que estão aparecendo (e falhando) por todo lado.

Uncle Bob em Dirty Rotten ScrumDrels.

James Shore pra mim é um daqueles autores que quando ele fala em Agile, ele leva em consideração o que Agile é e não quanto dinheiro ele pode ganhar em suas consultorias, então é uma opinião a ser respeitada.

No Brasil, as listas de discussões viraram local para se fazer propaganda do curso X, da consultoria Y ou site Z faz tempo, a única lista onde esse pessoal não se criou, foi a xp-rio (lá você pode fazer perguntas sabendo que o pessoal vai te responder sem pensar que você é um possível cliente). Opiniões são completamente baseadas em “quantos clientes eu posso conseguir afirmando que X é melhor que Y?”.

Toda semana vejo aparecer um curso de Scrum novo, ministrado por alguém certificado PMP e “Certified Scrum Master”, acho que isso acaba gerando uma boa parte do problema. Sua empresa quer Agile com CMMI ? Sem problemas tá cheio de consultor por aí pronto para quebrar os valores ágeis somente para ganhar um dinheiro da sua empresa.

Como o Milfont já havia previsto, o Scrum está se tornando cada vez mais o PMBoK de jeans.

Sinceramente, se você esta querendo iniciar com desenvolvimento ágil, Scrum, extreme programming, Lean, crystal… utilize as listas de discussão para fazer perguntar e tirar suas dúvidas. Contudo filtre bem as respostas, tenha em mente que tem muita gente ali que precisa de convencer que X é melhor que Y ou que X é perfeito para seu ambiente, muitos vão mentir deformar o movimento ágil o quanto for necessário, somente para conquistar seu dinheiro :)

Isso não quer dizer que você não deva contratar um coach para ajudar com o desenvolvimento ágil em sua empresa, isso com certeza é algo que vai acelerar bastante as coisas. Contudo, preste atenção em quem você está contratando.

Voltando agora para o James Shore, ele escreveu um post que relata muito bem um fato que vem acontecendo devido a toda essa fama do agile, não vou repetir o que ele escreveu lá, então o link é esse The Decline and Fall of Agile.

The Clean Code Talks

Achei duas apresentações que Miško Hevery fez no google (onde ele trabalha), estão no youtube com o título The Clean Code Talks (nome bastante sugestivo), por enquanto só assisti uma e achei boa, então ficam aqui os vídeos.

Notícia rápida, a partir de 1º de janeiro de 2009, para você ser um Certified ScrumMaster você deverá fazer uma prova!

Parece que estão tentando dar algum crédito ao título, mas acho que vai continuar sendo somente um comprovante de participação em um curso.

Mais informações, você encontra aqui.

The role of leadership in software development, é uma apresentação feita em 06/05/08 por Mary e Tom Poppendieck. Então, observando quem são os 2 palestrantes, você já sabe que realmente deve assistir isso.

Depois de uma semana afastado, retornei a empresa pra ver como as coisas estão andando e para continuar o treinamento. Agora para apresentar o test driven development.

Assim que entrei na empresa, tive uma boa supresa. Eles colocaram mais um quadro na empresa. Agora eles tem um quadro para as tarefas e outro onde ficam os itens das retrospectivas e os itens mais importantes do product backlog.

Além disso, pelo que observei está tudo indo bem, as coisas não estão ótimas, contudo eles estão melhorando aos poucos e isso é o importante.

Como já comentei aqui no blog, eles estão utilizando PHP para desenvolver o projeto novo deles. Então fui dar uma olhada no que havia de novo no PHPUnit, preparei uma apresentação bem simples para explicar os conceitos do TDD.

Comecei com o clássico “TDD não é teste, TDD é uma forma de desenvolver o sistema de uma forma incremental”. Repeti isso umas cinco vezes no início e mais algumas durante os exercícios. Depois disso expliquei o ciclo do TDD, comentei que para classe desenvolvida, deve existir outra classe de testes e falei sobre design, a mudança que é evitar aquele pensamento enorme inicial de como algo deve ser para pensar em um design que vai evoluindo junto com a classe.

Depois fui para uma parte mais prática, expliquei que toda classe de teste vai ser um sub-classe de uma classe do PHPUnit (o que é algo ruim, no JUnit4 não precisa fazer isso) e que todo método de teste tem a assinatura:

public function testMetodoDeveTerComportamentoTal{}

Algo que eu também dei bastante ênfase, é no nome do método de teste. Como o PHPUnit não permite a utilização de contextos, o nome deve ser grande e claro, pra ser facilmente entendido o que o teste está testando. Além disso, também lembrei eles que cada teste deve testar apenas um item. Pra exemplificar isso citei uma classe imaginária Calculadora, nos testes você pode ter os métodos testDeveSomar500Com300 e testNaoDevePermitirDivisaoPorZero mas não deve ter apenas um método de teste que garanta que a calculadora deve somar e não aceita divisão por zero. Ou seja, One Assertion Per Test.

Depois disso já pedi para eles abrirem a IDE por eles utilizada (Zend Studio), ela já tem um suporte legal para o TDD, embora utilizar o PHPUnit que vem junto com a IDE é sofrível, muito, muito lento.

Então o primeiro exercício foi criar uma calculadora. Desenvolver uma calculadora é extremamente simples, mas a idéia era que eles tivessem algum contato com o PHPUnit sem se preocupar com o problema que iriam resolver.

Ao criar um novo TestCase, a IDE já criou os métodos setUp() e tearDown() e já fez da classe de testes uma sub-classe de PHPUnit_Framework_TestCase. Aproveitei esse momento para explicar que o método setUp() é chamado sempre antes de cada teste e o tearDown() é chamado sempre depois que cada teste é executado. Também expliquei qual o motivo de existirem esses métodos.

Continuei o exercício explicando as funcionalidades a medida que era necessário. Depois que eles criaram a assinatura do primeiro teste, expliquei como é feito a asserção no PHPUnit e apresentei as mais utilizadas (assertEquals assertTrue assertFalse assertNull assertNotNull). O exemplo da calculadora foi útil também para apresentar como funciona a asserção de exceções no PHPUnit.

No final desse exercício, eles tinha uma boa idéia de como funciona o PHPUnit e como os testes do TDD podem ajudar na garantia que não seja adicionado nenhum bug num sistema com testes. Contudo eles ainda não tinham idéia de como o TDD pode ajudar no desenvolvimento.

Isso eu deixei para o segundo exercício. Deixei 2 horas separadas para esse exercício, que basicamente funcionava da seguinte forma.

Eu, cliente, quero um sistema no qual eu entre um valor numérico, por exemplo 327 e o sistema deve retornar o número por extenso, no caso, trezentos e vinte e sete. Os número podem variar de 0 até 999.999 com duas casas decimais.

Escolhi esse exercício pois considero que o desenvolvimento incremental do TDD se beneficia muito de um exercício como esse.

A primeira reação deles ao ouvir o exercício foi pegar um papel e começar a esboçar a solução, com exceção de um desenvolvedor, que foi para o google procurar algo pronto. Nesse momento pedi para eles sentarem em duplas e conversei para mostrar como TDD ajuda a resolver o problema. Comecei dando a idéia de resolver primeiro de 0 até 10, depois de 11 até 20. Mostrando pra eles que quebrando o problema iria ficar muito mais simples para resolver.

Eles aceitaram a idéia e começaram a escrever código. Foi muito legal que eles pegaram o espírito do TDD, eles foram desenvolvendo um teste de cada vez, fazendo cada teste passar antes de evoluir o código, além de ficar refatorando constantemente.  As duplas também eram trocadas a cada 30 minutos,  para garantir um ritmo parecido em toda equipe.

No final de 2 hoas o resultado foi muito bom. Todos haviam gostado do que haviam produzido e de como haviam produzido. Diferentemente do que aconteceu comigo, que demorei uns 3 meses para cair na real com TDD, aparentemente eles pegaram bem o espírito e gostaram. Já perguntaram como eles vão utilizar no projeto atual deles!

Abri um espaço para dúvidas no final, contudo somente uma apareceu.

TDD é legal, mas quando o código é muito simples, não preciso fazer isso, não é?

A minha opinião é que mesmo códigos muito simples devem ser testados. Códigos muito simples geralmente possuem testes muito simples, então o tempo para escrever somente o código da classe ou a classe e o teste vão ser pequenos. Outro problema é que é comum ter um código simples no início, contudo conforme o sistema cresce o código também cresce. Por último, TDD ajuda a ter um código sem bugs e mesmo em códigos simples podem escapar alguns bugs. Então para mim código simples está longe de ser um motivo para não utilizar TDD em uma classe.

É isso, na próxima semana vou falar sobre dummies, fakes, stubs e mocks.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.