Visual Studio 2022でC++のTDD環境を構築しよう!
ということで、技術選定を兼ねて、C++のTDD環境を構築してみましょう。
今回はWindowsをターゲットとしたC++開発を条件とします。
どのようなビルドシステム x テストフレームワークの組み合わせができるのでしょうか。
前提条件
- Visual Studio Community 2022
選定の条件ですが、以下の2つを将来のCI化のために必要条件とします。
- コマンドラインでテストが実行できる
- コマンドラインでビルドが実行できる
また、好ましい要素として以下を挙げておきます。
- テストの追加が難しくないこと
- ターゲットの追加が難しくないこと
- コンパイラの変更(cl.exe->clang++など)ができる
- Git管理と相性が良い
- 開発環境の構築に手間がかからない
ビルドシステム
テストフレームワーク
Microsoft 単体テスト フレームワーク(CppUnitTestFramework)
GoogleTest
Boost.Test
CTest
組み合わせを試す
[x] 初級: IDE + Microsoft 単体テスト
[ ] 基礎: MSBuild + Microsoft 単体テスト
[ ] 基礎: MSBuild + GoogleTest
[ ] 応用: CMake + Microsoft 単体テスト
[ ] 応用: CMake + GoogleTest
初級: IDE + Microsoft 単体テスト
IDEを使用して実装とテストをしてみます。
まずはVisual Studio(以下、VS)でソリューションを作ります。
コンソールアプリを作成する
まずは、新しいプロジェクトの作成→コンソールアプリを選択→次へ
適当な場所に「FizzBuzzApp」というプロジェクト名/ソリューション名でソリューションを作成します。
プロジェクトファイルの確認
作成したディレクトリには、FizzBuzzApp.vcxproj
というファイルが生成されています。
とりあえず規定のターゲットでビルド
msbuild
にはパスを通しておいてください。
msbuild FizzBuzzApp.vcxproj
ビルドに成功しました。
0 個の警告
0 エラー
経過時間 00:00:03.04
cppファイルの追加
FizzBuzzApp
を右クリックし、[追加]>[クラス]を選択し、FizzBuzz
クラスを追加します。
追加された.cpp、.hファイルの内容を以下のようにします。
#include "FizzBuzz.h"
#include <string>
using namespace std;
string FizzBuzz::fizzbuzz(int num) {
return "fizz";
}
#pragma once
#include <string>
using namespace std;
class FizzBuzz
{
public:
string fizzbuzz(int num);
};
単体テストフレームワークの追加
テスト作成のワークフロー2に従って試します。
以下の2つの手順を実施します:
- Visual Studio 2022 でテスト プロジェクトを作成する
- ソリューション内の他のプロジェクトへの参照を作成する
ここでは、UnitTest1
をユニットテストとして追加しました。
「オブジェクトまたはライブラリ ファイルのリンク」をするため、テスト実行ファイルにテスト対象をリンク3します。
追加時の値にマクロを使いましたが、マクロボタンから評価後の値を使うと楽に探せます。
- [構成プロパティ]>[リンカー]>[入力]の[追加の依存ファイル]には、`FizzBuzz.objを追加します
- [構成プロパティ]>[リンカー]>[全般]の[追加のライブラリ ディレクトリ]には、
$(SolutionDir)\FizzBuzzApp\x64\Debug
を追加します - [構成プロパティ]>[VC++ ディレクトリ]の[インクルード ディレクトリ]には、@$(SolutionDir)\FizzBuzzApp`を追加します
続いてワークフローに戻り、次の手順を実施します:
- ヘッダー ファイルの #include ディレクティブを追加する
- テスト メソッドを作成する
試しに次のようなテストメソッドを作成しました。
#include "pch.h"
#include "CppUnitTest.h"
#include "../FizzBuzzApp/FizzBuzz.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(_1isFizz)
{
string ans = "fizz";
FizzBuzz obj = FizzBuzz();
Assert::AreEqual(ans, obj.fizzbuzz(1));
}
};
}
その後、「テストの実行」に移り、テストを実行します。
後はテストメソッドをどんどん追加するだけです。
コマンドラインからビルド&テストを実行してみる
メニュー バーで [ツール]>[コマンド ライン]>[開発者コマンド プロンプト]を選択する。
念のため、rebuildターゲットにしてみる。
msbuild -t:rebuild
cd x64\Debug
vstest.console.exe UnitTest1.dll
Microsoft (R) Test Execution Command Line Tool Version 17.9.0 (x64)
Copyright (c) Microsoft Corporation. All rights reserved.
テスト実行を開始しています。お待ちください...
合計 1 個のテスト ファイルが指定されたパターンと一致しました。
成功 _1isFizz [< 1 ms]
成功 _2isBuzz [< 1 ms]
テストの実行に成功しました。
テストの合計数: 2
成功: 2
合計時間: 0.3328 秒
IDE + Microsoft 単体テストの感想
ということで、初級編でもコマンドでビルド&テストできましたね。
ソリューション内の他のプロジェクトへの参照を作成するあたりが少し複雑でした。
ここで得られた知見としては、
- テストの実行ファイルはMS提供のvstest.console.exeを使う
- テストメソッドが入ったオブジェクトはテスト対象とリンクして、dll化する
でした。
また、依存関係の複雑性が上昇したときにメンテナンス&レビューができるか不安な所です。
基礎: MSBuild + Microsoft 単体テスト
とりあえず、このチュートリアル4に従って進めます。
完成したプロジェクトファイル5に、Visual Studio 2022に合わせて以下の変更を加えます:
-
ToolsVersion="17.0"
とします -
PlatformToolset
の要素はv143
とします
msbuildを実行して、成果物を実行してみます。
.'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe' .\fizzbuzzapp.vcxproj /p:configuration=debug
.\debug\fizzbuzzapp.exe
Hello, from MSBuild!
.'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe' .\fizzbuzzapp.vcxproj /t:clean /p:configuration=release
疲れたのでここまで。そのうち追記します。