LoginSignup
14

More than 1 year has passed since last update.

【C++】UnitTest(C ++用Microsoft単体テストフレームワーク/vstest.Console.exe)の使い方概要

Last updated at Posted at 2019-04-03

UnitTest関連記事

やりたいこと

C++で作成したDLLがエクスポートしている関数の単体テスト(UnitTest)を行いたい。

概要

VisualStudio(2017)で単体テストプロジェクトを作成し、そこで単体テストを行う。

やること

プロジェクト作成

DLL作成用のプロジェクトを含むソリューションに、単体テスト用プロジェクトを追加する。
image.png

image.png

テスト対象のdllの必要物を参照設定する

C++で作成したDLLをC++で呼ぶでやったように、テストしたいDLLを使えるようにする。
(.libが見えるようにリンカの設定をし、DllImportをするための.hが見えるようにインクルードフォルダの設定をする)

単体テスト用コードを作成

初期状態で、下記のようなコードが作成される。

unittest1.cpp
#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        TEST_METHOD(TestMethod1)
        {
            // TODO: テスト コードをここに挿入します
        }

    };
}

ここに、以前作成したDLLを呼ぶコードを追加する。
(もとのDLLはこちらを参照)※単体テスト用に関数をいくつか追加。


DLLの関数を、下記のようにテストコードで呼び出す。

unittest1.cpp
#include "stdafx.h"
#include "CppUnitTest.h"

#include "DllTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTestCpp
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        BEGIN_TEST_METHOD_ATTRIBUTE(TestMethod_Normal)
            TEST_PRIORITY(1)
        END_TEST_METHOD_ATTRIBUTE()

        TEST_METHOD(TestMethod_Normal)
        {
            wchar_t* buf_in = L"あいうえお";
            wchar_t* buf_out = nullptr;

            int ans1 = Test_MyApiAdd(1, 2);
            int ans2 = Test_MyApiSub(3, 1);
            Test_MyApiPointerCopy(buf_in, &buf_out);

            Assert::AreEqual(ans1, 1 + 2); // 正常に終了
            Assert::AreEqual(ans2, 3 - 1); // 正常に終了
            Assert::IsNotNull(buf_out);    // 正常に終了

            Logger::WriteMessage("Test OK");// デバッグ時のログ(出力欄)に出力
        }

        BEGIN_TEST_METHOD_ATTRIBUTE(TestMethod_Error)
            TEST_PRIORITY(1)
        END_TEST_METHOD_ATTRIBUTE()

        TEST_METHOD(TestMethod_Error)
        {
            wchar_t* buf_in = nullptr;
            wchar_t* buf_out = nullptr;

            int ans1 = Test_MyApiAdd(1, 2);
            int ans2 = Test_MyApiSub(3, 1);
            Test_MyApiPointerCopy(buf_in, &buf_out);

            Assert::AreEqual(ans1, 1 + 5);    // ans1と1+5が一致しないので、ここでTestストップ。
            Assert::AreEqual(ans2, 100 - 1);  // 実施されない
            Assert::IsNotNull(buf_out);       // 実施されない

            Logger::WriteMessage("Test OK");
        }
    };
}

DLLの関数のコードは今回はこんな感じ。
足し算、引き算、文字列へのポインタをコピーする、だけの関数。

DllTest.cpp

int __cdecl Test_MyApiAdd(int p1, int p2)
{
    return p1 + p2;
}

int __cdecl Test_MyApiSub(int p1, int p2)
{
    return p1 - p2;
}

void __cdecl Test_MyApiPointerCopy(wchar_t* p_in, wchar_t** p_out)
{
    if (p_in != nullptr)
    {
        *p_out = p_in;
    }
    else
    {
        p_out = nullptr;
    }
}

Assert

「Assert::AreEqual()」などのモジュールを使って、テスト対象の関数の戻り値などが正しい値かどうかを確認する。下記のようなものがある。

モジュール名 役目
AreEqual オブジェクトが一致することを確認する
AreNotEqual オブジェクトが一致しないことを確認する
IsNull オブジェクトがNULLであることを確認する
IsNotNull オブジェクトがNULLでないことを確認する

など。ほかにも多数ある。

詳しくは、MSのページを参照。

Attribute

テスト用メソッドに対して、Attributeを設定できるらしいが、どうやって使うかはっきりわからず。詳しくは、MSのページを参照。

VisualStudio上でUnitTestを実施

[テスト] > [実行] の中のメニューを選んで、UnitTestを実施する。
または、[テスト] > [ウインドウ] > [テストエクスプローラ] でテストエクスプローラを開き、そこでもテストの実行ができる。
image.png

[実行]ではなく、[デバッグ]をすると、UnitTestのコード上でBreakを貼ったり、step実行ができる。

コンソールでUnitTestを実施

必要物をダウンロード

テストエージェントvstest.console.exeが必要。下記の「VisualStudio2019のツール」からダウンロードする。

https://visualstudio.microsoft.com/ja/downloads/?q=agents
image.png

コンソールで実施

インストール後、「VSTest.Console.exe 」を使用して、テストを行う。
書式は、

vstest.console.exe "UnitTestのプロジェクトが吐いたDLL" "オプション"

UnitTest用.bat
rem Unitテスト実施用bat
rem x86用 ログを出力
rem ログは、「カレントディレクトリ\TestResults」に出力される
cd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\"
vstest.console.exe "C:\Users\masa\Documents\myTortoiseGit\WPF-\020_CppDllProject\Debug\UnitTestCpp.dll" /platform:x86 /inIsolation /Logger:trx
pause

※注意※
上のbatでは、vstest.console.exeのあるフォルダとしてC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\としているが、VisualStudioを入れずに上のダウンロードからVSTESTのエージェントだけを入れた場合は、フォルダが別になる。その場合は、パスを自分のPCにあったものにすること。
例)私のPCの場合は下記にあった。
C:\Program Files (x86)\Microsoft Visual Studio\2019\TestAgent\Common7\IDE\Extensions\TestPlatform\vstest.console.exe

実行すると、このような窓が表示される。
image.png

ログは、カレントディレクトリにできた「TestResults」フォルダ内に保存される。
.trxファイルを開くと、VisualStudioで結果を見ることができる。
image.png
※BEGIN_TEST_METHOD_ATTRIBUTEで設定したTEST_PRIORITYの値は、この結果で見れるっぽい。vstestの実行パラメータに、優先順位を指定できるので、そこに生きると思われる。(未検証)

C#のUnitTestについて

C++とほとんど同じやり方でUnitTestできる。下記のページを参照。

MsTestによるユニットテストの解説

https://qiita.com/mima_ita/items/55394bcc851eb8b6dc24
VSの設定からプロジェクトの設定、コードの書き方まで詳しく書いてくれている。
これ見れば一通りできそう。(コマンドラインでの実施も書いてくれている)

MS docs

公式ページ。単体テストのやり方はいくつかあるらしく(MSTestとか、xUnitとか)、その説明が書かれたページ。

MSTestのコマンドラインパラメータの一覧

参照(C++)

Visual StudioでC ++用のMicrosoft単体テストフレームワークを使用する

Microsoft.VisualStudio.TestTools.CppUnitTestFramework APIリファレンス(Assertとか、Attributeとか)
https://docs.microsoft.com/ja-jp/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference?view=vs-2019#cppUnitTestAssert_h

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14