Posted at

Qtでgoogletestを使うときのテンプレート

More than 1 year has passed since last update.


はじめに

Qt Creatorでgoogletestを使えるようになりました(詳しくはQt Creator Autotest Plugin について

でも、実際に使ってみようとすると、どういうプロジェクト構成にすると、プロダクトコードとテストコードをうまく管理できるかわかりませんでした。

そこで、自分なりのテンプレートを作ってみることにしました。

もっといい方法をご存知の方は、ぜひ突っ込みをお願いします。


手順


  1. subdirsテンプレートで新規アプリケーションを作成

  2. プロダクトコードをサブプロジェクトとして取り込む

  3. プロダクトコードの.proファイルから、ソースファイルとヘッダファイルの指定を.priファイルに移す

  4. Auto Test Projectをサブプロジェクトとして作成

  5. テスト用サブプロジェクトからプロダクトコードを参照

  6. テストを書く


subdirsテンプレートで新規アプリケーションを作成

Qt Creatorでsubdirsプロジェクトを新規に作成します。

プロダクトコードのプロジェクト名と同名にならないようにだけ、気を付けます。

今回は、simplebrowser-gtestとしました。

この時点でのディレクトリ構造は、次の通りです。

simplebrowser-gtest/

└── simplebrowser-gtest.pro

simplebroser-gtest.proの中身は、次の1行だけです。

TEMPLATE = subdirs


プロダクトコードをサブプロジェクトとして取り込む

今回は、QtのExampleに含まれる、WebEngineWidgetsのsimplebrowserプロジェクトを取り込みます。

Qt Creatorでのやり方がよくわからないため、手動で行いました。

simplebrowserディレクトリを、simplebrowser-gtest配下に、がさっとコピーします。

simplebrowser-gtest/

├── simplebrowser

│   ├── browser.cpp

│   ├── browser.h

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

一部省略

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

│   ├── simplebrowser.pro

│   ├── webpopupwindow.cpp

│   ├── webpopupwindow.h

│   ├── webview.cpp

│   └── webview.h

└── simplebrowser-gtest.pro

simplebrowser-gtest.proに次の1行を追加します。

SUBDIRS = simplebrowser

これで、simplebrowserプロジェクトが、simplebroser-gtestに取り込まれます。

試しにQt CreatorのRunボタンを押すと、simplebrowserが立ち上がります。


プロダクトコードの.proファイルから、ソースファイルとヘッダファイルの指定を.priファイルに移す

simplebrowser.proは次のようになっています。

googletestでmain.cpp以外に対して、ユニットテストを書きたいです。

TEMPLATE = app

TARGET = simplebrowser
QT += webenginewidgets
CONFIG += c++11

HEADERS += \
browser.h \
browserwindow.h \
downloadmanagerwidget.h \
downloadwidget.h \
tabwidget.h \
webpage.h \
webpopupwindow.h \
webview.h

SOURCES += \
browser.cpp \
browserwindow.cpp \
downloadmanagerwidget.cpp \
downloadwidget.cpp \
main.cpp \
tabwidget.cpp \
webpage.cpp \
webpopupwindow.cpp \
webview.cpp

FORMS += \
certificateerrordialog.ui \
passworddialog.ui \
downloadmanagerwidget.ui \
downloadwidget.ui

RESOURCES += data/simplebrowser.qrc

そこで、テスト用のサブプロジェクトとソースコードを共有できるように、ソースとヘッダファイルの指定を、proファイルからpriファイルに移します。

simplebrowser.priを次の通り作成します。テスト用のサブプロジェクトから参照できるように、インクルードパスを追加し、ソースとヘッダファイルもディレクトリパスから記載します。

main.cppは、priに書かないようにします。

SRC_DIR = $$PWD

HEAD_DIR = $$PWD
FORM_DIR = $$PWD

INCLUDEPATH *= \
$$HEAD_DIR

HEADERS += \
$$HEAD_DIR/browser.h \
$$HEAD_DIR/browserwindow.h \
$$HEAD_DIR/downloadmanagerwidget.h \
$$HEAD_DIR/downloadwidget.h \
$$HEAD_DIR/tabwidget.h \
$$HEAD_DIR/webpage.h \
$$HEAD_DIR/webpopupwindow.h \
$$HEAD_DIR/webview.h

SOURCES += \
$$SRC_DIR/browser.cpp \
$$SRC_DIR/browserwindow.cpp \
$$SRC_DIR/downloadmanagerwidget.cpp \
$$SRC_DIR/downloadwidget.cpp \
$$SRC_DIR/tabwidget.cpp \
$$SRC_DIR/webpage.cpp \
$$SRC_DIR/webpopupwindow.cpp \
$$SRC_DIR/webview.cpp

FORMS += \
$$FORM_DIR/certificateerrordialog.ui \
$$FORM_DIR/passworddialog.ui \
$$FORM_DIR/downloadmanagerwidget.ui \
$$FORM_DIR/downloadwidget.ui

RESOURCES += $$SRC_DIR/data/simplebrowser.qrc

simplebrowser.proから、ソースとヘッダファイルの指定を取り除き、次の1行を追加して、priファイルをインクルードします。

include(simplebrowser.pri)

最終的に、simplebrowser.proは次のようになりました。(ずいぶんすっきりです)

TEMPLATE = app

TARGET = simplebrowser
QT += webenginewidgets
CONFIG += c++11
include(simplebrowser.pri)

SOURCES += \
main.cpp


Auto Test Projectをサブプロジェクトとして作成

simplebrowser-gtest配下に、Auto Test Projectをサブプロジェクトとして作成します。

今回は、simplebrowser-unittestというプロジェクト名を付けました。

Test Frameworkにはgoogletestを選択します。

あらかじめ、googletestのレポジトリをどこかにcloneしておく必要があります。

最後のSummary画面で、Auto Test Projectが、ちゃんとターゲットのサブプロジェクトになっていることを確認します。

Add as a subproject to project: simplebrowser-gtest


テスト用サブプロジェクトからプロダクトコードを参照

先ほど作成したプロジェクトの、simplebrowser-unittest.proは、以下のようになります。

include(gtest_dependency.pri)

TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG += thread
CONFIG -= qt

HEADERS += tst_webviewtest.h

SOURCES += main.cpp

以下の1行を追加して、テストしたいターゲットのソースとヘッダを参照します。

include(../simplebrowser/simplebrowser.pri)


テストを書く

テストを書きます。

力尽きてしまったので、以下のコードはとりあえず、プロダクトコードを参照して、googletestのフレームワークが動く、程度のものです。

Qt CreatorのTools->Tests->Run All Tests、で無事テストが動作し、テストがパスしました。

Qt CreatorのRunボタンを押すと、変わらず、simplebrowserが起動します。

#include <gtest/gtest.h>

#include <gmock/gmock-matchers.h>
#include "browser.h"
#include "browserwindow.h"
#include "webview.h"
#include <QApplication>

using namespace testing;

TEST(WebViewTest, Test1)
{
int argc;
char **argv;
QApplication app(argc, argv);

QUrl expected = QStringLiteral("https://www.qt.io");
Browser browser;
BrowserWindow *window = browser.createWindow();
window->currentTab()->setUrl(expected);

QUrl actual = window->currentTab()->url();

EXPECT_EQ(expected, actual);
}

テストを書く上で、simplebrowser-unittest.proを以下の通り修正しないとダメでした。

追加:

QT += webenginewidgets

削除:

CONFIG -= qt

このあたりは、プロダクトコードのpriファイルに書いておくほうがよさそうですね。

コードはこちら

https://github.com/tomoyuki-nakabayashi/qt-googletest-template