このチュートリアルでは、Linux/Windows クロスプラットフォーム環境において、Google Test フレームワークを使用して C言語プログラムをテストする方法を詳しく説明します。
本プロジェクトでは、Google Test (gtest/gmock) を使用してC言語プログラムのユニットテストを行います。
Linux では GCC、Windows では MSVC を使用したクロスプラットフォーム開発環境をサポートしています。
-Wl,--wrap、Windows では適切なリンカオプションを使用した関数の置き換え本フレームワークでは、テストコードを以下の4つのフェーズに分けて記述します:
c-modernization-kit/
+-- testfw/ # テストフレームワーク (サブモジュール)
| +-- cmnd/ # テスト支援コマンド
| +-- include/ # フレームワーク提供のモック (stdio等)
| +-- include_override/ # オーバーライド用ヘッダー
| +-- libsrc/ # フレームワーク提供のモック実装
| +-- docs-src/ # テストフレームワークドキュメント
+-- makefw/ # Make ビルドフレームワーク (サブモジュール)
| +-- makefiles/ # makefile テンプレート
| +-- prepare.mk # 準備処理
| +-- makemain.mk # ビルドルール生成
+-- test/ # テストコード (本プロジェクト固有)
| +-- include/ # プロジェクト固有のモックヘッダー
| | +-- mock_calc.h # calcHandlerのモック
| | +-- mock_calcbase.h # add, subtract, multiply, divide のモック
| +-- libsrc/ # プロジェクト固有のモック実装
| | +-- mock_calc/ # calcHandler モックライブラリ
| | | +-- makefile # 標準テンプレート
| | | +-- makepart.mk # プロジェクト固有の設定
| | | +-- mock_calc.cc
| | | +-- mock_calcHandler.cc
| | +-- mock_calcbase/ # calcbase 関数モックライブラリ
| | +-- makefile # 標準テンプレート
| | +-- makepart.mk # プロジェクト固有の設定
| | +-- mock_calcbase.cc
| | +-- mock_add.cc
| | +-- mock_subtract.cc
| | +-- mock_multiply.cc
| | +-- mock_divide.cc
| +-- src/ # テストコード
| +-- calc/
| +-- libcalcbaseTest/ # ライブラリ関数のテスト
| | +-- addTest/
| | +-- makefile # 標準テンプレート
| | +-- makepart.mk # プロジェクト固有の設定
| | +-- addTest.cc
| +-- main/ # main関数を含むプログラムのテスト
| +-- addTest/
| | +-- makefile # 標準テンプレート
| | +-- makepart.mk # プロジェクト固有の設定
| | +-- addTest.cc
| +-- calcTest/
| +-- makefile # 標準テンプレート
| +-- makepart.mk # プロジェクト固有の設定
| +-- calcTest.cc
+-- prod/ # テスト対象のソースコード
+-- calc/
+-- include/
| +-- libcalcbase.h # 静的リンク用API
| +-- libcalc.h # 動的リンク用API
| +-- libcalc_const.h # 定数定義
+-- libsrc/
| +-- calcbase/
| +-- add.c # add関数の実装
| +-- subtract.c # subtract関数の実装
| +-- multiply.c # multiply関数の実装
| +-- divide.c # divide関数の実装
+-- src/
+-- add/
| +-- add.c # addコマンドのmain関数
+-- calc/
+-- calc.c # calcコマンドのmain関数
sudo apt-get install -y \
build-essential \
g++ \
make \
libgtest-dev \
libgmock-dev \
gcovr \
lcov
sudo dnf install -y \
gcc \
g++ \
make \
gtest-devel \
gmock-devel \
python3-pip
sudo pip3 install gcovrWindows では、Start-VSCode-With-Env.ps1 を実行して VS Code を起動します:
.\Start-VSCode-With-Env.ps1cd /path/to/c-modernization-kit
git submodule update --init --recursiveプロジェクトのルートディレクトリに .workspaceRoot ファイルを作成します:
touch .workspaceRoot
New-Item .workspaceRoot -ItemType File
type nul > .workspaceRootこのファイルにより、makefile がプロジェクトルートを自動検出できます。
モックを作成することで、テスト対象のコードが依存する関数の動作を制御できます。
test/include/mock_xxxxx.h にモックヘッダーを作成します。
#ifndef _MOCK_CALCBASE_H
#define _MOCK_CALCBASE_H
#include <stdio.h>
#include <gmock/gmock.h>
// テスト対象のヘッダーをインクルード
#include <libcalcbase.h>
// モッククラスの定義
class Mock_calcbase
{
public:
// MOCK_METHOD マクロで関数をモック化
// 構文: MOCK_METHOD(戻り値の型, 関数名, (引数リスト));
MOCK_METHOD(int, add, (int, int, int *));
MOCK_METHOD(int, subtract, (int, int, int *));
MOCK_METHOD(int, multiply, (int, int, int *));
MOCK_METHOD(int, divide, (int, int, int *));
Mock_calcbase();
~Mock_calcbase();
};
// グローバルなモックインスタンスへのポインタ
extern Mock_calcbase *_mock_calcbase;
#endif // _MOCK_CALCBASE_Htest/libsrc/mock_xxxxx/mock_xxxxx.cc にモッククラスの実装を作成します。
#include <testfw.h>
#include <mock_calcbase.h>
// グローバルインスタンスの実体
Mock_calcbase *_mock_calcbase = nullptr;
// コンストラクタ: デフォルト動作を設定
Mock_calcbase::Mock_calcbase()
{
// デフォルト動作を設定 (オプション)
ON_CALL(*this, add(_, _, _))
.WillByDefault(Invoke([](int a, int b, int *result) {
*result = a + b;
return CALC_SUCCESS;
})); // モックの既定の挙動を定義する例
ON_CALL(*this, subtract(_, _, _))
.WillByDefault(Return(CALC_SUCCESS)); // 一般的にはモックの既定の挙動は NOP にしておき、テストプログラムで具体的な挙動を決める
ON_CALL(*this, multiply(_, _, _))
.WillByDefault(Return(CALC_SUCCESS));
ON_CALL(*this, divide(_, _, _))
.WillByDefault(Return(CALC_SUCCESS));
_mock_calcbase = this;
}
// デストラクタ: グローバルポインタをクリア
Mock_calcbase::~Mock_calcbase()
{
_mock_calcbase = nullptr;
}test/libsrc/mock_xxxxx/mock_関数名.cc にC言語関数のモック実装を作成します。
#include <testfw.h>
#include <mock_calcbase.h>
// C言語の関数として実装
// この関数がテスト時に本物の add() 関数の代わりに呼ばれます
// WEAK_ATR 属性により、リンク時に弱いシンボルとして扱われる
WEAK_ATR int add(int a, int b, int *result)
{
int rtc = 0;
// モックインスタンスが存在する場合はモックを呼び出す
if (_mock_calcbase != nullptr)
{
rtc = _mock_calcbase->add(a, b, result);
}
// トレース出力 (デバッグ用)
if (getTraceLevel() > TRACE_NONE)
{
printf(" > %s %d, %d, 0x%p", __func__, a, b, (void *)result);
if (getTraceLevel() >= TRACE_DETAIL)
{
printf(" -> %d, %d\n", *result, rtc);
}
else
{
printf("\n");
}
}
return rtc;
}extern "C" は不要 (.cc ファイルでも関数名が C++ にならない)_mock_calcbase != nullptr でモックの有無を確認test/libsrc/mock_xxxxx/ ディレクトリに以下のファイルを作成します。
test/libsrc/mock_xxxxx/makefile は標準テンプレートをそのまま使用します。
find-up = \
$(if $(wildcard $(1)/$(2)),$(1),\
$(if $(filter $(1),$(patsubst %/,%,$(dir $(1)))),,\
$(call find-up,$(patsubst %/,%,$(dir $(1))),$(2))\
)\
)
WORKSPACE_FOLDER := $(strip $(call find-up,$(CURDIR),.workspaceRoot))
include $(WORKSPACE_FOLDER)/makefw/makefiles/prepare.mk
##### makepart.mk の内容は、このタイミングで処理される #####
include $(WORKSPACE_FOLDER)/makefw/makefiles/makemain.mktest/libsrc/mock_xxxxx/makepart.mk にプロジェクト固有の設定を記述します。
OUTPUT_DIR := $(WORKSPACE_FOLDER)/test/lib
SRCS := \
mock_calcbase.cc \
mock_add.cc \
mock_subtract.cc \
mock_multiply.cc \
mock_divide.cc通常の関数 (main を含まない) のテスト方法を説明します。
#include <testfw.h>
#include <mock_stdio.h>
#include <libcalcbase.h>
// テストフィクスチャクラス
class addTest : public Test
{
};
// テストケース
TEST_F(addTest, test_1_add_2)
{
// Arrange (状態設定)
int result;
// Pre-Assert (期待動作設定)
// - モックの期待動作を設定 (この例では不要)
// Act (実行)
int rtc = add(1, 2, &result); // [手順] - add(1, 2, &result) を呼び出す。
// Assert (検証)
EXPECT_EQ(CALC_SUCCESS, rtc); // [確認] - 戻り値が CALC_SUCCESS であること。
EXPECT_EQ(3, result); // [確認] - 結果が 3 であること。
}test/src/calc/libcalcbaseTest/addTest/addTest.cc
#include <testfw.h>
#include <mock_stdio.h>
#include <libcalcbase.h>
class addTest : public Test
{
};
// 正の数の加算テスト
TEST_F(addTest, test_1_add_2)
{
// Arrange
int result;
// Pre-Assert
// Act
int rtc = add(1, 2, &result); // [手順] - add(1, 2, &result) を呼び出す。
// Assert
EXPECT_EQ(CALC_SUCCESS, rtc); // [確認] - 戻り値が CALC_SUCCESS であること。
EXPECT_EQ(3, result); // [確認] - 結果が 3 であること。
}
// 交換法則のテスト
TEST_F(addTest, test_2_add_1)
{
// Arrange
int result;
// Pre-Assert
// Act
int rtc = add(2, 1, &result); // [手順] - add(2, 1, &result) を呼び出す。
// Assert
EXPECT_EQ(CALC_SUCCESS, rtc); // [確認] - 戻り値が CALC_SUCCESS であること。
EXPECT_EQ(3, result); // [確認] - 結果が 3 であること。
}
// NULLポインタのテスト
TEST_F(addTest, test_null_result)
{
// Arrange
// Pre-Assert
// Act
int rtc = add(1, 2, NULL); // [手順] - add(1, 2, NULL) を呼び出す。
// Assert
EXPECT_EQ(CALC_ERROR, rtc); // [確認] - 戻り値が CALC_ERROR であること。
}main関数を含むプログラムをテストするには、リンカラップ機能を使用します。
GCCの -Wl,--wrap=main オプションを使用すると:
main 関数は __wrap_main として定義されるmain 関数は __real_main として参照可能になるgtest_wrapmain ライブラリが __wrap_main を提供し、Google Test を起動#include <testfw.h>
#include <mock_stdio.h>
#include <mock_calcbase.h>
class addTest : public Test
{
};
TEST_F(addTest, less_argc)
{
// Arrange
int argc = 2;
const char *argv[] = {"addTest", "1"}; // [状態] - main() に与える引数を、"1" **(不足)** とする。
// Pre-Assert
// Act
int rtc = __real_main(argc, (char **)&argv); // [手順] - main() に引数を与えて呼び出す。
// Assert
EXPECT_NE(0, rtc); // [確認] - main() の戻り値が 0 以外であること。
}
TEST_F(addTest, normal)
{
// Arrange
NiceMock<Mock_stdio> mock_stdio;
Mock_calcbase mock_calcbase;
int argc = 3;
const char *argv[] = {"addTest", "1", "2"}; // [状態] - main() に与える引数を、"1", "2" とする。
// Pre-Assert
EXPECT_CALL(mock_calcbase, add(1, 2, _))
.WillOnce([](int, int, int *result) {
*result = 3;
return CALC_SUCCESS;
}); // [Pre-Assert確認] - add(1, 2, &result) が 1 回呼び出されること。
// [Pre-Assert手順] - add(1, 2, &result) にて result に 3 を設定し、CALC_SUCCESS を返す。
EXPECT_CALL(mock_stdio, printf(_, _, _, StrEq("3\n")))
.WillOnce(DoDefault()); // [Pre-Assert確認] - printf() が 1 回呼び出され、内容が "3\n" であること。
// Act
int rtc = __real_main(argc, (char **)&argv); // [手順] - main() に引数を与えて呼び出す。
// Assert
EXPECT_EQ(0, rtc); // [確認] - main() の戻り値が 0 であること。
}NiceMock<T> は、未設定のモック呼び出しを許容するラッパーです。
// 例: stdio のモックは多数の関数があるため、
// 全てを EXPECT_CALL で設定するのは煩雑
// NiceMock を使うことで、必要な呼び出しだけを検証できる
NiceMock<Mock_stdio> mock_stdio;テストディレクトリに以下のファイルを作成します。
test/src/calc/libcalcbaseTest/addTest/makefile は標準テンプレートをそのまま使用します。
find-up = \
$(if $(wildcard $(1)/$(2)),$(1),\
$(if $(filter $(1),$(patsubst %/,%,$(dir $(1)))),,\
$(call find-up,$(patsubst %/,%,$(dir $(1))),$(2))\
)\
)
WORKSPACE_FOLDER := $(strip $(call find-up,$(CURDIR),.workspaceRoot))
include $(WORKSPACE_FOLDER)/makefw/makefiles/prepare.mk
##### makepart.mk の内容は、このタイミングで処理される #####
include $(WORKSPACE_FOLDER)/makefw/makefiles/makemain.mktest/src/calc/libcalcbaseTest/addTest/makepart.mk にプロジェクト固有の設定を記述します。
TEST_SRCS := \
$(WORKSPACE_FOLDER)/prod/calc/libsrc/calcbase/add.ctest/src/calc/main/addTest/makefile は標準テンプレートをそのまま使用します。
find-up = \
$(if $(wildcard $(1)/$(2)),$(1),\
$(if $(filter $(1),$(patsubst %/,%,$(dir $(1)))),,\
$(call find-up,$(patsubst %/,%,$(dir $(1))),$(2))\
)\
)
WORKSPACE_FOLDER := $(strip $(call find-up,$(CURDIR),.workspaceRoot))
include $(WORKSPACE_FOLDER)/makefw/makefiles/prepare.mk
##### makepart.mk の内容は、このタイミングで処理される #####
include $(WORKSPACE_FOLDER)/makefw/makefiles/makemain.mktest/src/calc/main/addTest/makepart.mk にプロジェクト固有の設定を記述します。
TEST_SRCS := \
$(WORKSPACE_FOLDER)/prod/calc/src/add/add.c
USE_WRAP_MAIN := 1
LIBS += mock_calcbase mock_libcこの分離により、ビルドシステムの更新が容易になり、保守性が向上します。
makefile テンプレート内で find-up 関数を使用して .workspaceRoot ファイルを検出し、プロジェクトルートを特定します。
find-up = \
$(if $(wildcard $(1)/$(2)),$(1),\
$(if $(filter $(1),$(patsubst %/,%,$(dir $(1)))),,\
$(call find-up,$(patsubst %/,%,$(dir $(1))),$(2))\
)\
)
WORKSPACE_FOLDER := $(strip $(call find-up,$(CURDIR),.workspaceRoot))include $(WORKSPACE_FOLDER)/makefw/makefiles/prepare.mk
include $(WORKSPACE_FOLDER)/makefw/makefiles/makemain.mkUSE_WRAP_MAIN := 1: main関数をラップして __real_main として呼び出し可能にする
-Wl,--wrap=main オプションが自動的に設定されるLIBS: リンクするライブラリ (プレフィックス -l なしで指定)
mock_xxxxx: モックライブラリmock_libc: 標準C関数のモック (stdio等)例:
LIBS += mock_calcbase mock_libcプロジェクトルートから:
cd test
make clean # クリーンビルド
make # ビルド
make test # テスト実行Windows の注意: コマンドプロンプトで環境設定スクリプトを実行してから make を実行してください。
特定のテストディレクトリで:
cd test/src/calc/libcalcbaseTest/addTest
make testフィルター機能を使用:
export GTEST_FILTER=*test_1_add_2*
make test
export -n GTEST_FILTER # フィルターを解除
make test GTEST_FILTER=*test_1_add_2*REM Windows (コマンドプロンプト)
REM 方法1: 環境変数で指定
set GTEST_FILTER=*test_1_add_2*
make test
set GTEST_FILTER=
REM 方法2: makeコマンドに指定
make test GTEST_FILTER=*test_1_add_2*$env:GTEST_FILTER="*test_1_add_2*"
make test
Remove-Item Env:\GTEST_FILTER
make test GTEST_FILTER=*test_1_add_2*cd test
make test # テスト実行 (カバレッジデータ収集)
gcovr --exclude-unreachable-branches注意: Windows でのコードカバレッジ取得は、使用するツールによって手順が異なります。
MSVC 環境では、Visual Studio のコードカバレッジツールまたはサードパーティツールの使用を検討してください。
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from addTest
[ RUN ] addTest.test_1_add_2
[ OK ] addTest.test_1_add_2 (0 ms)
[ RUN ] addTest.test_2_add_1
[ OK ] addTest.test_2_add_1 (0 ms)
[----------] 2 tests from addTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test suite ran. (0 ms total)
[ PASSED ] 2 tests.
test/src/calc/main/calcTest/calcTest.cc
#include <testfw.h>
#include <mock_stdio.h>
#include <mock_calc.h>
class calcTest : public Test
{
};
// 引数不足のテスト
TEST_F(calcTest, less_argc)
{
// Arrange
int argc = 2;
const char *argv[] = {"calcTest", "1"}; // [状態] - main() に与える引数を、"1" **(不足)** とする。
// Pre-Assert
// Act
int rtc = __real_main(argc, (char **)&argv); // [手順] - main() に引数を与えて呼び出す。
// Assert
EXPECT_NE(0, rtc); // [確認] - main() の戻り値が 0 以外であること。
}
// 正常系のテスト
TEST_F(calcTest, normal)
{
// Arrange
NiceMock<Mock_stdio> mock_stdio;
Mock_calc mock_calc;
int argc = 4;
const char *argv[] = {"calcTest", "1", "+", "2"}; // [状態] - main() に与える引数を、"1", "+", "2" とする。
// Pre-Assert
EXPECT_CALL(mock_calc, calcHandler(CALC_KIND_ADD, 1, 2, _))
.WillOnce([](int, int, int, int *result) {
*result = 3;
return CALC_SUCCESS;
}); // [Pre-Assert確認] - calcHandler(CALC_KIND_ADD, 1, 2, &result) が 1 回呼び出されること。
// [Pre-Assert手順] - calcHandler(CALC_KIND_ADD, 1, 2, &result) にて result に 3 を設定し、CALC_SUCCESS を返す。
EXPECT_CALL(mock_stdio, printf(_, _, _, StrEq("3\n")))
.WillOnce(DoDefault()); // [Pre-Assert確認] - printf() が 1 回呼び出され、内容が "3\n" であること。
// Act
int rtc = __real_main(argc, (char **)&argv); // [手順] - main() に引数を与えて呼び出す。
// Assert
EXPECT_EQ(0, rtc); // [確認] - main() の戻り値が 0 であること。
}このテストの makepart.mk:
TEST_SRCS := \
$(WORKSPACE_FOLDER)/prod/calc/src/calc/calc.c
USE_WRAP_MAIN := 1
LIBS += mock_calc mock_libcTEST_F(MyTest, call_times_check)
{
Mock_calcbase mock;
// 期待: add が正確に 2 回呼ばれること
EXPECT_CALL(mock, add(_, _))
.Times(2)
.WillRepeatedly(Return(0));
// 実際の呼び出し
add(1, 2);
add(3, 4);
// テスト終了時に自動検証される
}TEST_F(MyTest, call_order_check)
{
Mock_calcbase mock;
InSequence seq; // 順序を保証
EXPECT_CALL(mock, add(1, 2)).Times(1);
EXPECT_CALL(mock, add(3, 4)).Times(1);
// この順序で呼ばれる必要がある
add(1, 2);
add(3, 4);
}TEST_F(MyTest, argument_check)
{
Mock_stdio mock_stdio;
// 第4引数が "Hello" という文字列であることを検証
EXPECT_CALL(mock_stdio, printf(_, _, _, StrEq("Hello\n")))
.Times(1);
printf("%s", "", "", "Hello\n");
}TEST_F(MyTest, multiple_returns)
{
Mock_calcbase mock;
EXPECT_CALL(mock, add(_, _))
.WillOnce(Return(10)) // 1回目は 10
.WillOnce(Return(20)) // 2回目は 20
.WillRepeatedly(Return(0)); // 3回目以降は 0
EXPECT_EQ(10, add(1, 2)); // 1回目
EXPECT_EQ(20, add(3, 4)); // 2回目
EXPECT_EQ(0, add(5, 6)); // 3回目以降
}4つのフェーズを明確にコメントで記述:
TEST_F(MyTest, test_case)
{
// Arrange
// - テストデータの準備
// Pre-Assert
// - モックの期待動作設定
// Act
// - テスト対象の実行
// Assert
// - 結果の検証
}テストケース名は具体的かつ分かりやすく:
test_add_positive_numberstest_main_with_insufficient_argstest1, test_normalモックオブジェクトはテストケース内で宣言:
TEST_F(MyTest, test_case)
{
// このスコープ内でモックが有効
Mock_calcbase mock;
// テストコード
}
// スコープを抜けるとモックが破棄される複雑なモック (stdio等) は NiceMock を使用:
// 多数の関数を持つモックは NiceMock で簡潔に
NiceMock<Mock_stdio> mock_stdio;
// 検証したい呼び出しのみ EXPECT_CALL で指定
EXPECT_CALL(mock_stdio, printf(_, _, _, StrEq("result\n")))
.WillOnce(DoDefault());各テストケースは独立して実行可能にする:
class MyTest : public Test
{
protected:
void SetUp() override
{
// 各テストケース実行前の初期化
}
void TearDown() override
{
// 各テストケース実行後のクリーンアップ
}
};正常系だけでなく異常系もテスト:
// 正常系
TEST_F(MyTest, normal_case) { /* ... */ }
// 境界値
TEST_F(MyTest, boundary_case) { /* ... */ }
// エラーケース
TEST_F(MyTest, error_case) { /* ... */ }
// NULL ポインタ
TEST_F(MyTest, null_pointer_case) { /* ... */ }テストの意図を日本語コメントで明確に:
// Act
int rtc = add(1, 2); // [手順] - add(1, 2) を呼び出す。
// Assert
EXPECT_EQ(3, rtc); // [確認] - 戻り値が 3 であること。makefile と makepart.mk を分離:
共通処理はフレームワークに集約:
makefw/makefiles/prepare.mk: 準備処理makefw/makefiles/makemain.mk: ビルドルール生成この分離により、ビルドシステムの更新が容易になり、保守性が向上します。
定期的にカバレッジを確認:
make test
gcovr --exclude-unreachable-branches --html --html-details -o coverage.htmlテストを自動化:
#!/bin/bash
cd test
make clean
make
make test
if [ $? -ne 0 ]; then
echo "Tests failed!"
exit 1
fi
echo "All tests passed!"@echo off
REM test-runner.bat (Windows)
cd test
make clean
make
make test
if %ERRORLEVEL% neq 0 (
echo Tests failed!
exit /b 1
)
echo All tests passed!異なるプラットフォームでコードを保守する際のベストプラクティス:
#ifdef _WIN32
// Windows 固有の処理
#else
// Linux 固有の処理
#endif原因: 必要なライブラリがリンクされていない
解決策: makefile の LIBS に追加
LIBS += -lmock_calcbase -ltest_com原因: 同じシンボルが複数回定義されている
解決策:
- モック関数の実装ファイルを確認
- TEST_SRCS に同じソースを重複して追加していないか確認
原因: __real_main が未定義
解決策: makepart.mk に USE_WRAP_MAIN := 1 を追加
USE_WRAP_MAIN := 1これにより、ビルドシステムが自動的にプラットフォームに応じた適切なリンカオプションを設定します。
原因: リンク順序の問題
解決策:
1. モックライブラリを makepart.mk の LIBS に追加
2. TEST_SRCS に実体のソースを含めない
LIBS += mock_calcbase # OK原因: Visual Studio Build Tools の環境変数が設定されていない
解決策: Start-VSCode-With-Env.ps1 で環境設定を実行
. .\Start-VSCode-With-Env.ps1 -EnvOnly原因: GCC と MSVC ではコンパイラオプションが異なる
解決策: makefw サブモジュールのビルドフレームワークが自動的にプラットフォームを検出し、
適切なコンパイラオプションを設定します。makefile の設定を確認してください。
testfw/docs-src/how-to-mock.mdtestfw/docs-src/how-to-test.mdtestfw/docs-src/about-test-phase.mdtestfw/docs-src/how-to-expect.mdtestfw/docs-src/how-to-extern.mdこのチュートリアルでは、以下の内容を説明しました:
USE_WRAP_MAIN := 1 による自動設定これらの知識を活用して、Linux/Windows 両対応の堅牢で保守性の高いテストコードを作成してください。