このページの内容

第2章:データ駆動型テスト

この章では、異なるテストデータを使用してテストを複数回実行する方法を説明します。

これまで、テストしたいデータをテスト関数内にハードコーディングしてきました。テストデータをさらに追加すると、関数は次のような形になるでしょう:

QCOMPARE(QString("hello").toUpper(), QString("HELLO"));
QCOMPARE(QString("Hello").toUpper(), QString("HELLO"));
QCOMPARE(QString("HellO").toUpper(), QString("HELLO"));
QCOMPARE(QString("HELLO").toUpper(), QString("HELLO"));

関数が繰り返しのコードで煩雑になるのを防ぐため、Qt Test ではテスト関数へのテストデータの追加をサポートしています。必要なのは、テストクラスに別のプライベートスロットを追加することだけです:

class TestQString: public QObject
{
    Q_OBJECT

private slots:
    void toUpper_data();
    void toUpper();
};

データ関数の記述

テスト関数に関連付けられたデータ関数には、名前の末尾に「_data 」が付加されます。データ関数は次のようになります:

void TestQString::toUpper_data()
{
    QTest::addColumn<QString>("string");
    QTest::addColumn<QString>("result");

    QTest::newRow("all-lower") << "hello" << "HELLO";
    QTest::newRow("mixed")     << "Hello" << "HELLO";
    QTest::newRow("all-upper") << "HELLO" << "HELLO";
}

まず、QTest::addColumn() 関数を使用して、テストテーブルの 2 つの要素を定義します。テスト用文字列と、その文字列にQString::toUpper() 関数を適用した際の期待される結果です。

次に、QTest::newRow() 関数を使用して、テーブルにデータを追加します。行名内のデータをフォーマットする必要がある場合(たとえば、反復処理で多数のデータ行を生成する場合など)は、QTest::addRow() 関数を使用することもできます。各データ行は、テストテーブル内の個別の行となります。

QTest::newRow() は 1 つの引数を受け取ります。これはデータセットに関連付けられ、テストログ内でデータ行を識別するために使用される名前です。QTest::addRow() は、(printf 形式の)フォーマット文字列を受け取り、その後に、フォーマット文字列内のフォーマットトークンの代わりに表されるパラメータが続きます。その後、データセットを新しいテーブル行にストリーム処理します。 まず任意の文字列を指定し、その文字列にQString::toUpper()関数を適用した際の期待される結果を指定します。

このテストデータは、2次元のテーブルとして考えることができます。この例では、「string 」と「result 」という2つの列と、3つの行があります。さらに、各行には名前とインデックスが関連付けられています:

indexname文字列result
0すべて小文字"hello"HELLO
1混合"Hello"HELLO
2すべて大文字「HELLO」HELLO

データが行にストリームで入力される際、各データ項目は、それが値を供給する列の型と一致することがアサーションされます。いずれかのアサーションが失敗した場合、テストは中止されます。

特定のテスト関数のデータテーブル内では、行名および列名は一意である必要があります。2つの行または2つの列が同じ名前を共有している場合、(Qt Test 6.5以降)警告が出力されます。 警告をエラーとして扱う方法についてはqWarning() を、テストからその他の警告を排除する方法については「警告のテスト」を参照してください。

テスト関数の書き換え

これで、テスト関数を次のように書き換えることができます。

void TestQString::toUpper()
{
    QFETCH(QString, string);
    QFETCH(QString, result);

    QCOMPARE(string.toUpper(), result);
}

TestQString::toUpper() 関数は 3 回実行されます。これは、関連する TestQString::toUpper_data() 関数で作成したテストテーブルのエントリごとに 1 回ずつ実行されるためです。

まず、QFETCH() マクロを使用して、データセットの2つの要素を取得します。QFETCH() は、要素のデータ型と要素名の2つの引数を取ります。次に、QCOMPARE() マクロを使用してテストを実行します。

このアプローチにより、テスト自体を変更することなく、新しいデータをテストに追加することが非常に容易になります。

スタンドアロンの実行可能ファイルの準備

また、テストケースをスタンドアロンの実行可能ファイルにするには、次の2行が必要です:

QTEST_MAIN(TestQString)
#include "testqstring.moc"

前述と同様に、QTEST_MAIN() マクロは、すべてのテスト関数を実行する単純な main() メソッドに展開されます。また、テストクラスの宣言と実装の両方が .cpp ファイル内にあるため、Qt のイントロスペクションが機能するように、生成された moc ファイルもインクルードする必要があります。

実行ファイルのビルド

CMake または qmake を使用して、テストケースの実行可能ファイルをビルドできます。

CMake を使用したビルド

CMakeLists.txt ファイルでビルド設定を構成します:

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

cmake_minimum_required(VERSION 3.16)
project(tutorial2 LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Test Widgets)

qt_standard_project_setup()

qt_add_executable(tutorial2
    testqstring.cpp
)

set_target_properties(tutorial2 PROPERTIES
    WIN32_EXECUTABLE TRUE
    MACOSX_BUNDLE TRUE
)

target_link_libraries(tutorial2 PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::Test
    Qt6::Widgets
)

install(TARGETS tutorial2
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_app_script(
    TARGET tutorial2
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

次に、コマンドラインから `cmake ` を実行するか、Qt-prefix/<version>/<platform>/bin/qt-cmake にある `qt-cmake ` という便利スクリプトを使用します:

<Qt-prefix>/<version>/<platform>/bin/qt-cmake <source-dir> <build-dir> -G Ninja

その後、お好みのジェネレータツールを実行して実行ファイルをビルドします。ここではNinjaを使用しています:

ninja

qmake を使用したビルド

.pro ファイルでビルド設定を構成します:

QT += widgets testlib

SOURCES = testqstring.cpp

# install
target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial2
INSTALLS += target

次に、qmake を実行し、最後にmake を実行して実行ファイルをビルドします:

qmake
make

実行ファイルの実行

ビルドされた実行ファイルを実行すると、次のような出力が表示されるはずです:

********* Start testing of TestQString *********
Config: Using QtTest library %VERSION%, Qt %VERSION%
PASS   : TestQString::initTestCase()
PASS   : TestQString::toUpper(all-lower)
PASS   : TestQString::toUpper(mixed)
PASS   : TestQString::toUpper(all-upper)
PASS   : TestQString::cleanupTestCase()
Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of TestQString *********

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