Sailfish OSの開発:Sailfish OSでのC ++依存C ++コードのテスト

こんにちは この記事は、Sailfish OSモバイルプラットフォームの開発とテストに関する一連の記事の続きです。 以前の記事の1つは、アプリケーションのQMLコンポーネントのテストに当てられていました。 ただし、開発者は多くの場合、QMLで利用できない機能を使用したり、パフォーマンスを改善したりするために、独自のコンポーネントをC ++で記述する必要に直面しています。 これも書かれています。 こうしたコンポーネントのテストは、既存のコンポーネントのテストとは異なります。 この記事では、C ++で作成された独自のQMLコンポーネントをテストする方法を示します。



テストアプリケーション



アプリケーションとして、 前回の記事で取り上げたものと同じものを取り上げましょう-カウンターアプリケーション(アプリケーションのソースコードはGitHubで入手可能です)。 現在の実装では、カウンター値はページプロパティに保存されます。 この値は、追加ボタンとリセットボタンをクリックすると変更され、ビューに表示するために使用されます。



C ++で記述されたコードを使用して値が保存および変更されるように、アプリケーションを変更します。 次のようなCounterクラスを追加します。



// counter.h #include <QObject> class Counter : public QObject { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) private: int m_count = 0; public: int count(); Q_INVOKABLE void incrementCount(); Q_INVOKABLE void resetCount(); signals: void countChanged(); };
      
      







 // counter.cpp int Counter::count() { return m_count; } void Counter::incrementCount() { m_count++; emit countChanged(); } void Counter::resetCount() { m_count = 0; emit countChanged(); }
      
      





このクラスはQObjectから継承され、本体にQ_OBJECTマクロが含まれているため、QMLにエクスポートできます。 クラスには、単一の読み取り専用プロパティcountが含まれますincrementCount()およびresetCount()メソッドは、このプロパティの値を変更するために使用されます。 メソッドはQ_INVOKABLEマクロでマークされているため、QMLから呼び出すことができます。



C ++で記述されたクラスをQMLで使用するには、クラスをQMLタイプとして登録する必要があります。 これは通常、アプリケーションのmain()関数の本体で行われます。 この場合、これはできません。 事実、 qmltestrunnerはテストの実行時にアプリケーションのメイン関数を呼び出しません。



QMLプラグイン



QMLプラグインを使用して、上記の問題を解決できます 。 アイデアは、C ++コードをライブラリに割り当て、アプリケーションとテストを開始するときに使用することです。 この場合のQMLタイプの登録は、QMLプラグインに転送されます。



プラグインを作成するには、プロジェクトを2つの部分に分割する必要があります。 各部分の下に、ディレクトリの名前に対応する名前の* .proファイルを含むサブプロジェクトでディレクトリを作成します。 最初のサブプロジェクトコアを呼び出します。これには、 main()関数を持つ* .cppファイルを除くすべてのC ++コードが含まれます。 2つ目はアプリで 、QMLファイル、 * .desktopファイル、および翻訳ファイルが含まれます。 ここでは、 main()関数を使用して* .cppファイルを配置します。



core.proファイルは次のとおりです。



 TEMPLATE = lib TARGET = core CONFIG += qt plugin c++11 QT += qml\ quick\ HEADERS += \ counter.h SOURCES += \ counter.cpp DISTFILES += qmldir uri = counter.cpp.application.Core qmldir.files = qmldir installPath = /usr/lib/counter-cpp-application/$$replace(uri, \\., /) qmldir.path = $$installPath target.path = $$installPath INSTALLS += target qmldir
      
      





core.proでは、 TEMPLATE = libを使用して、サブプロジェクトをライブラリーとして使用する必要があります。 ライブラリ( TARGET )の目的は、その名前、つまり コア CONFIGで 、ライブラリがプラグインとして接続していることを示すプラグインを追加してください。 DISTFILESでqmldirファイルへのパスを追加する必要があります。このファイルはコアディレクトリにあり、モジュールとプラグインの名前を含む必要があります。 この場合、このファイルの次の内容は次のようになります。



 module counter.cpp.application.Core plugin core
      
      





core.proファイルの最後に、ライブラリファイルとqmldirファイルへのパスを指定する必要あります。 ライブラリをディレクトリ/ usr / lib /に配置し、プラグインカウンタ/ cpp / application / Coreへのパスを指定します。



app.proファイルには、アプリケーション自体の構成が含まれています。 ターゲットアプリケーション、qmlファイルへのパス、アイコン、および翻訳がここに示されています。 ここで、main関数を使用して* .cppファイルを追加します。 この例では、ファイルの形式は次のとおりです。



 TARGET = counter-cpp-application CONFIG += sailfishapp \ sailfishapp_i18n \ c++11 SOURCES += src/counter-cpp-application.cpp OTHER_FILES += qml/counter-cpp-application.qml \ qml/cover/CoverPage.qml \ translations/*.ts \ counter-cpp-application.desktop TRANSLATIONS += translations/counter-cpp-application-de.ts SAILFISHAPP_ICONS = 86x86 108x108 128x128 256x256 DISTFILES += \ qml/CounterCppApplication.qml \ qml/pages/CounterPage.qml
      
      





ここで、作成した2つのサブプロジェクトが含まれるように* .proプロジェクトファイルを変更する必要があります。 これを行うには、 TEMPLATE = subdirsをこのファイルに追加し、ディレクトリをサブプロジェクトとして追加します。 この場合、これらのディレクトリにあるサブプロジェクトが順番に収集されます。 ここでは、プロジェクトファイルは常にメインプロジェクトのルートにある必要があるため、 rpmディレクトリからプロジェクトファイルを追加したままにする必要があります。 このアプリケーションでは、次のようになります。



 TEMPLATE = subdirs OTHER_FILES += $$files(rpm/*) SUBDIRS += \ app \ core app.depends = core
      
      





ここで、 アプリサブプロジェクトはコアに依存していることを指摘しました。



プロジェクト構造が準備できたので、プラグインの実装を開始できます。 C ++クラスを作成する必要があります。これをCorePluginと呼びます 。 クラスはQQmlExtensionPluginから継承する必要があります。 タイプを登録し、エンジンを初期化します。



QQmlExtensionPluginクラスには、オーバーライドできる2つのメソッドがあります。





ここでは、最初の方法のみで十分です。 これを使用して、 Counterクラスを登録します。 registerTypes()メソッドの本体に、次を入力します。



 qmlRegisterType<Counter>(uri, 1, 0, "Counter");
      
      





山括弧内に、登録されたクラスの名前が示されます。 最初のパラメーターはプラグインのURIです。 2番目と3番目のパラメーターは、メジャーバージョン番号とマイナーバージョン番号です。 4番目のパラメーターは、QMLのクラスを使用できる名前です。 これで、アプリケーションでタイプCounterを使用できます。



独自のQMLコンポーネントを使用する



次に、アプリケーションのメイン関数でライブラリへのパスを指定する必要があります。 これを行うには、アプリケーションとビューを手動で初期化する必要があります。 通常の場合、初期化は次のように実行されます。



 int main(int argc, char *argv[]) { return SailfishApp::main(argc, argv); }
      
      





メイン()関数コードを変更して、ライブラリパスを示します。



 int main(int argc, char *argv[]) { QGuiApplication* app = SailfishApp::application(argc, argv); QQuickView* view = SailfishApp::createView(); view->engine()->addImportPath("/usr/lib/counter-cpp-application/"); view->setSource(SailfishApp::pathTo("qml/counter-cpp-application.qml")); view->showFullScreen(); QObject::connect(view->engine(), &QQmlEngine::quit, app, &QGuiApplication::quit); return app->exec(); }
      
      





ここで、アプリケーションとビューのインスタンスを作成します。 次に、ライブラリへのパス、アプリケーションのメインQMLファイルへのパスを指定し、全画面表示を表示します。 最後に、アプリケーションの終了ハンドラーを構成して実行します。 これで、作成したライブラリをQMLファイルにインポートして、 カウンタータイプを使用できます。



前の記事のCounerPage.qmlファイルに基づいています。 次のようにプラグインを追加します。



 import counter.cpp.application.Core 1.0
      
      





以前にqmldirsファイルで指定されたURIと、タイプの登録時に指定されたバージョン1.0を使用します。 タイプを使用するには、ページ内にタイプを追加します。



 Counter { id: counter }
      
      





ここで、countプロパティの値を変更する代わりに、カウンターを追加およびリセットするときに、それぞれcounter.increment()およびcounter.reset()メソッドを呼び出します

テストコードは、視覚コンポーネントを変更しなかったため、前の記事と同じままです。



テストを実行する



テストはqmltestrunnerを使用して起動されます。 コードの一部がQMLプラグインに渡されるため、手動でパスを指定する必要があります。 これを行うには、テストを実行する前にライブラリファイルへのパスが割り当てられている変数QML2_IMPORT_PATHを使用します。 その結果、問題のアプリケーションでは、次のようになります。



 QML2_IMPORT_PATH=/usr/lib/counter-cpp-application/ /usr/lib/qt5/bin/qmltestrunner -input /usr/share/counter-cpp-application/tests/
      
      





テストコードと結果の出力は、 前の記事と同じままです。



 ********* Start testing of qmltestrunner ********* Config: Using QtTest library 5.2.2, Qt 5.2.2 PASS : qmltestrunner::Counter tests::initTestCase() PASS : qmltestrunner::Counter tests::test_counterAdd() PASS : qmltestrunner::Counter tests::test_counterReset() PASS : qmltestrunner::Counter tests::cleanupTestCase() Totals: 4 passed, 0 failed, 0 skipped ********* Finished testing of qmltestrunner *********
      
      





おわりに



独自のQMLコンポーネントのテストは、QtQuickライブラリで既に利用可能なテストとは異なります。 それらをテストする可能性を実現するには、QMLプラグイン内のすべてのC ++コードを選択し、ライブラリとして接続する必要がありました。 その結果、テストコードは標準のQMLコンポーネントをテストするコードと変わりません。 それにもかかわらず、プロジェクト自体に大きな変更が必要でした。 この形式のアプリケーションは、ストアで公開するときにすでに使用できます。 この例のソースコードはGitHubで入手できます



技術的な問題は、ロシア語を話すコミュニティのSailfish OSのTelegramまたはVKontakteグループチャネルでも議論できます。



著者:セルゲイ・アヴェルキエフ



All Articles