- Esta pergunta não é sobre estruturas de teste de unidade.
- Esta pergunta não é sobre escrever testes de unidade.
- Esta pergunta é sobre onde colocar o código UT escrito e como / quando / onde compilar e executá-lo.
Ao trabalhar efetivamente com o código legado , Michael Feathers afirma que
bons testes de unidade ... corra rápido
e essa
Um teste de unidade que leva 1/10 de segundo para executar é um teste de unidade lento.
Eu acho que essas definições fazem sentido. Também acho que eles implicam que você deve manter um conjunto de testes de unidade e um conjunto desses testes de código que demoram mais tempo separadamente, mas acho que esse é o preço que você paga apenas por chamar algo de teste de unidade se for executado (muito) rapidamente .
Obviamente, o problema em C ++ é que a "correr" o teste de unidade ( s ), você tem que:
- Edite seu código (produção ou teste de unidade, dependendo do "ciclo" em que você está)
- Compilar
- Ligação
- Iniciar executável ( s ) de teste de unidade
Editar (após uma votação estranha) : Antes de entrar em detalhes, tentarei resumir o ponto aqui:
Como o código de teste de unidade C ++ pode ser organizado de maneira eficaz, para que seja eficiente editar o código (teste) e executá-lo?
O primeiro problema é decidir onde colocar o código do Teste de Unidade para que:
- é "natural" editá-lo e visualizá-lo em combinação com o código de produção associado.
- é fácil / rápido iniciar o ciclo de compilação da unidade que você está mudando no momento
O segundo problema, relacionado, é o que compilar para que o feedback seja instantâneo.
Opções extremas:
- Cada unidade-teste-teste-unidade vive em um arquivo cpp separado e esse arquivo cpp é compilado + vinculado separadamente (junto com o arquivo de unidade de código-fonte que ele testa) a um único executável que executa esse teste de unidade.
- (+) Isso minimiza o tempo de inicialização (compilação + link!) Para a única unidade de teste.
- (+) O teste é executado super rápido, porque apenas testa uma unidade.
- (-) A execução de todo o conjunto precisará iniciar um bazilhão de processos. Pode ser um problema para gerenciar.
- (-) A sobrecarga do início do processo se tornará visível
- O outro lado seria ter - ainda - um arquivo cpp por teste, mas todos os arquivos cpp de teste (junto com o código que testam!) Estão vinculados a um executável (por módulo / por projeto / escolha sua opção).
- (+) O tempo de compilação ainda seria bom, pois apenas o código alterado será compilado.
- (+) A execução de todo o conjunto é fácil, pois existe apenas um exe para executar.
- (-) O conjunto levará séculos para ser vinculado, pois cada recompilação de qualquer objeto acionará um re-link.
- (-) (?) O processo levará mais tempo para ser executado, embora se todos os testes de unidade forem rápidos, o tempo deve ser bom.
Então, como são tratados os testes de unidade C ++ do mundo real ? Se eu executar essas coisas todas as noites / a cada hora, a segunda parte realmente não importa, mas a primeira parte, a saber, como "acoplar" o código UT ao código de produção, para que seja "natural" que os desenvolvedores mantenham os dois em foco sempre importa, eu acho. (E se os desenvolvedores tiverem o código UT em foco, eles quererão executá-lo, o que nos leva de volta à parte dois.)
Histórias do mundo real e experiência apreciada!
Notas:
- Esta pergunta deixa intencionalmente plataforma não especificada e sistema de criação / projeto.
- Perguntas com a tag UT & C ++ é um ótimo ponto de partida, mas infelizmente muitas perguntas e especialmente respostas estão muito focadas nos detalhes ou em estruturas específicas.
- Há um tempo atrás, eu respondi uma pergunta semelhante sobre estrutura para testes de unidade de impulso. Acho que falta essa estrutura para testes de unidade rápidos e "reais". E acho a outra pergunta muito estreita, daí a nova pergunta.
:-(
Onde você deve procurar respostas para essas perguntas, se não estiver neste fórum?
Pipeline<A,B>.connect(Pipeline<B,C>)
deve compilar enquanto Pipeline<A,B>.connect(Pipeline<C,D>)
não deve compilar: O tipo de saída do primeiro estágio é incompatível com o tipo de entrada do segundo estágio.