Menos bugs, maior qualidade: TDD – Test-Driven Development

tdd

A busca pela causa de bugs é a etapa mais frustrante do processo de desenvolvimento de firmware, essa busca representa despesas imprevisíveis à gestão e esforços intensos sem retornos em proporção para os desenvolvedores, ou seja, todo mundo perde. Apontar a incidência de bugs como um dos principais vilões do desenvolvimento de sistemas embarcados não seria um exagero. Test Driven Development (TDD) é empregado justamente para diminuir a incidência de bugs. Regulando em micro passos a construção de código de produção e testes unitários o TDD vai encurtar a vida útil de um bug de dias ou meses para minutos, contanto que o desenvolvedor siga rigorosamente os micro passos do TDD, que podem ser grosseiramente resumidos a duas etapas:

  1. acrescente um teste e veja-o falhar;
  2. escrava o mínimo de código para vê-lo passar.

Ao contrário do que se espera, o teste unitário é escrito antes do código de produção, assim é codificado apenas o suficiente para fazer o teste passar. Esses testes unitários, uma vez escritos, ficam inseridos na firmware pelo resto da sua existência, e, quando a firmware receber modificações ou incrementos, eles vão proteger o código legado de eventuais corrupções. Por fim, o TDD ajuda a prevenir e detectar bugs nos dois momentos de existência de um projeto, durante o desenvolvimento e durante a manutenção ou expansão.

Mas TDD não é só isso, também existem outros benefícios associados ao seu uso tão importante quanto a prevenção de bugs e a diminuição do tempo gasto em debug, tais como:

  1. ter documentação na forma de testes: quando o cliente de um módulo precisar entender como ele é usado, basta ler os testes;
  2. aumentar a robustez: quando algum código existente for comprometido, algum teste falhará;
  3. modularizar e diminuir o acoplamento: para um código ser testável ele precisa ser escrito em módulos e desacoplado dos demais módulos;
  4. proporcionar paz de espírito: TDD passa maior segurança e por isso desenvolvedores que usam TDD dizem dormir melhor;
  5. prover monitoramento do progresso: os testes informam o que já foi implementado e está funcionado.

Em TDD todos os testes devem ser automatizados e rodados centenas de vezes por dia durante o desenvolvimento, por isso quando TDD é empregado em sistemas embarcados tanto os testes quanto o código de produção é escrito independente de plataforma. Além de rodar no hardware embarcado (target), também roda na máquina de desenvolvimento (host), possibilitando que a cada linha escrita os testes sejam executados, entretanto ao se escrever código independente de plataforma em sistemas embarcados fica necessário construir mocks ou fakes para simular o comportamento do hardware, mas apenas o suficiente para que módulos dependentes sejam testados, somado a isso, essa questão de dependência com o hardware é minimizada pois TDD instrúi a construir os módulos dependentes com o mínimo de funcionalidades possíveis.

Além dos benefícios convencionais, quando aplicado em embarcados, o TDD também apresenta outras vantagens, como:

  1. reduzir o risco: todo o código de produção é verificado independentemente do hardware;
  2. remover o longo processo de debug no target;
  3. isolar o hardware e a firmware;

Por fim, vale mencionar a definição que Jack Ganssle dá a software de qualidade: software sem bugs entregue no prazo. É justamente isso que TDD ajuda a fazer, diminui o tempo gasto na procura de bugs assim como a incidência deles no código final de produção, eleva a manutenibilidade do código e por fim melhora o desempenho e o prazer do desenvolvedor. Só se tem a ganhar.

Aquele que deseja aplicar TDD na sua vida de desenvolvedor, deve, obrigatoriamente, ler o livro do James Grenning chamado Test-Driven Development for Embedded C.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

[wpseo_breadcrumb]
Comentários:
Notificações
Notificar
guest
3 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Robert Perez
Robert Perez
25/11/2013 18:23

Hola Felipe, hace tiempo quiero profundizar en los test para software embarcado pero no consigo ver como insertar tests por ejemplo en intercambio de paquetes via sockets, o funciones que requieran de una estructura de datos ya proporcionada.

Como se hace en estos casos ?

Gracias, Robert
Uruguay

Felipe Lavratti
Felipe Lavratti
Reply to  Robert Perez
25/11/2013 19:43

Hola Robert Perez! Veja bem, para usar TDD em sockets, por exemplo, fica um pouquinho menos óbvio. Tomamos o exemplo de construir um sistema de mandar uma struct qualquer via sockets entre dois nodos da rede. Primeiramente rodamos o ciclo teste-código para construir as rotinas de, tomamos neste caso, recebimento. Nesta etapa um módulo de recebimento vai ser escrito e a parte de envio necessária para testá-lo vai ficar definitivamente misturada dentro dos testes. Agora passamos para o próximo passo, onde vamos rodar o ciclo teste-código para escrever as rotinas de envio, mas desas vez, nós já temos o módulo… Leia mais »

Robert Perez
Robert Perez
Reply to  Felipe Lavratti
26/11/2013 18:31

Gracias Felipe, es lo que me temía 🙂

Supongo que las funciones stub o mock functions como les llaman deben setear el entorno, crear estructuras, abrir sockets, etc para poder testear las funciones realmente.
Si bien el tiempo invertido en esta etapa es mucho, entiendo que termina siendo menor al tiempo usado en la depuracion.

Voy a conseguir el libro de TDD para embedded systems que recomiendas porque me he quedado enganchado con este tema.

Gracias por la info.
Abrazo desde aquí tambien !

Talvez você goste:

Séries

Menu
Privacy Settings saved!
Configurações de Privacidade

Entenda quais dados e informações usamos para ter melhor entrega de conteúdo personalizado para você.

These cookies are necessary for the website to function and cannot be switched off in our systems.

Para usar este site, usamos os seguintes cookies tecnicamente exigidos

  • wordpress_test_cookie
  • wordpress_logged_in_
  • wordpress_sec

Decline all Services
Accept all Services