Posts com Tag ‘Engenharia de software’

Hoje eu passei por um artigo em inglês intitulado “Pare de Fazer Teste Unitário de Tudo”.

Minha idéia aqui não é falar sobre esse artigo mas apenas comentar duas sentenças que estão lá como pontos negativos do teste unitário.

Mesmo fora do seu contexto original, estas sentenças isoladas representam pensamentos bem comuns sobre unit testing.

A primeira sentença 

Sempre que nós precisamos alterar nosso código, custa tempo para alterar nossos testes unitários.

Se você usa TDD, notará que este raciocínio está invertido.

Um teste unitário descreve o que uma parte do sistema deve fazer, e valida se o sistema está mesmo fazendo aquilo.

Usando TDD, eu nunca altero um teste para acompanhar uma mudança no sistema mas sim o inverso: eu primeiro altero o teste para que ele passe a descrever o novo comportamento do sistema, e depois eu altero o sistema para que ele passe no teste!

Em TDD, portanto, o teste unitário não é um fardo para ser carregado pelo sistema, e talvez seja justamente o inverso! Imagino que no futuro escreveremos apenas os testes, e o computador vai se programar para atendê-los.

Mas pode ser mesmo um fardo escrever ou corrigir o teste depois de tudo pronto…

Eu me lembro que nos primórdios do meu trabalho com xUnit, eu escrevia meus testes unitários como sendo a cereja do bolo em uma implementação linda e já funcionando.

Pouco tempo depois, isso perdeu a graça e ser obrigado a escrever o teste depois de já ter terminado o serviço era mesmo muito chato – até porque era mais difícil pois o design não tinha ficado tão bacana quanto ele tem que ficar quando se quer escrever os testes primeiro.

E o próprio teste não ficava bacana; acabava testando o que não devia e deixava de testar o que deveria, pois ele ficava limitado ao que se pode fazer quando se escreve testes para um design não muito bom.

A outra sentença

Testes unitários só podem testar aquilo que nós pensamos que poderia ser um bug; não o que realmente impacta nossos usuários.

Mais uma vez, pra quem usa TDD isso soa bem esquisito.

TDD não tem nada a ver com escrever teste para prevenir um bug; e TDD tem tudo a ver justamente com escrever testes para aquilo que impacta nossos usuários.

Realmente, se eu deixar para escrever o teste depois, é possível que o meu raciocínio seja: “o que será que pode dar bug no futuro e que eu gostaria de prevenir com um teste?”. E é provável também que eu não seja muito bom em prever o futuro e escreva o teste errado.

Mas, se eu escrevo o teste antes, o raciocínio não tem nada a ver com isso. Usando TDD, meu racioncínio é: “que teste eu devo escrever para que, quando ele estiver passando, demonstre que a funcionalidade está pronta e faz o que deveria fazer?”.

Além disso, se eu usar TDD ao pé da letra, não vou adicionar nenhuma fração de funcionalidade sem ter antes escrito um teste para ela, não porque eu tenho medo de bugs mas sim porque eu quero ter feedback rápido de que que o que eu estou fazendo está funcionando, de que eu estou tendo progresso no desenvolvimento do sistema.

Ora, se estou escrevendo testes para funcionalidades e não para bugs, estou preocupado justamente com o que impacta o usuário em vez de praticar o exercício ingrato de tentar adivinhar o que pode dar errado. E pelo simples fato de todas as funcionalidades estarem cobertas, as chances de bug são naturalmente bem menores.

Tenho visto que cada bug encontrado provém de um teste que eu pulei (escrevi direto a funcionalidade, sem escrever o teste antes), ou então não é bug mas sim a ausência de uma funcionalidade que não foi prevista (do tipo: “hmmm, não sabia que o usuário precisava disso”) e isto é bastante aceitável.

Para encerrar

Agora, falando sobre o título deste post, será que o verdadeiro poder do teste unitário reside apenas na prática de TDD?

A maioria dos argumentos negativos que vejo sobre testes unitários me fazem balbuciar “ué, mas não é assim que eu faço teste unitário…”.

E estes argumentos geralmente tratam o teste como algo para ser feito depois de implementar a funcionalidade. Ou então até mencionam o TDD mas parecem ignorar como de fato se usa TDD.

Fim.

Anúncios

Não herdar é libertador

Publicado: 23 de setembro de 2013 em Uncategorized
Tags:

Quando eu me iniciei no mundo da Programação Orientada a Objetos eu ficava muito fascinado com a possibilidade de herdar classes e procurava oportunidades de fazer isso. Sempre lembrava que pessoa herdava de mamífero que herdava de animal, do qual herdava também o pássaro, do qual herdavam a galinha e o gavião, sendo que mamífero emite som e cada classe concreta implementa o seu próprio som.

Menos a girafa, que se você invocar o método “emitir som” decerto é lançada uma “not implemented exception” ou a girafa se comporta de uma maneira muito louca e você vai ter que depurar pra entender.

Mais complexo ainda é o momento em que você descobre que galinha e gavião também emitem som e resolve subir o método abstrato “emitir som” da classe Mamífero para a classe Animal. E daí emitir som aparece na classe minhoca a qual, mesmo que emita algum som, não é relevante para o seu negócio.

Há alguns anos comecei a perceber que herdar estava mais me atrapalhando que ajudando. (mais…)

Antes de escrever este texto eu fui procurar algumas opiniões já publicadas sobre isso. Não consegui ir muito longe porque me deparei com um verdadeiro show de horrores e fiquei paralisado. Encontrei uma verdadeira tese ensinando a comentar código fonte!

Quando comecei a ler eu achei que o cara estava de brincadeira, que era uma pegadinha e que no final ele esclareceria tudo. Mas não! (mais…)