O Desenvolvimento Orientado a Testes implica escrever o teste antes do código e seguir um certo ciclo :
- Teste de gravação
- Verificar teste (execução)
- Escrever código de produção
- Verificar teste (execução)
- Limpar código de produção
- Teste de verificação (execução)
Para mim, isso só é possível se sua solução de desenvolvimento permitir alternar muito rapidamente entre o código de produção e teste e executar o teste para uma determinada parte do código de produção com extrema rapidez.
Agora, enquanto existem muitas estruturas de teste de unidade para C ++ (estou usando o atm Bost.Test), parece que realmente não existe nenhuma solução decente (para C ++ nativa ) do Visual Studio (Plugin) que faça o TDD ciclo suportável, independentemente da estrutura usada.
"Suportável" significa que é uma ação de um clique executar um teste para um determinado arquivo cpp sem ter que configurar manualmente um projeto de teste separado etc. "Suportável" também significa que um teste simples é iniciado (vinculado!) E executado muito rapidamente .
Então, quais ferramentas (plug-ins) e técnicas existem para tornar o ciclo TDD possível para o desenvolvimento nativo de C ++ com o Visual Studio?
Nota: Eu estou bem com ferramentas gratuitas ou "comerciais".
Por favor : Não há recomendações de estrutura. (A menos que a estrutura tenha um plug-in Visual Studio dedicado e você queira recomendar o plug-in.)
Nota de edição : As respostas até o momento forneceram links sobre como integrar uma estrutura de Teste de Unidade ao Visual Studio. Os recursos descrevem mais ou menos como obter a estrutura do UT para compilar e executar seus primeiros testes. Isso é não o que esta pergunta é sobre. Sou da opinião de que, para realmente trabalhar produtivamente, tendo os Testes de Unidade em uma manutenção manual (!), Separar vcproj de suas classes de produção adicionará tanta sobrecarga que o TDD "não é possível". Tanto quanto sei, você não adiciona "projetos" extras a uma coisa Java ou C # para habilitar testes de unidade e TDD, e por um bom motivo. Isso deveria possível com o C ++, dadas as ferramentas corretas, mas parece (essa pergunta é sobre) que existem muito poucas ferramentas para TDD / C ++ / VS.
Pesquisando, encontrei uma ferramenta, o VisualAssert , que parece apontar na direção certa. No entanto, em geral, não parece ser amplamente utilizado (comparado ao CppUnit, Boost.Test etc.).
Editar: eu gostaria de adicionar um comentário ao contexto desta pergunta. Eu acho que ele faz um bom resumo do esboço (parte) do problema: (comentário por Billy ONeal )
O Visual Studio não usa "scripts de criação" razoavelmente editáveis pelo usuário. Um projeto produz um binário. Além disso, o Java tem a propriedade de que o Java nunca constrói um binário completo - o binário que você constrói é apenas um ZIP dos arquivos de classe. Portanto, é possível compilar separadamente e JAR juntos manualmente (usando, por exemplo, 7z). C ++ e C #, na verdade, vinculam seus binários, de modo geral, você não pode escrever um script como esse. O mais próximo que você pode chegar é compilar tudo separadamente e, em seguida, fazer dois vínculos (um para produção e outro para teste).
fonte
As far as I am aware, you do not add extra "projects" to a Java or C# thing to enable Unit Tests and TDD,
<- Não acho que isso esteja correto. Você também costuma ter vários projetos em C #; você não deseja enviar seu código de teste no seu binário de produção.7z
). C ++ e C #, na verdade, vinculam seus binários, de modo geral, você não pode escrever um script como esse. O mais próximo que você pode chegar é compilar tudo separadamente e, em seguida, fazer dois vínculos (um para produção e outro para teste).Respostas:
Eu escrevi uma série de blogs em 5 partes sobre como fazer TDD com C ++ e Visual Studio: parte 1 , parte 2 , parte 3 , parte 4 , parte 5 .
Não sei por que você diz que não faz projetos extras em C # para fazer TDD, porque é o que eu sempre fiz com o NUnit e parece típico do que outras pessoas fazem com o NUnit também. O motivo é simples: sempre mantenha o código de teste separado do código de produção. Para C ++ com Visual Studio, isso significa projetos separados, assim como para C # e NUnit. Pelo que sei do mundo Java, isso também é comum lá.
Obviamente, todo mundo tem idéias diferentes do que é "suportável" para fazer TDD. Venho praticando o método descrito em meu blog há vários anos e acho muito suportável. C ++ é uma linguagem compilada e o material de compilação pode ser lento quando o sistema em teste é altamente acoplado. Simplesmente não há como fugir disso sem refatorar para um design mais frouxamente acoplado.
Minha "ação de um clique" é "Build Solution". Se estiver construindo demais, você sempre poderá descarregar projetos irrelevantes enquanto estiver trabalhando e o Build Solution criará apenas o subconjunto mínimo de projetos necessários para serem atualizados como resultado de suas alterações.
É verdade que a natureza do tempo de compilação do C ++ demora um pouco mais em cada ciclo do processo TDD do que com o NUnit e o C #, mas vale a confiança que recebo do meu código C ++ bem testado. Caso contrário, passarei muito mais tempo no depurador. Eu recomendaria ser poupador no uso do gmock, pois ele pode aumentar substancialmente o tempo de compilação do teste. Até agora, na maioria das vezes, consegui objetos leves e "falsos" e raramente preciso da funcionalidade completa de zombarias. As estruturas de simulação para C ++ são fortemente baseadas em modelos e isso pode aumentar significativamente o tempo de compilação; portanto, elas devem ser reservadas para onde você realmente precisa de uma simulação e uma farsa simplesmente não funciona.
Eu considerei criar um assistente de projeto de teste de unidade Boost.Test para automatizar parte da natureza da chapa da caldeira de criar o projeto de teste para o código de produção, mas depois de fazer isso algumas vezes, não é tão difícil de fazer manualmente.
Quanto às soluções com muitos projetos (150?), Há maneiras de lidar com isso também. Um exemplo óbvio é encontrar grupos de projetos relacionados, agrupá-los e começar a consumi-los / publicá-los como uma unidade. Se você realmente precisa reconstruir / tocar em todos os 150 projetos para pequenas alterações que você está fazendo durante um ciclo de TDD, seu código é tão altamente acoplado de qualquer maneira que os testes de unidade provavelmente não farão muita diferença.
Olhando para o link IDE do netbeans, acho o colírio para os olhos algo que analisa a saída de teste e mostra uma pequena linha de teste em uma janela com um símbolo verde ou vermelho ao lado, algo que eu pensei que sentiria falta de ter vindo da NUnit, mas na verdade não errou. Achei mais útil a compilação simplesmente falhar e, em seguida, clique duas vezes na janela de erros para colocar o cursor no local da asserção com falha.
fonte
Não estou usando Visual-C ++, mas estou executando o TDD com C ++, usando googletest e googlemock, com QtCreator como meu IDE. Anos atrás, eu tinha uma configuração semelhante ao Visual-C ++, mas usando uma estrutura de teste de unidade diferente.
O que eu achei útil é separar o projeto em alguns subprojetos.
Com essa configuração, meu IDE cuida de adicionar arquivos a vários projetos e, se as dependências estiverem sendo determinadas corretamente, eu posso executar todos os meus testes de unidade com uma reconstrução parcial. Eu ainda o tenho configurado atualmente para executar todos os meus testes imediatamente após a compilação. Jenkins, o IC que estou usando atualmente, também executa e fornece resultados de testes e dados de cobertura.
Pode ser possível adicionar um iniciador personalizado no seu IDE para um arquivo para executar os testes de unidade do arquivo Foo.cpp se você nomear todos os testes de unidade do Foo no equipamento de teste TestFoo. Como configurar isso precisamente para o Visual-C ++ Não tenho certeza, mas acho que é possível.
fonte
Eu uso o MSTest para testar o código C ++ nativo.
Aqui está o ótimo post sobre este caminho: http://blogs.msdn.com/b/jsocha/archive/2010/11/19/writing-unit-tests-in-visual-studio-for-native-c. aspx
Sim, haverá pelo menos dois projetos - um para o próprio aplicativo, outro para testes.
Em vez de criar um terceiro projeto com biblioteca estática, apenas adiciono a fonte do aplicativo ao projeto de teste, para que a solução fique assim:
fonte
Talvez um pouco tarde, mas se eu li sua pergunta corretamente, você está procurando técnicas para melhorar o ciclo TDD? Não foi mencionado aqui, mas você já viu eventos pós-compilação no VS?
Nossas soluções são normalmente organizadas (com as Dependências do projeto mostradas) ...
O evento pós-compilação do MAIN-APP executará UNIT-TEST-APP
O evento pós-compilação do UNIT-TEST-APP será executado automaticamente (basta colocar '$ (TargetPath)' como o comando a ser executado no evento pós-compilação).
(Isso significa que, ao criar o APP PRINCIPAL, os testes de unidade podem ser executados duas vezes, mas isso não foi realmente um problema no nosso caso!)
Como mencionado, sim, existe uma pouco de esforço na configuração dessa estrutura, mas, uma vez lá, adicionar testes é simples.
Então, tudo o que você precisa fazer é criar o aplicativo principal e os testes de unidade serão executados automaticamente!
fonte
Bem, não sei se isso ajuda, mas existem ótimos vídeos sobre TDD de Brett L. Schuchert. Infelizmente, ele não mostra a combinação "C ++" e "VS", mas
TDD com C # e VS: http://vimeo.com/album/210446
TDD com C ++ e Eclipse: http://vimeo.com/13240481
Talvez você possa trabalhar com esses dois.
EDIT: o vídeo C ++ é sobre o uso da estrutura de teste CppUTest com o Eclipse, é claro. Quando publiquei, achei que deveria ser facilmente adotado para uso no VS. Então, pesquisei um pouco e descobri o seguinte:
http://schuchert.wikispaces.com/tdd.cpp.NotesOnCppUTest
que fornece informações sobre como usar o CppUTest no Visual Studio.
fonte
Googletest
Como integrar com vc ++
Você não precisa de um plugin, o teste é apenas outro alvo. Não há plugins para gerar teste com c ++, mesmo que você pudesse testar coisas inúteis, como atribuições
fonte
vcproj
arquivo em tempo real, puxando o arquivo de teste que eu escrevi e o arquivo de produção referenciado e tentando executá-lo? (Apenas sonhando, mas poderia ser feito para trabalhar.)Não posso comentar sobre as ferramentas C ++, pois não falo há 20 anos (.NET dev atualmente) e acho que a maioria das ferramentas atualmente são para código gerenciado, mas para técnicas ...
Como outros já mencionaram, o código de teste está sempre em um projeto / montagem completamente diferente do código de produção e sim, você normalmente precisa manter esse projeto sozinho, embora certamente no VS IDE isso não seja um grande problema, pois muitas vezes você tem vários projetos. parte da sua solução de qualquer maneira.
O código de produção é e deve ser escrito um pouco diferente para TDD. À medida que você escreve os testes, você acaba tendo que projetar seu código para ser testável. Esse é outro assunto em si, mas pode levar tempo e parecer muito frustrante no início, especialmente se suas ferramentas / IDE não fornecerem um feedback rápido, optar por executar ferramentas de linha de comando para executar testes é apenas disruptivo.
Existem muitas técnicas específicas para tornar o código testável, mas a maioria delas se divide em criar objetos pequenos que não fazem muito, para que você possa testá-los isoladamente e poder injetar uma versão de teste de algum comportamento em algo mais complexo. objetos. As estruturas do COI podem ajudar muito aqui.
Um livro que você pode achar útil é; Michael Feathers, trabalhando efetivamente com o Legacy Code. Isso usa vários idiomas em seus exemplos e pode ajudar a identificar abordagens específicas para adaptar com segurança códigos / técnicas que não foram originalmente projetadas para serem testáveis.
Advertência pequena: bebi do Agile Kool-Aid anos atrás: D
fonte
Working Effectively with Legacy Code
na minha mesa :-)O Maven não é amplamente usado em C ++ (ainda é usado principalmente para Java, mas é independente da linguagem), mas é uma ferramenta muito poderosa e permite manter tudo em um único projeto (incluindo testes, de fato, é o recomendado). abordagem com Maven). Só o sugiro agora, já que a partir das respostas até agora parece que uma alternativa com um plug-in do VS pode não existir.
Procurando por plugins que encontrei:
http://incubator.apache.org/npanday/
mas ainda não parece muito maduro. Com a instalação do Maven, tudo o que você precisa fazer para executar os testes é executado
mvn test
na linha de comando.Se você estiver interessado, pode aprender sobre isso aqui e (um dos) plugins de suporte a C ++ aqui (o Maven possui uma arquitetura de plugins, então tudo é um plug-in).
fonte
Recomendação de estrutura: Em nosso escritório, usamos o TestDriven.NET que se integra ao Visual Studio. As classes mais unittest são escritas em C ++ / CLI, que podem ser chamadas para exercitar qualquer código nativo que você precise testar. Sim, as classes C ++ / CLI entram em seu próprio assembly, portanto, um projeto de "teste" foi adicionado à (s) solução (s).
fonte