Código de efeito colateral de teste de unidade


10

Estou começando a escrever código C ++ para executar um robô e não sei como incorporar testes de unidade, se é que posso. Recebi uma biblioteca que permite a criação de "comandos" para o robô, que são agendados e executados automaticamente. O mecanismo para criar estes comandos é a subclasse uma classe base de comando que fornecem, e implementar virtuais void Initialize(), void Execute()e void End()métodos. Essas funções são executadas apenas por seus efeitos colaterais, que fazem coisas com o robô (acionar motores, estender os pistões, etc.). Por causa disso, não vejo realmente nenhum lugar para anexar testes de unidade ao código, além de zombar de toda a biblioteca para que eu possa verificar os estados antes e depois virtuais do robô. Existe uma maneira de testar a unidade que não é excessivamente onerosa?

Editar

Eu acho que posso ter enganado a funcionalidade da biblioteca. A biblioteca fornece a maior parte da interface para o robô, bem como o sistema de comando / agendamento, por isso não é tão simples quanto zombar da classe base de comando, eu precisaria zombar de toda a interface do hardware. Infelizmente, simplesmente não tenho tempo para fazer isso.


Suponho que você possa desfazer qualquer ação que faça seu robô, certo? Você não pode desfazer as ações do seu teste?
12113 Neil

1
É uma pena que a biblioteca não use composição em vez de herança, porque você poderia simplesmente zombar da classe de comando, se esse fosse o caso.
Robert Harvey

@ Neil Não sei bem o que você está perguntando. Você pode reformular sua pergunta?
que seus amigos estão

Respostas:


7

O que eu faria neste caso seria apresentar minha própria interface RobotControl com métodos correspondentes aos da lib real.

Depois de fazer isso, eu criaria uma classe RobotControlImpl que implementa essa interface na lib real do robô.

Os comandos que eu consequentemente escreveria não estenderiam a classe base, mas operariam na interface que você introduziu.

Dessa forma, você pode simular o RobotControl, passar o mock para qualquer comando e verificar se ele chamou os métodos corretos na interface.

No prod, você passaria o impl real do RobotControl para os comandos que você implementou.

Não tenho certeza se é isso que você tinha em mente e considerava complicado?

Edit: Ah, e se você espera que os comandos durmam para aguardar a conclusão (pesadelo, mas às vezes é isso que você tem), eu exigiria que os comandos chamassem um método de suspensão no RobotControl. Dessa forma, você pode desativar a suspensão durante o teste e apenas verificar se o comando tenta dormir.


2
+1. Não gosta da interface? Faça o seu.
12333 Neil

Parece que você está sugerindo que eu zombe de toda a biblioteca. Quase todas as funções que os comandos chamarão são internas à biblioteca.
Will Kunkel

0

Eu acho que é possível tornar o código testável de uma maneira minimamente invasiva. Com isso, quero dizer com isso: você pode escrever os comandos exatamente como pretendido pelos autores da biblioteca de robôs. Isso pode ser vantajoso se você deseja trocar código com outras pessoas que não estão usando sua camada intermediária.

Requer uma "compilação de teste de unidade" separada do seu código.

O que você faz é que, em um arquivo de cabeçalho central, você verifica um tempo de compilação para definir se essa é a compilação do teste de unidade e, nesse caso, redefine o nome da classe base e talvez algumas outras classes na biblioteca do robô para nomes de classes da sua implementação de teste. Você deve definir as mesmas funções virtuais da biblioteca do robô, além de fornecer stubs para os métodos que você chama no robô.

Então você tem comandos que você pode lançar em sua própria estrutura de teste que chama os mesmos métodos que a biblioteca de robôs faria.

Isso envolverá uma quantidade de stubbing e zombaria, mas isso é inevitável em qualquer projeto de teste de unidade.

A alteração do nome da classe base pode ser feita com um #define ou provavelmente preferido, um typedef.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.