sábado, 23 de agosto de 2008

Vídeo-Palestra: Extreme Programming

Palestra recomendada para quem quer conhecer melhor como é o desenvolvimento ágil utilizando Extreme Programming. Em português (!).

Palestrante: Vinícius Manhães Teles, da ImproveIt
Evento: TDC 2008

quinta-feira, 21 de agosto de 2008

TDD na Prática - Parte II: Verificação e Confiabilidade

Como visto na Parte I, para criar código (que seja facilmente) "testável" é preferível escrever código que o testa primeiro.

Exercitar o código verificando seus limites e estados auxilia na descoberta de como o mesmo deve se comportar e traz um maior controle sobre seu funcionamento. Conseqüentemente, culmina em um maior nível de confiabilidade.

Tornar freqüente a verificação do código, de forma com que a cada alteração do mesmo ele seja novamente verificado, garante a manutenção deste nível de confiabilidade.

Verificar o código continuamente e acrescentar novas verificações à medida em que forem necessárias, além de re-executar todos os testes (teste de regressão), pode ser um processo doloroso se não for automatizado. Assim, existem diversas ferramentas que suavizam o processo, permitindo nos concentrar no que é importante.

Como o uso das ferramentas, em poucos (mili)segundos executamos todas as verificações e temos um maior grau de certeza que:

1) O novo código criado passa nos testes;

2) Após uma alteração no código, ele continua passando nos testes;

3) A alteração numa parte do código não fez outra parte do código parar de funcionar (compilar), nem deixar de funcionar como esperado (mudou o comportamento), pois ela também continua passando nos testes;

Para garantir 1) e 2) temos o Teste Unitário e para 3) o Teste de Integração e o Teste de Regressão.

Diversos frameworks de testes foram criados com esta finalidade, para cada linguagem. Em especial, os baseados na SUnit (como JUnit, CppUnit, DUnit, NUnit, etc.) são os preferidos por serem simples, poderosos e fáceis de adaptar a qualquer ambiente de desenvolvimento ou sistema operacional.

TDD, xUnit e xMock

A maioria dos desenvolvedores que adotam TDD, adotam também uma framework xUnit para execução dos testes. Não é diferente comigo, nem com este blog. Para cada linguagem há uma variedade de opções, com diversas vantagens e desvantagens a se ponderar. Por exemplo, para C++ existe também a Boost.Test, a CppUnitLite, a NanoCppUnit, a Unit++, a CxxTest e por aí vai. Tenho preferência pelas versões com maior adoção (como a CppUnit), apesar de que para determinadas aplicações, certos frameworks trazem vantagens interessantes.

Outra ferramenta importante, recomendada para usuários que já possuam alguma experiência em testes, é a de simulação de comportamento, para os chamados Objetos Substitutos, ou Mock Objects. Frameworks como jMock, MockPP, NMock, etc. etc. etc. trazem maneiras muito úteis de fazer construções que testem o comportamento esperado de objetos.

Enquanto os frameworks xUnit tem foco na verificação de estados de um objeto, os xMock tem foco na verificação do comportamento dos objetos, na interação entre os mesmos. É sempre possível simular os testes sem o auxílio de um framework, mas seu uso traz uma certa padronização na maneira com a qual os testes são construídos.

Com todas as facilidades e opções disponíveis, a adoção de um framework de testes passa a ser de extrema importância na implementação de TDD. Neste blog, você verá alguns deles em ação e saberá como a maioria deles funciona.

quarta-feira, 20 de agosto de 2008

Interação e Substituição de Objetos

Ter uma visão clara de como os objetos interagem é um fator fundamental no desenvolvimento de software orientado a objetos. É até mais importante do que saber como cada objeto funciona isoladamente.

Pensando que um software O. O. é uma espécie de teia de objetos que se interconectam, fazendo de sua interação o fator gerador do comportamento do software, mudar seu comportamento será como plugar novos objetos no lugar dos que estavam, bastando para isso que o plug esteja no formato esperado.

Simular este tipo de comportamento no software requer que tomemos algumas medidas de análise bem pensadas, estudadas, para que tudo se encaixe da maneira apropriada.

Tipos de Substituição

A substituição dos objetos pode não servir apenas para mudar o comportamento do software. Ela pode servir, principalmente, para analisar o comportamento do mesmo.

Se ao invés de plugar um objeto que precise desempenhar determinada tarefa você plugar outro que registre ou exponha como se deu a interação dos outros objetos com ele, você terá uma excelente ferramenta para análise comportamental.

Caso o objeto precise desempenhar tarefas necessitando da colaboração de outros, sendo requerida a passagem de mensagens para os mesmos, seu objeto pode simulá-la sem que seja necessário qualquer esforço adicional.

Você pode substituir o comportamento do objeto (plug) real pelo comportamento que você deseja, apenas para investigar o comportamento dos objetos (plugues) em que ele estará conectado.

Objeto Substituto

Como disse, para que o objeto substituto possa ocupar o espaço do original, basta que ele apresente o mesmo formato. Este formato do objeto pode ser descrito também como a interface do objeto, ou seja, a maneira com a qual é feita a interação com ele.

Mantendo a mesma interface, os objetos interconectados a ele não precisam ser modificados, podendo lhe referir sempre da mesma maneira.

Mock Object, Proxy e outros nomes

Ao objeto substituto são dados diversos nomes, como Mock Object (geralmente como é referenciado em TDD), Proxy (Padrão GoF), Surrogate, etc. Apesar de haverem diversas variações na maneira como são usados (por exemplo, como virtual proxies, remote proxies, smart references, etc.), todos se baseiam no sentido da substituição do objeto original.

Em suma

A substituição dos objetos para análise, teste ou mudança do comportamento é um dos conceitos mais significativos para o entendimento da criação de software testável e de objetos reutilizáveis. Entender as variações possíveis e os benefícios e problemas trazidos por cada implementação traz uma grande maturidade ao desenvolvedor e potencializa o crescimento e a manutenção de software, levando à um custo de alteração mais baixo e a melhoria da "testabilidade" do mesmo.

segunda-feira, 18 de agosto de 2008

TDD na Prática - Parte 1: Influência no Design

Para se ter uma idéia rápida de como é TDD na prática, criarei um joguinho bem simples, e de conhecimento geral, que deve servir como exemplo: o Jogo da Velha. (Se você não teve infância ou sofre de perda grave de memória, consulte as regras aqui. :)

Para verificar se a implementação do jogo estará correta, escreverei código que a teste. Mas daí vem algumas questões:

  • Como terei certeza de que o código que escreverei poderá ser testado de forma adequada ?
  • Como saber que não vou ter que modificar meu código depois só pra torná-lo "testável" ?
  • O design do código será apropriado o suficiente para me dar toda a informação que precisarei verificar ?

Se escrevo código que implementa uma funcionalidade antes de escrever código que a testa, corro o risco de que seu design não seja adequado para que seja testado. Portanto, a melhor maneira de escrever código "testável" é definindo seu teste primeiro. Assim você garante que a implentação deve seguir o design que você propôs.

"Hum... então TDD é mais do que escrever testes primeiro, tem a ver sobre design também...", você pode estar pensando. Sim, com certeza; TDD é mais sobre design do que propriamente a ordem em que os testes são feitos.

Em geral, você guia o design pelos testes. Essa  abordagem, ligada a noções de conceitos como acoplamento e coesão, levam a um código altamente flexível e testável. Normalmente, o que queremos quando desenvolvemos software de qualidade.

quarta-feira, 13 de agosto de 2008

Glossário Rápido

Eu não espero reinventar a roda e ter que explicar todos os conceitos, metodologias, processos, siglas, etc. que surgirem neste blog. Diversos outros autores já reservaram seu tempo fazendo isso. Meu intuito aqui é prover uma definição suscinta para quem não quer ler todo o conteúdo encontrado no Wikipedia ou no site mais próximo, encontrado talvez numa pesquisa no Google.

Metologias Ágeis

É o nome dado ao conjunto de metologias dissidentes do Manifesto Ágil. Exemplos: Extreme Programming, Scrum, Crystal, Feature-Driven Development, etc.

Manifesto Ágil

Um conjunto de princípios que visa potencializar o relacionamento das pessoas envolvidas no projeto do software (desenvolvedores, gerentes, clientes, etc.) , de forma a trazer benefícios para o mesmo, através de suas relações e práticas.

Práticas Ágeis

Práticas comumente adotadas pelas metodologias ágeis, como Desenvolvimento Incremental, Liberação Frequente, etc.

eXtreme Programming (XP)

Apesar de não parecer, não é nada de novo. Juntou-se práticas antigas de uma forma que pudesse melhorar o desenvolvimento de software, enxugando ao máximo as tarefas burocráticas e que não estavam ligadas diretamente à programação. As práticas foram unidas de forma que uma sustentasse a outra, cobrindo eventuais problemas relacionados à prática isolada das mesmas. O nome "extrema" vem do sentido de que a adoção das práticas é um tanto radical em relação ao desenvolvimento de software tradicional.

Scrum

Outro dissidente do Manifesto Ágil, o Scrum possui uma série de regras, papéis e documentos bem definidos, a serem seguidos pela equipe participante do projeto. Possui terminologia própria (apesar das práticas e papéis não serem novos) que ajudam no entendimento do processo e em sua adoção. Tem foco mais na parte administrativa que na de implementação.

Test-Driven Development (TDD)

Prática em que se escreve código para testar uma funcionalidade no software, antes que o código que implementa esta funcionalidade tenha sido escrito. Envolve diversos outros fatores como design, refactoring, integração, automação de tarefas e diversos tipos de teste, se tornando muito mais abrangente de que a simples definição de sua prática. O TDD é utilizado pela maioria das metodologias ágeis.

Refactoring

Consiste em melhorar o código existente através de sua reorganização, sem que sua funcionalidade seja modificada. A cada tipo de reorganização foi dado um nome (ou frase) para expressar sua intensão e facilitar a comunicação entre os desenvolvedores.

Design Patterns

Os Padrões de Projeto são modelos de organização e interação de classes, percebidos por desenvolvedores de software ao longo do tempo, que foram catalogados e nomeados para facilitar sua indentificação.

Gang of Four (GoF)

Apelido dado ao grupo de autores do livro "Design Patterns - Elements of Reusable Object Oriented Software", composto por Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides. O livro é uma espécie de catálogo de padrões de projeto de software (Design Patterns) , sendo uma ferramenta indispensável aos bons analistas de sistemas e arquitetos de software.

Acoplamento

Nível de inter-dependência entre módulos (ou outras partes) do software. Quanto menor, melhor (mais reutilização).

Coesão

Grau de "singularidade" de um módulo (ou outras partes) do software. Se um módulo desempenha uma única função ou tem um único propósito, ele é altamente coeso.

KISS

Princípio que tem como objeto sempre manter as coisas bem simples. Sua abreviação possui variações, como Keep It Small and Simple ("mantenha as coisas pequenas e simples"), ou - a minha preferida - Keep It Simple, Stupid. ;)

YAGNI

Princípio cujo objetivo é que não se crie coisas das quais você não tem certeza absoluta se vai precisar. Sua abreviação se refere You Ain't Gonna Need It (algo como "você não vai precisar disto").

DRY

Princípio que visa reduzir a repetição, a duplicação, de trabalho. Vem de Don't Repeat Yourself (algo como "não se repita").

Fixture

Conjunto de dados de teste que são compartilhados entre diversos testes.

Outros termos serão incluídos aqui à medida em que forem sendo referenciados pelos artigos do blog.

O que virá

Uma idéia do que deve ser visto por aqui:

Metodologias e Processos

Muita gente ainda desconhece ou tem uma visão um tanto turva sobre Metodologias Ágeis, Scrum, XP, TDD, etc. e de diversos outros assuntos relacionados a metodologias de desenvolvimento de software.

Espero deixar aqui minha contribuição para esclarecer alguns pontos, com enfoque prático, fazendo um balanço sempre pragmático.

Modelos, Padrões e Princípios

Abrirei espaço para discussão de Design Patterns, modelos de separação em camadas, Refactoring, além de vários princípios que tangem as boas práticas do desenvolvimento de software.

Linguagens

Devo escrever mais sobre C++, Delphi e Java (nessa ordem), por causa de meus amigos e colegas de trabalho, além dos alunos que sempre pedem por um trecho de código no qual eles possam aprender um pouco mais da linguagem (além de adicionar em seus programas para não ter mais que reescrever tanto código). ;)

Ferramentas e Outros

Ferramentas e outros tópicos sempre irão surgir. Aspectos importantes ligados à prática e o dia-a-dia do desenvolvimento de software permearão os artigos blog.

Acompanhem os marcadores do site e deixem seus comentários. Opinião é sempre bem-vinda. Discussão é sempre saudável.

terça-feira, 12 de agosto de 2008

Blog::Start()

{

    if ( YouLikeSoftwareDevelopment() )

       ThatsTheRightPlace();

   else

       GoToMyAnotherSite(); // www.thiagodp.blogspot.com

}