CTEST_CUSTOM_TESTS_IGNORE をマスターして CMake テストを極める


CTEST_CUSTOM_TESTS_IGNORE の仕組み

  1. テストの特定: CTEST_CUSTOM_TESTS_IGNORE は、正規表現またはセミコロンで区切られたテスト名のリストを使用して、除外するテストを指定します。
  2. 一致判定: CMake は、指定されたパターンと一致するテストを検索します。
  3. 除外処理: 一致するテストは CTest 実行リストから除外され、実行されません。

CTEST_CUSTOM_TESTS_IGNORE の利点

  • テストのデバッグ: 個々のテストを個別に実行することで、問題のあるテストを特定しやすくなります。
  • テスト時間の短縮: 実行しないテストを除外することで、テスト全体の時間を短縮できます。
  • テストの選択的実行: 特定の条件下でのみ実行すべきテストを制御できます。

CTEST_CUSTOM_TESTS_IGNORE の例

# 特定の正規表現に一致するテストをすべて除外
ctest_custom_tests_ignore(
  REGULAR_EXPRESSION
  "^MyTest.*"
)

# セミコロンで区切られたテスト名をリストアップして除外
ctest_custom_tests_ignore(
  SEMI_COLON_LIST
  "MyTest1;MyTest2"
)
  • テストの除外は、テストの開発やデバッグに役立ちますが、すべてのテストを実行していないことを忘れないように注意する必要があります。
  • テスト名が変更された場合、CTEST_CUSTOM_TESTS_IGNORE の設定も更新する必要があります。


cmake_minimum_required(VERSION 3.10)

project(MyProject)

add_executable(MyTest test1.cpp test2.cpp)

# 特定の正規表現に一致するテストをすべて除外
ctest_custom_tests_ignore(
  REGULAR_EXPRESSION
  "^MyTest.*"
)

add_test(MyTestTest MyTest)

例 2: セミコロンで区切られたテスト名をリストアップして除外

この例では、MyTest1MyTest2 というテスト名をセミコロンで区切ってリストアップし、それらを CTest 実行から除外します。

cmake_minimum_required(VERSION 3.10)

project(MyProject)

add_executable(MyTest test1.cpp test2.cpp)

# セミコロンで区切られたテスト名をリストアップして除外
ctest_custom_tests_ignore(
  SEMI_COLON_LIST
  "MyTest1;MyTest2"
)

add_test(MyTestTest MyTest)

例 3: 特定の条件に基づいてテストを動的に除外

この例では、MyCondition という変数の値に基づいてテストを動的に除外します。

cmake_minimum_required(VERSION 3.10)

project(MyProject)

add_executable(MyTest test1.cpp test2.cpp)

set(MyCondition OFF)

# 特定の条件に基づいてテストを動的に除外
if(MyCondition)
  ctest_custom_tests_ignore(
    REGULAR_EXPRESSION
    "^MyTest.*"
  )
endif()

add_test(MyTestTest MyTest)

説明

上記の例は、CTEST_CUSTOM_TESTS_IGNORE の基本的な使用方法を示しています。実際の使用方法は、プロジェクトの要件に応じて調整する必要があります。

  • テストを一時的に無効化したい場合は、ctest_exclude_test コマンドを使用することができます。
  • テストの実行を完全にスキップしたい場合は、add_test コマンドを使用せずに、target_link_libraries コマンドを使用してテストのターゲットをライブラリにリンクすることができます。


add_test コマンドの EXCLUDE_FROM_ALL 属性

利点

  • 個々のテストを個別に制御可能
  • シンプルで分かりやすい構文

欠点

  • すべてのテストケースを明示的に列挙する必要がある
  • 複雑な条件に基づいてテストを制御できない

add_test(MyTest1 test1.cpp)
set_property(TEST MyTest1 PROPERTY EXCLUDE_FROM_ALL TRUE)

add_test(MyTest2 test2.cpp)

CTest の --exclude-regex オプション

利点

  • 複雑な正規表現を使用してテストを指定可能
  • コマンドラインから簡単にテストを制御可能

欠点

  • 個々のテストを個別に制御できない
  • CMakeLists.txt ファイルを変更する必要がない

ctest --build --test --exclude-regex "^MyTest.*"

カスタムテストランナーの実装

利点

  • テストの実行順序や条件を自由に設定可能
  • 柔軟性と制御性に優れている

欠点

  • CMake に詳しくない場合は難しい
  • 複雑な実装が必要

#include <ctest/CTEST.h>

void myCustomTestRunner() {
  // テストの実行順序や条件を自由に設定
  CTEST_RUN_TEST(MyTest1)
  // ...
}

int main() {
  CTEST_MAIN(myCustomTestRunner)
}

テストデータに基づいてテストを制御

利点

  • テストケースを個別に記述する必要がない
  • テストの実行をデータに基づいて動的に制御可能

欠点

  • 複雑なロジックが必要になる場合がある
  • テストデータの管理が必要

set(MyTestData "data.json")

add_test(MyTest test.cpp)
set_property(TEST MyTest PROPERTY DEPENDS MyTestData)

ctest_target_depends(MyTestTarget MyTest)

最適な代替方法の選択

最適な代替方法は、プロジェクトの要件と開発者のスキルによって異なります。

  • テストの実行をデータに基づいて動的に制御したい場合は、テストデータに基づいてテストを制御 する方法がおすすめです。
  • 柔軟性と制御性に優れた方法が必要な場合は、カスタムテストランナーの実装 がおすすめです。
  • コマンドラインから簡単にテストを制御したい場合は、CTest の --exclude-regex オプション がおすすめです。
  • シンプルで分かりやすい方法が必要な場合は、add_test コマンドの EXCLUDE_FROM_ALL 属性 がおすすめです。