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 テストを含むプロジェクトを作成し、Qt Creator から直接ビルドして実行することができます。詳細については、Qt Creator: テストのビルドと実行 を参照してください。

テストの作成

テストを作成するには、QObject をサブクラス化し、1つ以上のプライベート・スロットを追加します。各プライベートスロットは、テスト内のテスト関数です。QTest::qExec() を使うと、テストオブジェクト内のすべてのテスト関数を実行することができます。

さらに、テスト関数として扱われない以下のプライベートスロットを定義することができます。これらのスロットが存在すると、テストフレームワークによって実行され、 テスト全体あるいは現在のテスト関数を初期化したりクリーンアップしたりするために使われます。

  • initTestCase() は、最初のテスト関数が実行される前に呼び出されます。
  • initTestCase_data() グローバルテストデータテーブルを作成するために呼び出されます。
  • cleanupTestCase() 最後のテスト関数が実行された後に呼び出されます。
  • init() 各試験関数が実行される前にコールされます。
  • cleanup() 各テスト関数の実行後に呼び出されます。

テストの準備にはinitTestCase() を使用する。すべてのテストは、繰り返し実行できるように、システムを使用可能な状態にする必要があります。クリーンアップ処理はcleanupTestCase() で処理する。

テスト関数の準備にはinit() を使用する。すべてのテスト関数は、繰り返し実行できるように、システムを使用可能な状態にしておく必要があります。クリーンアップ操作はcleanup() で処理する必要があり、テスト関数が失敗して早期に終了しても実行されます。

別の方法として、RAII(リソース取得は初期化)を使って、デストラクタでクリーンアップ操作を呼び出すようにすると、テスト関数が戻ってオブジェクトがスコープ外に移動したときに、クリーンアップ操作が実行されるようになります。

initTestCase() が失敗した場合、テスト関数は実行されません。init() が失敗した場合、次のテスト関数は実行されず、テストは次のテスト関数に進みます。

classMyFirstTest:publicQObject
{ Q_OBJECTprivate: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.");
    } };

最後に、テスト・クラスに静的な publicvoid initMain() メソッドがある場合、QApplication オブジェクトがインスタンス化される前に、QTEST_MAIN マクロによって呼び出されます。これは5.14で追加された。

詳しい例については、Qt Test チュートリアルを参照してください。

テスト関数のタイムアウトを増やす

QtTest 無限ループや類似のバグを検出するために、各テストの実行時間を制限します。デフォルトでは、テスト関数の呼び出しは 5 分後に中断されます。データ駆動型テストの場合、これは個別の data タグを持つ各呼び出しに適用されます。このタイムアウトは、 環境変数に、1回の呼び出しで許容できる最大ミリ秒数を設定することで設定できます。テストが設定されたタイムアウトより長くかかった場合、テストは中断され、 が呼び出される。その結果、テストはクラッシュしたかのようにデフォルトで中止される。QTEST_FUNCTION_TIMEOUT qFatal()

LinuxまたはmacOSのコマンドラインからQTEST_FUNCTION_TIMEOUT を設定するには、次のように入力する:

QTEST_FUNCTION_TIMEOUT=900000
export QTEST_FUNCTION_TIMEOUT

Windowsの場合:

SET QTEST_FUNCTION_TIMEOUT=900000

この環境でテストを実行する。

あるいは、テスト・クラスのinitMain()メソッドから呼び出すなどして、テスト・コード自体にプログラム的に環境変数を設定することもできます:

qputenv("QTEST_FUNCTION_TIMEOUT", "900000");

タイムアウトの適切な値を計算するには、テストに通常どれくらいの時間がかかるかを確認し、 問題の兆候なしにどれくらいの時間がかかるかを判断します。その長い時間をミリ秒に変換して、タイムアウトの値を求めます。例えば、遅いマシンなどで、数分かかるテストに20分かかると判断した場合、20 * 60 * 1000 = 1200000 を掛け、環境変数に900000 の代わりに1200000 を設定します。

テストの構築

通常、プロダクションコードの1クラスをテストするテストクラスを含む実行ファイルをビルドすることができます。しかし、通常は1つのコマンドを実行することで、プロジェクト内の複数のクラスをテストしたいと思うでしょう。

単体テストの書き方を参照ください。

CMake と CTest によるビルド

Build with CMake と CTestを使ってテストを作成することができます。CTestでは、テスト名とマッチする正規表現に基づいてテストを含めたり除外したりすることができます。さらにLABELS プロパティをテストに適用すると、CTest はそれらのラベルに基づいてテストを含めたり除外したりできます。test target がコマンドラインで呼び出されると、ラベル付けされたすべてのターゲットが実行されます。

注: Androidでは、接続されているデバイスまたはエミュレータが1つの場合、テストはそのデバイス上で実行されます。複数のデバイスが接続されている場合は、環境変数ANDROID_DEVICE_SERIAL にテストを実行したいデバイスのADB シリアル番号を設定してください。

CMakeには他にもいくつかの利点がある。例えば、テスト実行の結果は、CDashを使ってウェブサーバーに公開することができます。

CTest は、さまざまなユニットテストフレームワークに対応し、QTest ですぐに動作します。

以下は、プロジェクト名と使用言語(ここではmytestと C++)、テストのビルドに必要な Qt モジュール(Qt5Test)、テストに含まれるファイル(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 += testlib

make check を使ってテストを実行したい場合は、次の行を追加する:

CONFIG += testcase

テストがターゲットにインストールされないようにするには、次の行を追加する:

CONFIG += no_testcase_installs

make check の詳細については、qmakeのマニュアルを参照してください。

他のツールでのビルド

他のビルドツールを使用している場合は、Qt Test のヘッダファイルの場所をインクルードパスに追加してください(通常は Qt のインストールディレクトリの下にあるinclude/QtTest です)。Qt のリリースビルドを使用している場合は、テストをQtTest ライブラリにリンクしてください。デバッグビルドの場合は、QtTest_debug を使用してください。

Qt Test コマンドライン引数

構文

自動テストを実行するための構文は、以下のような単純な形式をとる:

testname [options] [testfunctions[:testdata]]...

testname に実行ファイル名を代入する。testfunctions には、実行するテスト関数の名前を含めることができる。testfunctions が渡されなければ、すべてのテストが実行される。testdata のエントリ名を追加すると、テスト関数はそのテストデータでのみ実行されます。

例えば

/myTestDirectory$ testQString toUpper

toUpper というテスト関数を、利用可能なすべてのテストデータで実行します。

/myTestDirectory$ testQString toUpper toInt:zero

利用可能なすべてのテスト・データを使用してtoUpper テスト関数を実行し、zero というテスト・データ行を使用してtoInt テスト関数を実行します(指定されたテスト・データが存在しない場合、関連するテストは失敗し、利用可能なデータ・タグが報告されます)。

/myTestDirectory$ testMyWidget -vs -eventdelay 500

testMyWidget 関数テストを実行し、すべての信号放出を出力し、各シミュレートされたマウス/キーボード イベント後 500 ミリ秒待機する。

オプション

ロギングオプション

以下のコマンドラインオプションは、テスト結果の報告方法を決定します:

  • -o filename,format
    Writes output to the specified file, in the specified format (one of txt, csv, junitxml, xml, lightxml, teamcity or tap). Use the special filename - (hyphen) to log to standard output.
  • -o filename
    指定したファイルに出力を書き込みます。
  • -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 -v1 for plain text output.)
  • -vs
    発行されたすべてのシグナルと、それらのシグナルに起因するスロットの起動を表示します。(このオプションはすべての出力フォーマットに影響します。)

テストオプション

以下のコマンドラインオプションは、テストの実行方法に影響します:

  • -functions
  • -datatags
    テストで使用可能なすべてのデータタグを出力します。グローバル・データ・タグの前には ' __global__ ' が付きます。
  • -eventdelay ms
    If no delay is specified for keyboard or mouse simulation (QTest::keyClick(), QTest::mouseClick() etc.), the value from this parameter (in milliseconds) is substituted.
  • -keydelay ms
    -eventdelayと似ていますが、キーボードシミュレーションにのみ影響し、マウスシミュレーションには影響しません。
  • -mousedelay ms
    -eventdelayと似ていますが、マウスシミュレーションにのみ影響し、キーボードシミュレーションには影響しません。
  • -maxwarnings number
    出力する警告の最大数を設定します。0 で無制限、デフォルトは 2000 です。
  • -nocrashhandler
    Unix プラットフォームではクラッシュハンドラを無効にします。Windowsでは、デフォルトではオフになっているWindowsエラー報告ダイアログを再度有効にします。
  • -repeat n
    テストスイートを n 回、あるいはテストが失敗するまで実行します。不安定なテストを見つけるのに便利。否定された場合、テストは永遠に繰り返される。
  • -skipblacklisted
    ブラックリストに載ったテストをスキップする。このオプションは、ブラックリストに登録されたテストがカバレッジの統計値を膨らませるのを防いで、 テストカバレッジをより正確に計測できるようにするためのものです。テストカバレッジを測定していないときは、ブラックリストに載せたテストを実行して、新しいクラッシュが発生したとか、 ブラックリストに載せる原因となった問題が解決されたとか、テスト結果の変化を明らかにすることを推奨します。
  • -platform 名前
    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 のみ)。
  • -tickcounter
    CPUティックカウンタを使用してベンチマークを計時する。
  • -eventcounter
    ベンチマーク中に受信したイベントをカウントする。
  • -minimumvalue n
    許容可能な測定値の最小値を設定します。
  • -minimumtotal n
    テスト関数の繰り返し実行の最小許容合計を設定します。
  • -iterations n
    累積反復回数を設定します。
  • -median n
    中央値の反復回数を設定します。
  • -vb
    ベンチマーク情報を冗長に出力します。

その他のオプション

  • -help
    可能なコマンドライン引数を出力し、便利なヘルプを表示します。

Qt Test 環境変数

自動テストの実行に影響を与えるために、特定の環境変数を設定することができる:

  • QTEST_DISABLE_CORE_DUMP
  • QTEST_DISABLE_STACK_DUMP
    この変数を 0 以外の値に設定すると、自動テストがタイムアウトしたりクラッシュした場合に、Qt Test がスタックトレースを表示しないようにします。
  • QTEST_FATAL_FAIL
    この変数を 0 以外の値に設定すると、自動テストに失敗した場合に、自動テスト全体を直ちに中止します。これは、デバッガでテストを起動して、テストの不安定な失敗や断続的な失敗をデバッグするときなどに便利です。この変数のサポートは Qt 6.1 で追加されました。
  • QTEST_THROW_ON_FAIL (6.8 以降)
    Setting this variable to a non-zero value will cause QCOMPARE()/QVERIFY() etc to throw on failure (as opposed to just returning from the immediately-surrounding function scope).
  • QTEST_THROW_ON_SKIP (6.8 以降)
    Same as QTEST_THROW_ON_FAIL, except affecting QSKIP().

ベンチマークの作成

ベンチマークを作成するには、テストの作成手順に従って、ベンチマークを作成したいテスト関数に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 つのパフォーマンス結果しか報告できないからです。

QBENCHMARK マクロのボディを形成する(あるいは影響を与える)テストコード、あるいはsetBenchmarkResult() に渡される値を計算するテストコードの変更は避けてください。連続した性能結果の相違は、理想的には、テスト対象製品の変更によってのみ発生するはずです。テストコードを変更すると、性能の変化について誤解を招くような報告がなされる可能性があります。テストコードを変更する必要がある場合は、コミットメッセージにその旨を明記してください。

性能テスト関数では、QBENCHMARK またはsetBenchmarkResult() の後に、QCOMPARE()、QVERIFY() などの検証ステップを記述します。そして、意図したコードパスとは別のコードパスが測定された場合、性能結果が無効であるとフラグを立てることができます。性能解析ツールはこの情報を使って、無効な結果をフィルタリングすることができます。例えば、予期しないエラー状態が発生すると、通常、プログラムは正常なプログラム実行から早々にベイルアウトするため、性能の劇的な向上を偽って示すことになります。

測定バックエンドの選択

QBENCHMARK マクロ内のコードは測定され、正確な測定を行うために数回繰り返されることもあります。これは、選択した測定バックエンドに依存します。いくつかのバックエンドが利用可能です。コマンドラインで選択できます:

名前コマンドライン引数可用性
壁時間(デフォルト)すべてのプラットフォーム
CPUティックカウンター-ティックカウンターWindows、macOS、Linux、多くのUNIX系システム。
イベント・カウンター-イベント・カウンターすべてのプラットフォーム
コールグラインド-コールグラインドLinux(インストールされている場合)
Linux Perf-perfLinux

要するに、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 チュートリアルのWriting a Benchmarkを参照してください。

グローバルテストデータの使用

initTestCase_data() を定義して、グローバルテストデータテーブルを設定することができます。各テストは、グローバルテストデータテーブルの各行に対して1回ずつ実行されます。テスト関数自体がデータ駆動型である場合は、ローカル・データ行ごとに、グローバル・データ行ごとに実行されます。したがって、グローバル・データ・テーブルにg 行があり、テスト自身のデータ・テーブルにd 行がある場合、このテストの実行回数はgd となります。

グローバル・データは、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 という接頭辞はつけない)を渡すと、その関数のテストだけを実行することができます。テストクラスがグローバルデータを持っている場合、あるいは関数がデータ駆動型である場合は、コロンの後に data タグを追加して、そのタグのデータセットだけを関数に対して実行させることができます。グローバルなタグとテスト関数固有のタグの両方を指定するには、グローバルなデータタグを最初にして、間にコロンを挟みます。例

./testqlocale roundTripInt:zero

initTestCase_data() で指定されたロケールのそれぞれで、上記のroundTripInt() テスト(そのTestQLocale クラスが実行可能なtestqlocale にコンパイルされていると仮定)のzero テストケースを実行します。

./testqlocale roundTripInt:C

は、roundTripInt() の3つのテストケースすべてをCロケールでのみ実行します。

./testqlocale roundTripInt:C:zero

zero のテストケースのみをCロケールで実行します。

どのテストを実行するかをこのように細かく制御することで、問題のデバッグが非常に簡単になります。

© 2025 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.