概要
Catch2 は C++ のテストフレームワークで、簡潔で自然なテスト記述方法で知られており、セクションベースの共有セットアップ/クリーンアップ、BDD マクロ、基本的なマイクロベンチマーク機能をサポートしています。外部依存は不要で、シングルヘッダーファイルまたはコンパイル済みライブラリとして使用できます。
README プレビュー
\n\n\n[](https://github.com/catchorg/catch2/releases)\n[](https://github.com/catchorg/Catch2/actions/workflows/linux-simple-builds.yml)\n[](https://github.com/catchorg/Catch2/actions/workflows/linux-other-builds.yml)\n[](https://github.com/catchorg/Catch2/actions/workflows/mac-builds.yml)\n[](https://ci.appveyor.com/project/catchorg/catch2)\n[](https://codecov.io/gh/catchorg/Catch2)\n[](https://godbolt.org/z/EdoY15q9G)\n[](https://discord.gg/4CWS9zD)\n\n\n## What is Catch2?\n\nCatch2 is mainly a unit testing framework for C++, but it also\nprovides basic micro-benchmarking features, and simple BDD macros.\n\nCatch2's main advantage is that using it is both simple and natural.\nTest names do not have to be valid identifiers, assertions look like\nnormal C++ boolean expressions, and sections provide a nice and local way\nto share set-up and tear-down code in tests.\n\n**Example unit test**\n```cpp\n#include \n\n#include \n\nuint32_t factorial( uint32_t number ) {\n return number \n#include \n\n#include \n\nuint64_t fibonacci(uint64_t number) {\n return number < 2 ? number : fibonacci(number - 1) + fibonacci(number - 2);\n}\n\nTEST_CASE("Benchmark Fibonacci", "[!benchmark]") {\n REQUIRE(fibonacci(5) == 5);\n\n REQUIRE(fibonacci(20) == 6'765);\n BENCHMARK("fibonacci 20") {\n return fibonacci(20);\n };\n\n REQUIRE(fibonacci(25) == 75'025);\n BENCHMARK("fibonacci 25") {\n return fibonacci(25);\n };\n}\n```\n\n_Note that benchmarks are not run by default, so you need to run it explicitly\nwith the `[!benchmark]` tag._\n\n\n## Catch2 v3 has been released!\n\nYou are on the `devel` branch, where the v3 version is being developed.\nv3 brings a bunch of significant changes, the big one being that Catch2\nis no longer a single-header library. Catch2 now behaves as a normal\nlibrary, with multiple headers and separately compiled implementation.\n\nThe documentation is slowly being updated to take these changes into\naccount, but this workFAQ (5)
トラブル対応誤った _MSVC_VER マクロが原因で Catch2 v3.16.0 が MSVC 環境で最適化を再有効化しない問題を修正する方法
Catch2 の amalgamated ヘッダー(例:catch_amalgamated.hpp)で 1523 行目に移動し、最適化を再度有効にする pragma をガードしているプリプロセッサチェック内の誤ったマクロ _MSVC_VER を _MSC_VER に置き換えてください。その後、プロジェクトを再ビルドしてください。修正例:#if defined(_MSVC_VER) を #if defined(_MSC_VER) に変更します。この問題はコミット 45f9ea1e798c2e128dcba53602ccbddfe5676f6f で導入されたものです。パッチ適用済みのリリースが利用可能になった場合はそれを使用するか、回避策としてローカルのヘッダー修正を維持してください。
トラブル対応失敗したテストがCTest経由で実行される場合にのみ、追加のCatch2診断出力を表示するにはどうすればよいですか?
-s を指定した INFO()/WARN() の代わりに、Catch2 のイベントリスナーを使用してください。診断情報をグローバル変数またはスレッドセーフなシングルトンに保存し、テストに失敗がある場合にのみ testCaseEnded() から stderr に書き出します。CTest の --output-on-failure によって、その stderr 出力が表示されます。
#include <catch2/catch_test_macros.hpp>
#include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <iostream>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>
std::mutex g_failureInfoMutex;
std::vector<std::string> g_failureInfo;
#define FAIL_INFO(expr) \
do { \
std::ostringstream oss; \
oss << expr; \
std::lock_guard<std::mutex> lock(g_failureInfoMutex); \
g_failureInfo.push_back(oss.str()); \
} while (false)
class FailureInfoListener : public Catch::EventListenerBase {
public:
using EventListenerBase::EventListenerBase;
void testCaseStarting(Catch::TestCaseInfo const&) override {
std::lock_guard<std::mutex> lock(g_failureInfoMutex);
g_failureInfo.clear();
}
void testCaseEnded(Catch::TestCaseStats const& stats) override {
if (stats.totals.assertions.allOk()) {
return;
}
std::cerr << "Additional failure information:\n";
std::lock_guard<std::mutex> lock(g_failureInfoMutex);
for (auto const& line : g_failureInfo) {
std::cerr << line << '\n';
}
}
};
CATCH_REGISTER_LISTENER(FailureInfoListener)
テストでは次のように使用します:
TEST_CASE("GPU test") {
FAIL_INFO("GPU: " << gpuName);
REQUIRE(false);
}
次のように実行します:
ctest --output-on-failure
Catch2 にはレジストリからリスナーインスタンスを取得する方法が用意されていないため、リスナーは共有のグローバル変数を読み取るようにしてください。診断情報が複数のスレッドから記録される可能性がある場合は、ミューテックスを使用してください。カスタムレポーターも選択肢の一つですが、イベントリスナーの方がシンプルで推奨されるアプローチです。
トラブル対応Catch2のcatch_discover_testsのTEST_PREFIXで末尾のスペースを保持するにはどうすればよいですか?
Catch2 v2.13.4 と CMake v3.10.3 の組み合わせでは、TEST_PREFIX が add_custom_command() を介して渡される際に末尾のスペースが失われます。ビルドで使用している Catch.cmake (通常は contrib/Catch.cmake の 160 行目付近) を編集し、以下を:
-D "TEST_PREFIX=${_TEST_PREFIX}"
次のように置き換えてください:
-D "TEST_PREFIX='${_TEST_PREFIX}'"
同等の形式は次のとおりです:
-D TEST_PREFIX='${_TEST_PREFIX}'
add_custom_command() 呼び出しの VERBATIM はそのまま残してください。テスト検出スクリプトが再生成されるよう、再構成してリビルドします:
cmake -S . -B build
cmake --build build
ctest --test-dir build -N
この変更により、TEST_PREFIX "${TARGET} " は <target><test name> ではなく <target> <test name> のような CTest 名を生成するようになります。Catch.cmake にパッチを適用できない場合は、一時的な回避策として ${TARGET}. や ${TARGET}: のようなスペース以外の区切り文字を使用してください。
トラブル対応Clang 20 での Catch2 ビルド失敗の修正方法: '-Wunreachable-code-return' と 'no matching function for call to get_wrapper'
Clang 20のビルド修正が含まれるv3.9.1以降にCatch2をアップグレードしてください。Gitチェックアウトの場合は、以下を実行します:
git fetch --tags
git checkout v3.9.1
CXX=clang++ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
Catch2ライブラリのみが必要でセルフテストが不要な場合は、回避策として開発ビルドを無効にしてください:
CXX=clang++ cmake -S . -B build -DCATCH_DEVELOPMENT_BUILD=OFF
cmake --build build
この失敗は開発/セルフテストのターゲットで発生するため、CATCH_DEVELOPMENT_BUILD=OFFでビルドすることで、失敗するテストファイルのコンパイルを回避できます。-Wno-error=unreachable-code-returnを使用しても最初の警告が抑制されるだけで、get_wrapperテンプレートエラーは解決されません。
トラブル対応macOS または Alpine で TEMPLATE_PRODUCT_TEST_CASE を使用した際に発生する Catch2 の "no matching function for call to 'get_wrapper'" エラーを修正する方法
これはテストの構文が原因ではなく、libc++ を組み合わせた Clang 20/21 が原因です。Clang は、アリティの異なる型リストを指定した TEMPLATE_PRODUCT_TEST_CASE を拒否します。Clang 22 でこのコンパイラ側の問題は修正されており、Catch2 PR #3173 では回避策が追加されています。
修正するには、Catch2 を 3.15.0 から PR #3173 を含む新しい v3.x リリース、または最新の v3.x バージョンにアップグレードしてください。Meson サブプロジェクトの場合は、subprojects/catch2.wrap を更新して次を実行します:
meson subprojects update catch2
meson setup --reconfigure build
CMake FetchContent の場合は、GIT_TAG を最新の Catch2 v3.x リリースに更新して再構成してください。
その他の回避策:
- コンパイラを Clang 22 にアップグレードする。
- Catch2 をすぐにアップグレードできない場合は、catchorg/Catch2 PR #3173 の変更を cherry-pick またはバックポートする。