Qt Test 概要
Qt Test は、Qt ベースのアプリケーションやライブラリのユニットテストを行うためのフレームワークです。Qt Test は、ユニットテストフレームワークに一般的に見られるすべての機能に加え、グラフィカルユーザーインターフェースのテストのための拡張機能も提供します。
Qt Test は、Qtベースのアプリケーションやライブラリ向けのユニットテストの作成を容易にするように設計されています:
| 機能 | 詳細 |
|---|---|
| 軽量 | Qt Test 約6000行のコードと60個のエクスポートされたシンボルで構成されています。 |
| 独立した構成 | Qt Test 非GUIテストを行う場合、Qt Core モジュールから必要なシンボルはごくわずかです。 |
| 迅速なテスト | Qt Test 特別なテストランナーを必要とせず、テストのための特別な登録も不要です。 |
| データ駆動型テスト | 異なるテストデータを使用して、テストを複数回実行できます。 |
| 基本的な GUI テスト | Qt Test マウスおよびキーボードのシミュレーション機能を提供します。 |
| ベンチマーク | Qt Test ベンチマークをサポートし、いくつかの測定バックエンドを提供します。 |
| IDE との連携 | Qt Test Qt Creator 、Visual Studio、KDevelop で解釈可能なメッセージを出力します。 |
| スレッドセーフ | エラー報告はスレッドセーフかつアトミックです。 |
| 型安全性 | テンプレートを多用することで、暗黙的な型キャストに起因するエラーを防ぎます。 |
| 拡張が容易 | テストデータやテスト出力に、カスタム型を簡単に追加できます。 |
Qt Creator のウィザードを使用して、Qt Testを含むプロジェクトを作成し、Qt Creator から直接ビルドおよび実行することができます。詳細については、Qt Creator の「テストのビルドと実行」を参照してください。
テストの作成
テストを作成するには、QObject をサブクラス化し、そこに 1 つ以上のプライベートスロットを追加します。各プライベートスロットは、テスト内のテスト関数となります。QTest::qExec() を使用すると、テストオブジェクト内のすべてのテスト関数を実行できます。
さらに、テスト関数として扱われない以下のプライベートスロットを定義することもできます。これらが定義されている場合、テストフレームワークによって実行され、テスト全体または現在のテスト関数の初期化やクリーンアップに使用できます。
initTestCase()は、最初のテスト関数が実行される前に呼び出されます。initTestCase_data()は、グローバルなテストデータテーブルを作成するために呼び出されます。cleanupTestCase()は、最後のテスト関数が実行された後に呼び出されます。init()各テスト関数の実行前に呼び出されます。cleanup()すべてのテスト関数の実行後に呼び出されます。
テストの準備にはinitTestCase() を使用してください。すべてのテストは、システムを繰り返し実行可能な状態に保つ必要があります。クリーンアップ処理はcleanupTestCase() 内で処理するようにし、テストが失敗した場合でも実行されるようにしてください。
テスト関数の準備には `init() ` を使用してください。すべてのテスト関数は、システムを繰り返し実行可能な状態に保つ必要があります。クリーンアップ処理は `cleanup()` で行うようにし、テスト関数が失敗して早期に終了した場合でも実行されるようにしてください。
あるいは、RAII(リソースの取得は初期化である)を使用し、デストラクタ内でクリーンアップ処理を呼び出すことで、テスト関数が戻り、オブジェクトがスコープ外に出た際に確実にクリーンアップが行われるようにすることもできます。
initTestCase() が失敗した場合、どのテスト関数も実行されません。init() が失敗した場合、その次のテスト関数は実行されず、テストは次のテスト関数へと進みます。
例:
classMyFirstTest:publicQObject
{
Q_OBJECT
private:
boolmyCondition()
{
return true;
}
private slots:
voidinitTestCase()
{
qDebug("Called before everything else.");
}
voidmyFirstTest()
{
QVERIFY(true);// 条件が満たされていることを確認する
QCOMPARE(1, 1);// 2つの値を比較する
}
voidmySecondTest()
{
QVERIFY(myCondition());
QVERIFY(1 != 2);
}
voidcleanupTestCase()
{
qDebug("Called after myFirstTest and mySecondTest.");
}
};最後に、テストクラスに静的なパブリックメソッド `void initMain() ` がある場合、`QApplication ` オブジェクトがインスタンス化される前に、QTEST_MAIN マクロによってこのメソッドが呼び出されます。これはバージョン 5.14 で追加されました。
その他の例については、『Qt Test チュートリアル』を参照してください。
テスト関数のタイムアウト時間の延長
QtTest は、無限ループや類似のバグを検出するために、各テストの実行時間を制限します。デフォルトでは、テスト関数の呼び出しは5分経過後に中断されます。データ駆動型テストの場合、これは固有のデータタグを持つ各呼び出しに適用されます。 このタイムアウトは、QTEST_FUNCTION_TIMEOUT 環境変数を、1回の呼び出しに許容される最大時間(ミリ秒単位)に設定することで構成できます。テストが設定されたタイムアウト時間を超えると、テストは中断され、qFatal() が呼び出されます。その結果、デフォルトでは、テストはクラッシュしたかのように中止されます。
Linux または macOS のコマンドラインから `QTEST_FUNCTION_TIMEOUT ` を設定するには、次のように入力します:
QTEST_FUNCTION_TIMEOUT=900000
export QTEST_FUNCTION_TIMEOUTWindowsの場合:
SET QTEST_FUNCTION_TIMEOUT=900000その後、この環境内でテストを実行してください。
あるいは、テストコード内でプログラム的に環境変数を設定することも可能です。例えば、テストクラスの `initMain()`という特別なメソッドから以下のように呼び出す方法があります:
qputenv("QTEST_FUNCTION_TIMEOUT", "900000");タイムアウトの適切な値を算出するには、テストが通常どれくらいの時間を要するかを確認し、それが何らかの問題の兆候とならない範囲で、さらにどれくらいの時間まで許容できるかを判断してください。 その余裕時間をミリ秒単位に変換して、タイムアウト値として設定します。たとえば、数分かかるテストが、処理速度の遅いマシンなどでは最大20分までかかっても妥当であると判断した場合、20 * 60 * 1000 = 1200000 を掛け算し、上記の900000 の代わりに1200000 を環境変数に設定します。
テストのビルド
通常、本番コードの 1 つのクラスをテストする 1 つのテストクラスを含む実行可能ファイルをビルドできます。ただし、通常は 1 つのコマンドを実行して、プロジェクト内の複数のクラスをテストしたい場合が多いでしょう。
手順ごとの詳細については、「ユニットテストの記述」を参照してください。
CMakeとCTestを使用したビルド
CMakeとCTestを使用してテストを作成できます。CTestでは、テスト名との正規表現の一致に基づいて、テストを含めたり除外したりすることができます。さらに、テストにLABELS プロパティを適用することで、CTestはそれらのラベルに基づいてテストを含めたり除外したりできるようになります。コマンドラインでtest ターゲットが呼び出されると、ラベルが付けられたすべてのターゲットが実行されます。
注: Androidでは 、接続されているデバイスまたはエミュレータが 1 台の場合、そのデバイス上でテストが実行されます。複数のデバイスが接続されている場合は、環境変数 `ANDROID_DEVICE_SERIAL ` を、テストを実行したいデバイスのADB シリアル番号に設定してください。
CMakeには他にもいくつかの利点があります。例えば、CDashを使用すれば、テスト実行の結果をWebサーバーに公開することが、実質的に手間をかけずに可能です。
CTest は、非常に多様なユニットテストフレームワークに対応しており、QTest を使用すれば、設定不要で動作します。
以下は、プロジェクト名と使用言語(ここではmytestと C++)、テストのビルドに必要な Qt モジュール(Qt Test )、およびテストに含まれるファイル(tst_mytest.cpp)を指定した CMakeLists.txt ファイルの例です。
project(mytest LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS Test)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
enable_testing(true)
qt_add_executable(mytest tst_mytest.cpp)
add_test(NAME mytest COMMAND mytest)
target_link_libraries(mytest PRIVATE Qt::Test)利用可能なオプションの詳細については、「CMake によるビルド」を参照してください。
qmake によるビルド
qmake をビルドツールとして使用している場合は、プロジェクトファイルに以下を追加してください:
QT += testlibmake check 経由でテストを実行したい場合は、次の行を追加してください:
CONFIG += testcaseテストがターゲットにインストールされないようにするには、次の行を追加してください:
CONFIG += no_testcase_installsmake check に関する詳細については、qmakeのマニュアルを参照してください。
他のツールを使用したビルド
他のビルドツールを使用する場合は、Qt Test ヘッダーファイルの場所をインクルードパスに追加してください(通常は、Qtインストールディレクトリ下のinclude/QtTest です)。Qtのリリースビルドを使用する場合は、テストコードをQtTest ライブラリにリンクしてください。デバッグビルドの場合は、QtTest_debug を使用してください。
Qt Test コマンドライン引数
構文
autotest を実行するための構文は、次のようなシンプルな形式になります:
testname [options] [testfunctions[:testdata]]...testname を、実行ファイルの名前に置き換えてください。testfunctions には、実行するテスト関数の名前を含めることができます。testfunctions が指定されていない場合は、すべてのテストが実行されます。testdata に記載されているエントリ名を末尾に追加すると、そのテストデータのみを使用してテスト関数が実行されます。
例:
/myTestDirectory$ testQString toUppertoUpper というテスト関数を、利用可能なすべてのテストデータで実行します。
/myTestDirectory$ testQString toUpper toInt:zero利用可能なすべてのテストデータを使用してtoUpper というテスト関数を実行し、さらに「zero 」という名前のテストデータ行を使用してtoInt というテスト関数を実行します(指定されたテストデータが存在しない場合、関連するテストは失敗し、利用可能なデータタグが報告されます)。
/myTestDirectory$ testMyWidget -vs -eventdelay 500testMyWidget 関数のテストを実行し、すべての信号出力を出力するとともに、シミュレートされたマウス/キーボードイベントの発生後、それぞれ500ミリ秒待機します。
オプション
ロギングオプション
以下のコマンドラインオプションは、テスト結果の報告方法を指定します:
-ofilename,format
Writes output to the specified file, in the specified format (one oftxt,csv,junitxml,xml,lightxml,teamcityortap). Use the special filename-(hyphen) to log to standard output.-ofilename
指定されたファイルに出力を書き込みます。-
-txt
結果をプレーンテキストで出力します。 -
-csv
結果を、スプレッドシートへのインポートに適したカンマ区切り値(CSV)形式で出力します。このモードでは通常の合格/不合格メッセージが表示されないため、ベンチマークのみに適しています。 -
-junitxml
結果をJUnit XMLドキュメントとして出力します。 -
-xml
結果を XML ドキュメントとして出力します。 -
-lightxml
結果を XML タグのストリームとして出力します。 -
-teamcity
結果をTeamCity形式で出力します。 -
-tap
結果をTest Anything Protocol(TAP) 形式で出力します。
-o オプションの最初のバージョンは、テスト結果を複数の形式でログに記録するために繰り返し指定できますが、標準出力にテスト結果をログに記録できるこのオプションのインスタンスは1つまでです。
-o オプションの最初のバージョンが使用されている場合、-o オプションの 2 番目のバージョン、および-txt 、-xml 、-lightxml 、-teamcity 、-junitxml 、-tap オプションはいずれも使用しないでください。
-o オプションのいずれのバージョンも使用しない場合、テスト結果は標準出力に記録されます。formatオプションが指定されていない場合、テスト結果はプレーンテキストで記録されます。
テストログの詳細オプション
以下のコマンドラインオプションは、テストログに報告される詳細度を制御します:
-
-silent
サイレント出力。致命的なエラー、テストの失敗、および最小限のステータスメッセージのみを表示します - 。
-v1
詳細出力。各テスト関数が実行されたタイミングを表示します。(このオプションはプレーンテキスト出力にのみ影響します。) -v2
Extended verbose output; shows each QCOMPARE() and QVERIFY(). (This option affects all output formats and implies-v1for plain text output.)-vs
発信されるすべてのシグナルと、それらのシグナルに起因するスロットの呼び出しを表示します。(このオプションは、すべての出力形式に影響します。)
テストオプション
以下のコマンドラインオプションは、テストの実行方法に影響を与えます:
-
-functions
テストで利用可能なすべてのテスト関数を出力し、終了します。 -
-datatags
テストで利用可能なすべてのデータタグを出力します。グローバルデータタグの前には「__global__」が付きます。 -eventdelayms
If no delay is specified for keyboard or mouse simulation (QTest::keyClick(), QTest::mouseClick() etc.), the value from this parameter (in milliseconds) is substituted.-keydelayms
-eventdelay と同様ですが、キーボードのシミュレーションにのみ影響し、マウスのシミュレーションには影響しません。-mousedelayms
-eventdelay と同様ですが、マウスのシミュレーションにのみ影響し、キーボードのシミュレーションには影響しません。-
-maxwarningsnumber
出力される警告の最大数を設定します。0 は無制限、デフォルトは 2000 です。 -
-nocrashhandler
Unixプラットフォームでクラッシュハンドラーを無効にします。Windowsでは、デフォルトで無効になっている「Windowsエラー報告」ダイアログを再度有効にします。これはクラッシュのデバッグに役立ちます。 -
-repeatn
テストスイートを n 回実行するか、テストが失敗するまで実行します。不安定なテストを見つけるのに役立ちます。負の値の場合、テストは無限に繰り返されます。これは開発者向けツールとして意図されており、プレーンテキストロガーでのみサポートされています。 -
-skipblacklisted
ブラックリストに登録されたテストをスキップします。このオプションは、ブラックリストに登録されたテストによってカバレッジ統計が水増しされるのを防ぎ、テストカバレッジをより正確に測定することを目的としています。テストカバレッジを測定しない場合は、ブラックリストに登録されたテストを実行して、新たなクラッシュの発生や、ブラックリスト登録の原因となった問題が解決されたかどうかなど、結果の変化を確認することをお勧めします。 -platformname
This command line argument applies to all Qt applications, but might be especially useful in the context of auto-testing. By using the "offscreen" platform plugin (-platform offscreen) it's possible to have tests that use QWidget or QWindow run without showing anything on the screen. Currently the offscreen platform plugin is only fully supported on X11.
ベンチマークの選択肢
以下のコマンドラインオプションは、ベンチマークテストを制御します:
-callgrind
Callgrind を使用してベンチマークの所要時間を計測します(Linux および macOS)。-perf
Linuxのperfイベントを使用してベンチマークの時間を計測します。-tickcounter
CPUティックカウンタを使用してベンチマークの所要時間を計測します。ハードウェアのサポートが必要です。-eventcounter
ベンチマーク実行中に受信したイベント数をカウントします。-minimumvaluen
許容される測定値の最小値を設定します。-minimumtotaln
テスト関数の繰り返し実行における、許容される最小合計回数を設定します。-iterationsn
累積反復回数を設定します。-mediann
中央値の反復回数を設定します。-vb
詳細なベンチマーク情報を出力します。
その他のオプション
-help
使用可能なコマンドライン引数を表示し、役立つヘルプ情報を提供します。
Qt Test 環境変数
autotestの実行に影響を与えるために、特定の環境変数を設定することができます:
QTEST_DISABLE_CORE_DUMP
この変数を 0 以外の値に設定すると、コアダンプファイルの生成が無効になります。QTEST_DISABLE_STACK_DUMP
この変数を 0 以外の値に設定すると、オートテストがタイムアウトしたりクラッシュしたりした場合に、Qt Test がスタックトレースを出力しなくなります。QTEST_FATAL_FAIL
この変数を 0 以外の値に設定すると、オートテストでエラーが発生した際に、オートテスト全体が直ちに中止されます。これは、例えば、デバッガでテストを実行して、不安定なエラーや断続的に発生するエラーをデバッグする場合などに役立ちます。この変数のサポートは Qt 6.1 で追加されました。
ベンチマークの作成
ベンチマークを作成するには、テスト作成の手順に従い、ベンチマーク対象のテスト関数にQBENCHMARK マクロまたはQTest::setBenchmarkResult()を追加します。以下のコードスニペットでは、マクロが使用されています:
class MyFirstBenchmark: public QObject
{
Q_OBJECT
private slots:
void myFirstBenchmark()
{
QString string1;
QString string2;
QBENCHMARK {
string1.localeAwareCompare(string2);
}
}
};パフォーマンスを測定するテスト関数には、QBENCHMARK マクロを1つ、またはsetBenchmarkResult() の呼び出しを1つだけ含める必要があります。テスト関数1つにつき、あるいはデータ駆動型セットアップにおけるデータタグ1つにつき、報告できるパフォーマンス結果は1つだけであるため、これらを複数回記述しても意味がありません。
QBENCHMARK マクロの本体を構成する(またはそれに影響を与える)テストコード、あるいはsetBenchmarkResult() に渡される値を計算するテストコードの変更は避けてください。連続するパフォーマンス結果の差異は、理想的にはテスト対象の製品への変更のみによって引き起こされるべきです。 テストコードの変更は、パフォーマンスの変化に関する誤解を招くようなレポートにつながる可能性があります。やむを得ずテストコードを変更する必要がある場合は、コミットメッセージでその旨を明確に記述してください。
パフォーマンステスト関数では、QBENCHMARK またはsetBenchmarkResult() の後に、QCOMPARE()、QVERIFY()などを使用した検証ステップを配置する必要があります。 これにより、意図したコードパスとは異なるパスが測定された場合、そのパフォーマンステスト結果を無効としてフラグを立てることができます。パフォーマンス解析ツールはこの情報を利用して、無効な結果をフィルタリングできます。例えば、予期しないエラー状態が発生すると、通常、プログラムは正常な実行から早期に終了してしまうため、パフォーマンスが劇的に向上したかのように誤って表示されてしまうことがあります。
測定バックエンドの選択
QBENCHMARK マクロ内のコードが計測され、正確な測定結果を得るために数回繰り返される場合もあります。これは、選択された測定バックエンドによって異なります。いくつかのバックエンドが利用可能です。これらはコマンドラインで選択できます(「ベンチマークオプション」を参照):
| 名前 | コマンドライン引数 | 利用可能状況 |
|---|---|---|
| ウォールタイム | (デフォルト) | すべてのプラットフォーム |
| CPUティックカウンタ | -tickcounter | Windows、macOS、Linux、および多くのUNIX系システム。 |
| イベントカウンタ | -eventcounter | すべてのプラットフォーム |
| Valgrind Callgrind | -callgrind | Linux(インストール済みの場合) |
| Linux Perf | -perf | Linux |
要するに、walltimeは常に利用可能ですが、有用な結果を得るには多くの反復処理が必要です。ティックカウンタは通常利用可能であり、少ない反復回数で結果を得ることができますが、CPUの周波数スケーリングの問題の影響を受けやすい場合があります。Valgrindは正確な結果を提供しますが、I/O待機時間を考慮しておらず、利用可能なプラットフォームも限られています。 イベントカウントはすべてのプラットフォームで利用可能であり、対応するターゲットに送信される前にイベントループが受信したイベント数を返します(これにはQt以外のイベントが含まれる場合があります)。
LinuxパフォーマンスモニタリングソリューションはLinuxでのみ利用可能で、多くの異なるカウンタを提供します。これらは、追加オプション-perfcounter countername を指定することで選択でき、例としては-perfcounter cache-misses 、-perfcounter branch-misses 、または-perfcounter l1d-load-misses などがあります。デフォルトのカウンタはcpu-cycles です。カウンタの完全なリストは、任意のベンチマーク実行ファイルを-perfcounterlist オプションを指定して実行することで取得できます。
- パフォーマンス・カウンターを使用するには、非特権アプリケーションへのアクセスを有効にする必要がある場合があります。
- 高解像度タイマーをサポートしていないデバイスでは、デフォルトで1ミリ秒の粒度が使用されます。
ベンチマークの例については、『Qt Test チュートリアル』の「ベンチマークの作成」を参照してください。
グローバル・テスト・データの使用
initTestCase_data() を定義して、グローバルテストデータテーブルを設定できます。 各テストは、グローバルテストデータテーブルの各行に対して 1 回ずつ実行されます。テスト関数自体がデータ駆動型である場合、ローカルデータ行ごとに、またグローバルデータ行ごとに実行されます。したがって、グローバルデータテーブルにg 行あり、テスト独自のデータテーブルにd 行ある場合、このテストの実行回数はg ×d となります。
グローバルデータは、QFETCH_GLOBAL() マクロを使用してテーブルから取得されます。
以下は、グローバルテストデータの代表的な使用例です:
- QSql テストで利用可能なデータベースバックエンドの中から選択し、すべてのテストをすべてのデータベースに対して実行する。
- SSLの有無(HTTP対HTTPS)およびプロキシの有無をすべて含めたネットワークテストを実行する。
- 高精度クロックと粗いクロックの両方でタイマーをテストする。
- パーサーが `QByteArray ` から読み込むか、`QIODevice` から読み込むかを選択する。
たとえば、roundTripInt_data() で提供される各数値を、initTestCase_data() で提供される各ロケールと組み合わせてテストする場合:
void TestQLocale::roundTripInt()
{
QFETCH_GLOBAL(QLocale, locale);
QFETCH(int, number);
bool ok;
QCOMPARE(locale.toInt(locale.toString(number), &ok), number);
QVERIFY(ok);
}テストのコマンドラインでは、関数名(test-class-name という接頭辞なし)を指定することで、その関数のテストのみを実行できます。 テストクラスにグローバルデータがある場合、または関数がデータ駆動型である場合は、コロン(:)の後にデータタグを付加することで、その関数に対してそのタグのデータセットのみを実行できます。グローバルタグとテスト関数固有のタグの両方を指定するには、それらをコロンで区切って組み合わせ、グローバルデータタグを先に記述します。例えば
./testqlocale roundTripInt:zeroは、上記のroundTripInt() テストのzero テストケース(TestQLocale クラスが実行ファイルtestqlocale にコンパイルされていることを前提とする)を、initTestCase_data() で指定された各ロケールで実行します。一方、
./testqlocale roundTripInt:Cは、roundTripInt() の 3 つのテストケースすべてを C ロケールでのみ実行し、
./testqlocale roundTripInt:C:zerozero のテストケースのみをCロケールで実行します。
どのテストを実行するかをこのようにきめ細かく制御できると、失敗が確認された 1 つのテストケースのみをステップ実行すればよいため、問題のデバッグが格段に容易になります。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.