はじめに
Qt Creatorでgoogletestを使えるようになりました(詳しくはQt Creator Autotest Plugin について。
でも、実際に使ってみようとすると、どういうプロジェクト構成にすると、プロダクトコードとテストコードをうまく管理できるかわかりませんでした。
そこで、自分なりのテンプレートを作ってみることにしました。
もっといい方法をご存知の方は、ぜひ突っ込みをお願いします。
手順
- subdirsテンプレートで新規アプリケーションを作成
- プロダクトコードをサブプロジェクトとして取り込む
- プロダクトコードの.proファイルから、ソースファイルとヘッダファイルの指定を.priファイルに移す
- Auto Test Projectをサブプロジェクトとして作成
- テスト用サブプロジェクトからプロダクトコードを参照
- テストを書く
subdirsテンプレートで新規アプリケーションを作成
Qt Creatorでsubdirsプロジェクトを新規に作成します。
プロダクトコードのプロジェクト名と同名にならないようにだけ、気を付けます。
今回は、simplebrowser-gtestとしました。
この時点でのディレクトリ構造は、次の通りです。
└── simplebrowser-gtest.pro
simplebroser-gtest.proの中身は、次の1行だけです。
プロダクトコードをサブプロジェクトとして取り込む
今回は、QtのExampleに含まれる、WebEngineWidgetsのsimplebrowserプロジェクトを取り込みます。
Qt Creatorでのやり方がよくわからないため、手動で行いました。
simplebrowserディレクトリを、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