Visual-C ++で「実際の」TDDをしている人はいますか。[閉まっている]


10

テスト駆動開発は、コードの前にテストを記述し特定のサイクルを実行することを意味します

  • テストを書く
  • テストの確認(実行)
  • 量産コードを書く
  • テストの確認(実行)
  • プロダクションコードのクリーンアップ
  • テストをチェック(実行)

私に関する限り、これは、開発ソリューションでプロダクションコードとテストコードを非常に迅速に切り替え、特定のプロダクションコード部分のテストを非常に迅速に実行できる場合にのみ可能です。

今、C ++には多くの単体テストフレームワークが存在しますが(Bost.Test atmを使用しています)、TDDを作成する適切な(ネイティブC ++の)Visual Studio(Plugin)ソリューション実際には存在しないようです。使用されるフレームワークに関係なく耐えられるサイクル。

「ベアラブル」とは、個別のテストプロジェクトなどを手動で設定しなくても、特定のcppファイルのテストを実行するのがワンクリックのアクションであることを意味します。 。

では、Visual Studioを使用したネイティブC ++開発でTDDサイクルを可能にするツール(プラグイン)とテクニックはどこにありますか?

注:私は無料または「商用」ツールで大丈夫です。

してくださいノーフレームワーク勧告。(フレームワークに専用のVisual Studioプラグインがあり、そのプラグインを推奨する場合を除きます。)


注の編集:これまでの回答は、ユニットテストフレームワークをVisual Studioに統合する方法に関するリンクを提供しています。リソースは多かれ少なかれ、UTフレームワークをコンパイルして最初のテストを実行する方法を説明しています。これはこの質問についてではありませんユニットテストを手動で維持(!)して実際に生産的に作業するには、vcprojを本番クラスから分離するとオーバーヘッドが大きくなり、TDDが「不可能」になると私は思います。私が知る限り、JavaまたはC#のモノに追加の「プロジェクト」を追加してユニットテストとTDDを有効にしないでください。これ 適切なツールを与えられたC ++で可能になるが、TDD / C ++ / VS用のツールはほとんどないようです(この質問についてです)。


探し回って、正しい方向を目指しているように見えるVisualAssertというツールを見つけました。しかし、残念ながら、広く使われているようには見えません(CppUnit、Boost.Testなどと比較して)。


編集:この質問のコンテキストにコメントを追加します。問題の概要(の一部)の良い要約を示していると思います:(Billy ONealによるコメント)

Visual Studioは、ユーザーが合理的に編集可能な「ビルドスクリプト」を使用しません。1つのプロジェクトで1つのバイナリが生成されます。さらに、Javaには、Javaが完全なバイナリを決して構築しないという特性があります-構築するバイナリは、クラスファイルの単なるZIPです。したがって、個別にコンパイルしてから、JARを手動で(たとえば、7zを使用して)コンパイルすることが可能です。C ++とC#はどちらも実際にはバイナリをリンクしているため、一般的に言えば、そのようなスクリプトを作成することはできません。あなたが得ることができる最も近いのは、すべてを別々にコンパイルしてから、2つのリンクを行うことです(1つは本番用、もう1つはテスト用)。


2
As far as I am aware, you do not add extra "projects" to a Java or C# thing to enable Unit Tests and TDD,<-私はこれが正しいとは思いません。通常、C#にも複数のプロジェクトがあります。テストコードを本番用バイナリで出荷したくない場合。
Billy ONeal、2011

2
フレームワークで処理されることは見たことがありません。バイナリの生成にはプロジェクトが必要です。2つのバイナリが必要です。1つはテストコード、もう1つは製品コードです。したがって、2つのプロジェクトが必要です。それを回避する方法はありません。
Billy ONeal、2011

1
@BillyONeal、私の(Java)プロジェクトの1つを除くすべてで、プロジェクトにはメインソースとテストソースが含まれています。ビルドスクリプトは、デプロイ可能なアーティファクトに配置する部分を選択します。
Robert Mark Bram

2
@Robert:Visual Studioは、ユーザーが合理的に編集可能な「ビルドスクリプト」を使用しません。1つのプロジェクトで1つのバイナリが生成されます。さらに、Javaには、Javaが完全なバイナリを決して構築しないという特性があります-構築するバイナリは、クラスファイルの単なるZIPです。したがって、個別にコンパイルしてからJARを手動で(たとえばを使用して7z)コンパイルすることができます。C ++とC#はどちらも実際にはバイナリをリンクしているため、一般的に言えば、そのようなスクリプトを作成することはできません。あなたが得ることができる最も近いのは、すべてを別々にコンパイルしてから、2つのリンクを行うことです(1つは本番用、もう1つはテスト用)。
Billy ONeal、2011年

4
マジ?「ヒント:各テストには1つのメイン関数が含まれ、1つの実行可能ファイルが生成されます。」これは、妥当な量のテストでは、途方もなく遅いように聞こえます。実行可能ファイルごとに1つのテストフィクスチャのみを意味する場合でも、その愚かなアドバイスはIMOにあります。数千のテスト(中規模のプロジェクトの場合)または数十万のテスト(大規模なプロジェクトの場合)でそれを実行してみてください。そうすれば、間違いなく気が狂います。
合法化

回答:


4

C ++とVisual StudioでTDDを実行する5部構成のブログシリーズを作成しました(パート1パート2パート3パート4パート5)

T#を行うためにC#で追加のプロジェクトを作成しないと言う理由がわかりません。これは、私がNUnitで常に行ってきたことであり、他の人々がNUnitでも行う典型的なことのようです。理由は簡単です。常にテストコードと製品コードを分離しておくことです。Visual Studioを使用するC ++の場合、これはC#とNUnitの場合と同様に、個別のプロジェクトを意味します。私がJavaの世界について知っていることから、これはそこでも一般的です。

明らかに、TDDを実行するために「耐えられる」ものについては、誰もが異なる考えを持っています。私は私のブログ記事で概説した方法を非常に長い間実践してきましたが、それは非常に我慢できると思います。C ++はコンパイルされた言語であり、テスト対象のシステムが高度に結合されていると、コンパイルに時間がかかる場合があります。より緩やかに結合された設計にリファクタリングしない限り、そこから抜け出すことはできません。

私の「ワンクリックアクション」は「ソリューションのビルド」です。ビルドが多すぎる場合は、作業中に無関係なプロジェクトをいつでもアンロードでき、Build Solutionは変更の結果として更新する必要のあるプロジェクトの最小限のサブセットのみをビルドします。

確かに、C ++のコンパイル時間の性質により、これはTDDプロセスの各サイクルでNUnitやC#を使用した場合よりも少し時間がかかりますが、十分にテストされたC ++コードから得られる信頼性は価値があります。それ以外の場合は、デバッガで多くの時間を費やすことになります。テストのコンパイル時間を大幅に増加させる可能性があるため、gmockの使用を控えるように注意してください。これまでのところ、ほとんどの場合、軽量の「偽造」オブジェクトを使用していないため、モックの本格的な機能はほとんど必要ありません。C ++のモックフレームワークは非常にテンプレートベースであり、これによりコンパイル時間が大幅に増加する可能性があるため、実際にモックが必要であり、偽物が必要としない場所のために予約する必要があります。

私はBoost.Test単体テストプロジェクトウィザードを作成して、量産コードのテストプロジェクトを作成するボイラープレートの性質の一部を自動化することを検討しましたが、数回実行すると、手動で行うのはそれほど難しくありません。

多くの(150?)プロジェクトを含むソリューションについては、それに対処する方法もあります。明らかなことの1つは、関連するプロジェクトのグループを見つけてそれらをまとめ、それらを1つの単位として消費/公開することです。TDDサイクル中に行う小さな変更のために、150のプロジェクトすべてを本当に再構築/変更する必要がある場合、コードは非常に結合されているため、ユニットテストで大きな違いはありません。

NetBeans IDEのリンクを見て、私は見つける目の保養の横に緑または赤のシンボルとウィンドウ内のテスト出力を解析し、何かやショーはほとんどのテスト列を有するのを私はNUnitのから来た逃すだろうと思ったことを何か、実際には見逃しませんでした。ビルドが単に失敗するだけの方が便利で、エラーウィンドウをダブルクリックして、失敗したアサーションの場所にカーソルを置くことができます。


「... C#で余分なプロジェクトを作成しないと言う理由がわからない... Javaの世界で私が知っていることから、これもそこでは一般的です...」私の誤解である可能性があります。(少なくとも.NETの場合、.NETの実行可能ファイルが必要なため-Javaの場合はクラスファイルが必要なだけなので、追加のプロジェクトがどこに収まるかはわかりません。)
Martin Ba

Javaがプロジェクトでどのように機能するかはわかりません。私はそこでの経験が限られています。私がほとんど知らないことから、プロジェクトは言語ではなくIDEの成果物であると理解しています。(厳密に言えば、これはC#にも当てはまりますが、短いブログ記事やデモンストレーション以外にコマンドラインコンパイラを使用している人は誰も知りません。)ただし、Javaの場合でも、テストコードは個別のプロジェクトがあなたのために行っている生産コード。C ++を条件付きでコンパイルして本番コードとテストコードを分離することはお勧めしません。
合法化

1
「テストコードを本番コードから分離してください。これは、個別のプロジェクトがあなたのために行っていることです」-aha!まあ、実際には、私見ではありません。C ++と.NETの両方で実行可能ファイルを作成し、(1つの)プロジェクトが必要な(1つの)実行可能ファイルを作成する必要があるため、個別の "プロジェクト"はC ++と.NETに必要です。テストコードを本番コードから分離して(または分離せずに)構いませんが、テストの実行可能ファイルを生成するために(冗長な)「プロジェクト」を追加する必要があることがわかりました。:-)
Martin Ba

1
ビルドされた2つの製品が必要です。製品コード(静的ライブラリ、共有ライブラリ、実行可能ファイルなど)とテスト実行可能ファイルです。Visual Studioでは、ビルドされた各製品がプロジェクトに対応するため、2つのプロジェクトが必要です。それは本当にそれ以上複雑ではありません。単体テストプロジェクトは冗長ではありません。
合法化

2

私はVisual-C ++を使用していませんが、QtCreatorをIDEとして、googletestとgooglemockを使用してC ++でTDDを実行しています。数年前、私はVisual-C ++で同様の設定をしていましたが、異なる単体テストフレームワークを使用しています。

私が便利だと思ったのは、プロジェクトをいくつかのサブプロジェクトに分割することです。

  1. 実際のプロジェクトソースコードの99%を含む静的または動的ライブラリ。
  2. 通常のプログラムを実行するmain()メソッドで主に構成されるプロジェクト。
  3. テストフレームワークを実行するmain()と、テストとモックオブジェクトを含む多くのファイルを含むテストプロジェクト。

このセットアップで、私のIDEはさまざまなプロジェクトにファイルを追加し、依存関係が正しく決定されている場合は、部分的な再ビルドですべての単体テストを実行できます。ビルド直後にすべてのテストを実行するように設定されています。私が現在使用しているCIであるJenkinsも実行され、テスト結果とカバレッジデータを提供します。

テストフィクスチャTestFooでFooのすべてのユニットテストに名前を付けた場合、ファイルにFoo.cppのユニットテストを実行するためのファイルに、カスタムランチャーをIDEに追加できる場合があります。これをVisual-C ++用に正確に設定する方法はわかりませんが、可能だと思います。


有用な情報ですが、「一般的なアドバイス」と呼んでいますが:-) ...また、レガシーのものには実際には実行できませんが、レガシーのものにテストを追加することはとにかく苦痛です(そして、少なくともテストリギングを簡単に追加できるようにしたかったのですが)。
Martin Ba

2

MSTestを使用してネイティブC ++コードをテストしています。
この方法についての素晴らしいブログ投稿は次のとおりです。http//blogs.msdn.com/b/jsocha/archive/2010/11/19/writing-unit-tests-in-visual-studio-for-native-c。 aspx

はい、少なくとも2つのプロジェクトがあります。1つはアプリケーション自体用、もう1つはテスト用です。
静的ライブラリを使用して3番目のプロジェクトを作成する代わりに、アプリケーションのソースをテストプロジェクトに追加するだけなので、ソリューションは次のようになります。

[-] Solution 'Foo'      Foo\Foo.sln
 |-[-] Foo              Foo\Foo\Foo.vcproj
 |  |-[-] include
 |  |  |- foo.h         Foo\Foo\foo.h
 |  |  |- bar.h         Foo\Foo\bar.h
 |  |
 |  |-[-] source
 |     |- foo.cpp       Foo\Foo\foo.cpp
 |
 |-[-] Foo.Tests        Foo\Foo.Tests\Foo.Tests.vcproj
    |                        (Additional include directory: "..\Foo")
    |-[-] include
    |  |- FakeBar.h     Foo\Foo.Tests\FakeBar.h
    |
    |-[-] source
       |-[-] app
       |  |- foo.cpp    Foo\Foo\foo.cpp    -- not in Foo.Tests\
       |
       |-[-] unit-tests
          |- foo_Tests.cpp   Foo\Foo.Tests\foo_Tests.cpp
          |- bar_Tests.cpp   Foo\Foo.Tests\bar_Tests.cpp

単体テストにC ++ / CLIのものを使用すると、純粋なネイティブC ++コードをテストするときに水を汚すだけです。ただし、NUnitを使用してC ++ / CLIアプリケーションコードをテストしました。テストはC#で記述しましたが、問題なく動作しました。(既存のコードベースはC ++ / CLIであり、C#に移植したくありませんでした。)
合法化

さらに、テストがC ++ / CLIで行われている場合、他のプラットフォームでは実行できません。私がC ++を使用したほとんどの場所では、クロスプラットフォームのコンパイル能力が必要でした。もちろん、他のプラットフォームでVSプロジェクトを再利用することはできませんが、MakefileやSConscriptsを使用することは大したことではありません。
2011年

@legalize Windows以外のプラットフォームでもWinAPI(およびCOMやその他のWindows固有のテクノロジ)を再利用することはできません。
Abyx

もちろん、Windows以外のプラットフォームでWindows固有のテクノロジを使用することはできません。私の観察では、プラットフォームにとらわれないコードがある場合、単体テストを特定のプラットフォームに結び付けたくありません。以前の雇用主では、多数の単体テストフレームワークとメソッドを評価しました。Boost.Testを選択したのは、それがクロスプラットフォームであり、ユニットテストに関してC ++標準ライブラリで結局何かが発生する場合は、Boost.Testである可能性が高いからです。
合法化

2

多分その日の遅いかもしれませんが、あなたの質問を正しく読んだ場合、TDDサイクルを改善するためのテクニックを探していますか?ここでは触れていませんが、VSでビルド後のイベントを見たことはありますか?

私たちのソリューションは通常整理されています(プロジェクトの依存関係が示されています)...

MAIN-APP > LIB1, LIB2, UNIT-TEST-APP
UNIT-TEST-LIB1 > LIB1
UNIT-TEST-LIB2 > LIB2
UNIT-TEST-APP > UNIT-TEST-LIB1, UNIT-TEST-LIB2

MAIN-APPのビルド後のイベントはUNIT-TEST-APPを実行します

UNIT-TEST-APPのビルド後のイベントはそれ自体で実行されます(ビルド後のイベントで実行するコマンドとして「$(TargetPath)」を入力するだけです)。

(これは、MAIN-APPをビルドするときにユニットテストが2回実行される可能性があることを意味しますが、それは私たちのケースでは本当に問題ではありませんでした!)

ただし、前述のとおり、はい、この構造の設定には少し労力が必要ですが、いったんそこに配置されれば、テストの追加は簡単です。

したがって、メインアプリをビルドするだけで、ユニットテストが自動的に実行されます。


1

これが役立つかどうかはわかりませんが、Brett L. SchuchertによるTDDに関するすばらしいビデオがいくつかあります。残念ながら、彼は「C ++」と「VS」の組み合わせを示していませんが、

C#およびVSでのTDD:http : //vimeo.com/album/210446

C ++およびEclipseを使用したTDD:http : //vimeo.com/13240481

多分あなたはそれらの2つからそれを解決することができます。

編集:C ++ビデオはもちろん、EclipseでCppUTestテストフレームワークを使用することについてです。それを投稿したとき、VSでの使用に簡単に採用できるはずだと思いました。だから私は少しグーグルしてこれを見つけました:

http://schuchert.wikispaces.com/tdd.cpp.NotesOnCppUTest

Visual StudioでCppUTestを使用する方法に関する情報を提供します。


2
Doc-TDD / Eclipseビデオを見ただけですが、これには反対票を投じます。ビデオは私興味がないこと、つまりユニットテストコードの書き方を正確に示してます。(この質問の)問題は単体テストを作成することではなく、C ++プロダクション開発と適切に統合する方法であり、これらのビデオがここでどのように役立つかわかりません。
Martin Ba

私はこの質問のコンテキストでこの回答に反対票を投じましたが、ビデオが非常に素晴らしいことを付け加えたいと思います。私はEclipse / TDD / C ++を見るのが面白いと感じました。ここでは役に立たない:-)
Martin Ba

@Martin:私の編集を参照してください。
Doc Brown

あなたの努力に感謝します。この追加のリンクがこの質問のコンテキストで本当に役立つとは思いませんが、自分で編集する必要があると思います。
Martin Ba

@マーティン:わかりました。質問と「耐えられる」の定義をもう一度読みましたが、少し期待しすぎていませんか?ユニットテストプロジェクトの設定は「ワンクリック」ソリューションではありませんが、実際のユニットテストを作成する作業は、使用しているフレームワークの規模をはるかに上回ります。
Doc Brown

1

Googletest
VC ++と統合する方法

プラグインは必要ありません。テストは別のターゲットです。c ++でテストを生成するプラグインはありません。割り当てなどの無意味なものをテストすることができれば可能です。


「たとえそれが割り当てのような無意味なものをテストすることになったとしても」-それはどういう意味ですか?C ++での単体テストのより良いIDEサポートは価値がないと本当に思いますか?
Martin Ba

つまり、c ++のような言語では、システムは明白なステートメント以外のテストを自動的に作成できないのです
Martin Beckett

2
何故なの?vcprojオンザフライでファイルを自動生成するプラグインを妨げているものは何ですか?私が書いたテストファイルファイルと参照されている本番ファイルを取り込み、それを実行しようとしていますか?(ただ夢を見ているだけで、うまくいくかもしれません。)
Martin Ba

2
フォローできるかわかりません。明らかに私は自分でテスト書かなければなりません。しかし、それらを実行すると、個別のテストプロジェクトファイルを手動で設定(および維持)するよりもはるかに簡単になります。
Martin Ba

2
いいえ、私はテストコードではなく、テストコードと「それ」の実稼働コードを実行するために必要なプロジェクト/コンパイラの足場を参照しました。
Martin Ba

1

私は約20年間触れていないので(最近の.NET開発)、C ++ツールについてコメントできません。最近のツールのほとんどはマネージコード用ですが、テクニックについては...

他の人が述べたように、テストコードは常に本番コードとは完全に異なるプロジェクト/アセンブリにあり、通常は自分でプロジェクトを維持する必要がありますが、VS IDEでは確かにこれは大きな問題ではなく、とにかくあなたのソリューションの一部。

量産コードは、TDDとは少し異なります。最初にテストを作成するとき、テスト可能なようにコードを設計する必要があります。これ自体は他のテーマですが、最初は時間がかかり、最初は非常にイライラするかもしれません。特に、IDE /ツールから迅速なフィードバックが得られない場合は、コマンドラインツールを実行してテストを実行すると、混乱を招くだけです。

コードをテスト可能にするための特定のテクニックはたくさんありますが、それらのほとんどは、あまり機能しない小さなオブジェクトを作成することに分解されるため、それらを個別にテストして、いくつかの動作のテストバージョンをより複雑なものに注入できます。オブジェクト。IOCフレームワークは、ここで非常に役立ちます。

あなたが役に立つと思う本は、マイケルフェザー、レガシーコードを効果的に使用。これは、その例で複数の言語を使用しており、元々テスト可能であるように設計されていなかったコード/技法を安全に適合させるための特定のアプローチを識別するのに役立つ場合があります。

小さな注意:私は数年前にアジャイルクールエイドから酔っていました:D


注:すでにWorking Effectively with Legacy Code机の上にいます:-)
Martin Ba

0

MavenはC ++で広く使用されていません(まだJavaで主に使用されていますが、言語に依存しません)は非常に強力なツールであり、1つのプロジェクトのすべてを維持できます(実際、テストを含む、これは推奨されます) Mavenとのアプローチ)。これまでの回答から、VSプラグインを使用した代替案は存在しない可能性があるため、私は今それを提案するだけです。

私が見つけたプラグインを検索しています:

http://incubator.apache.org/npanday/

まだ成熟していないようです。Mavenセットアップを使用すると、テストを実行するために必要なことはすべてmvn testコマンドラインで実行されます。

興味がある場合は、こことC ++をサポートするプラグインの1つをここで学習できます(Mavenにはプラグインアーキテクチャがあるため、すべてがプラグインです)。


0

フレームワークの推奨事項:私たちのオフィスでは、Visual Studioと統合するTestDriven.NETを使用しています。ユニットテストクラスはC ++ / CLIで記述されており、テストする必要のあるネイティブコードを呼び出すために呼び出すことができます。はい、C ++ / CLIクラスは独自のアセンブリに組み込まれるため、ソリューションに「テスト」プロジェクトが追加されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.