Incluindo testes de unidade em um projeto C simples e legado

12

O título diz tudo. Minha empresa está reutilizando um projeto de firmware herdado para um dispositivo de microcontrolador, totalmente escrito em C.

Obviamente, existem partes que estão erradas e precisam ser alteradas. Vindo de um background em C # / TDD, não gosto da ideia de refatorar aleatoriamente itens sem testes para garantir que a funcionalidade permaneça inalterada. Além disso, vi que erros difíceis de encontrar foram introduzidos em muitas ocasiões através de pequenas alterações (o que acredito que seria corrigido se o teste de regressão fosse usado). É preciso tomar muito cuidado para evitar esses erros: é difícil rastrear um monte de globais em todo o código.

Para resumir:

  • Como você adiciona testes de unidade ao código fortemente acoplado existente antes da refatoração?
  • Quais ferramentas você recomenda? (menos importante, mas ainda é bom saber)

Não estou diretamente envolvido na escrita desse código (minha responsabilidade é um aplicativo que irá interagir com o dispositivo de várias maneiras), mas seria ruim se bons princípios de programação fossem deixados para trás se houvesse uma chance de que eles pudessem ser usados.

Groo
fonte

Respostas:

7

Pegue uma cópia de Working Effective With Legacy Code de Michael Feathers. Destina-se a lidar com essas situações. Mesmo focado mais em linguagens OO, como C ++ e Java, acredito que ainda possa ajudá-lo bastante.

Parece que parte dele (ou um artigo preliminar) está disponível gratuitamente aqui .

Péter Török
fonte
+1, obrigado. Mas acredito que sou bastante bom em refatorar o código OO com mais código OO. O que não sei é como testar o código processual e refatorar o código processual com um código processual menos acoplado.
Groo
@Groo, o livro não trata de refatoração em si. É sobre como transformar um monte de código de espaguete sem nenhum teste de unidade em um monte de código (um pouco menos espaguete) bem coberto com testes de unidade. É difícil testar esse código; portanto, é necessário refatorar primeiro para torná-lo testável; no entanto, como você também mencionou, refatorar sem testes de unidade é arriscado, portanto é uma situação difícil. O livro orienta você sobre como fazer as menores e mais seguras alterações no código, que permitem cobri-lo com testes de unidade e, posteriormente, começar a refatorá-lo a sério.
Péter Török
Esse livro é uma boa sugestão e cobre C junto com os idiomas OO.
#
7

Para técnicas, provavelmente o livro de Michael Feathers na resposta de Péter Török será bastante abrangente. Se você não quiser ir ao livro, sugiro um processo de três etapas:

  1. examine o código não testável e duplique pequenas partes da funcionalidade desse código em funções testáveis. É importante que as novas funções tenham um comportamento obviamente equivalente à função que você está tentando duplicar - na verdade, não estou defendendo a criação de testes de unidade em torno do código legado, portanto, você precisa ter muito cuidado e limitar seu escopo, para manter a confiança na refatoração.
  2. escreva testes de unidade em torno dessas novas funções.
  3. modifique o código original para chamar as novas funções.

Repita esse processo algumas vezes e você deve descobrir que a qualidade da base de código herdada aumentou significativamente.

Quanto às ferramentas, observe que o C ++ pode chamar o C; portanto, qualquer estrutura de teste de unidade do C ++ pode ser usada para testar o código C. Por exemplo, estamos usando o CPPUnit para testar unitariamente um monte de código C em nosso projeto.

Aidan Cully
fonte
+1 obrigado pelas dicas e pelo link CPPUnit .
Groo