web-dev-qa-db-ja.com

autotoolsを介してビルドするプロジェクトでGoogle Testを使用するにはどうすればよいですか?

ある種の、ある種の理にかなっている回答がいくつかあるようですが、実行する方法がわかりません。そして、私は包括的な答えを見つけていません。

最初の問題

Google Testはインストールされたライブラリではなく、プロジェクトでビルドする必要があります。 ( [〜#〜] faq [〜#〜] を参照してください。)私の知る限り、これはGoogleテストライブラリがユニットテストの依存関係であり、プロジェクト内で初めて「make check」を実行します。これにより、Google Testライブラリがいくつかのディレクトリに構築されます。これを行う方法がわかりません。それは廃止予定のautotoolsスクリプトについて言及しており、彼らが何を言っているのか、または私のビルドを適切に指す方法がわかりません。

第二の問題

ビルドが成功した場合、ローカルでコンパイルしたバージョンのGoogle Testを使用してテストを実行するテストを作成するにはどうすればよいですか。テストディレクトリにMakefile.amコマンドがたくさんあると思います。しかし、それらは何ですか?そして、Google Testを使用した単体テストの例は何ですか?

20
Joel

満足のいくように問題を解決しました!今から完全に進みます。これは基本的にチュートリアルを求めています。 Google Testがautotoolsにうまく適合できるように、できれば論理的に行う必要がある多くの決定があります。長い回答をお詫びしますが、すべての詳細がそこにあるはずです。

最初の問題

答えを理解するには、質問を少し言い換える必要があります。テストコードをリンクするライブラリとしてGoogleテストをコンパイルしています。ライブラリはインストールされません。私たちが聞きたい質問は

「テストコードをリンクできるライブラリとしてGoogleテストをコンパイルするようにautotoolsをどのように構成しますか?」

そのためには、Google Testをダウンロードしてプロジェクトに配置する必要があります。私はGithubを使用しているので、プロジェクトのルートパスにサブモジュールを追加することでこれを行います。

$ git submodule add [email protected]:google/googletest.git
$ git submodule init
$ git submodule update

これは私のプロジェクトの私のルートにgoogletestをダウンロードします:

/:
    Makefile.am
    configure.ac
    src/:
        (files for my project)
    tests/:
        (test files)
    googletest/:
        googletest/:
            include/:
                (headers, etc., to be included)
                gtest/:
                    gtest.h
            m4/:
                (directory for m4 scripts and things)
            src/:
                (source files for Google Test)

手順 に従ってコンパイルする必要があります。 make checkの実行時にGoogleテストライブラリをビルドするだけなので、check_LTLIBRARIESを使用します。/testsのテストMakefile.amに以下を追加します。

check_LTLIBRARIES = libgtest.la
libgtest_la_SOURCES = ../googletest/googletest/src/gtest-all.cc
libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest
libgtest_la_LDFLAGS = -pthread

これには、configure.acでsubdir-objectsを有効にする必要があります。これは、AM_INIT_AUTOMAKE行に追加することによって行われます。 AC_CONFIG_FILESにメイクファイルを含める必要もあります。ライブラリファイルをコンパイルしているため、libtoolも使用したいと思います(その理由と方法については後で説明します)。 libtoolを使用するには、AM_PROG_AR、LT_INITを追加します。 autoreconfでm4マクロを/ m4にインストールしてから、automakeでそれらを見つけたいので、AC_CONFIG_MACRO_DIRSが必要です。私のconfigure.acは更新された行を持っています:

AM_INIT_AUTOMAKE([-Wall -Werror subdir-objects])
...
AM_PROG_AR
LT_INIT
AC_CONFIG_MACRO_DIRS([m4])
...
AC_CONFIG_FILES([Makefile
                 src/Makefile
                 tests/Makefile
                 ])

/Makefile.amの/ m4マクロディレクトリにあるサブディレクトリとマクロを指す行も含める必要があります。

ACLOCAL_AMFLAGS = -I m4

SUBDIRS = src tests

これは何をしましたか?LibtoolはAM_PROG_ARとLT_INITで有効になっています。 check_LTLIBRARIESは、libtoolを使用してlibgtest.laという便利なライブラリを作成することを意味します。 subdir-objectsを有効にすると、/ testsディレクトリにビルドされますが、インストールされません。つまり、テストを更新するときはいつでも、Googleテストライブラリlibgtest.laを再コンパイルする必要はありません。これは、テスト時の時間を節約し、より速く反復するのに役立ちます。次に、ユニットテストを更新するときに、後でそれに対してコンパイルする必要があります。ライブラリはmake checkの実行時にのみコンパイルされ、makeまたはmake installのみを実行する場合はコンパイルしないことで時間を節約できます。

第二の問題

次に、2番目の問題を改善する必要があります。(a)Googleテストライブラリにリンクされているテスト(b)をどのように作成し、それを使用しますか?質問は互いに絡み合っているので、すぐに回答します。

テストを作成するには、次のコードをgtest.cppにある/tests/gtest.cppファイルに挿入するだけです。

#include "gtest/gtest.h" // we will add the path to C preprocessor later

TEST(CategoryTest, SpecificTest)
{
    ASSERT_EQ(0, 0);
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}

これは単純なテスト0 = 0のみを実行します。ライブラリのテストを作成するには、 primer を読み取る必要があります。これには(まだ)ヘッダーは必要ありません。 「gtest/gtest.h」ファイルにリンクしているので、gtest/gtest.hが含まれるディレクトリを含めるようにautomakeに指示する必要があります。

次に、テストをビルドして実行することをautomakeに通知する必要があります。テストは、インストールしたくない実行可能ファイルに組み込まれます。次に、automakeがその実行可能ファイルを実行します。その実行可能ファイルがテストの成功または失敗を示しているかどうかを報告します。

Automakeはmakefileで変数check_PROGRAMSを探してそれを行います。これらはコンパイルするプログラムですが、必ずしも実行されるとは限りません。したがって、/tests/Makefile.amに追加します。

check_PROGRAMS = gtest

gtest_SOURCES = gtest.cpp

gtest_LDADD = libgtest.la

gtest_LDFLAGS = -pthread

gtest_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -pthread

Gtest_SOURCESは/tests/gtest.cppファイルを見つけてコンパイルします。 gtest_LDADDは、/ testsディレクトリにコンパイルされるlibgtest.laにリンクします。 Googleは、ptestを有効にするためにgtest_LDFLAGS行を使用することを望んでいます。最後に、ヘッダー「gtest/gtest.h」が見つかる場所を含める必要があります。これは、gtest_CPPFLAGS行です。 Googleは、/googletest/googletestの場所も含めて、

状態:Google Testライブラリlibgtest.lamakeを使用して/ testsディレクトリにコンパイルされますが、インストールされています。バイナリgtestはmake checkでのみコンパイルされますが、インストールされません。

次に、コンパイルされたバイナリgtestを実際に実行してエラーを報告するようにautomakeに指示します。これを行うには、/tests/Makefile.amに行を追加します。

TESTS = gtest

最終的な/tests/Makefile.amは次のようになります。

check_LTLIBRARIES = libgtest.la
libgtest_la_SOURCES = ../googletest/googletest/src/gtest-all.cc
libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -pthread

check_PROGRAMS = gtest demo

gtest_SOURCES = gtest.cpp ../src/fields.cpp

gtest_LDADD = libgtest.la

gtest_LDFLAGS = -pthread

gtest_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/src

demo_SOURCES = demo.cpp ../src/fields.cpp

demo_CPPFLAGS = -I$(top_srcdir)/src

TESTS = gtest

ここで、autoreconf -fiv/からmake check(エラーに注意して、うまくいけば修正する)を実行すると、実行するテストを取得できます。

build(dev)$ make check
Making check in tests
/Applications/Xcode.app/Contents/Developer/usr/bin/make  gtest
make[2]: `gtest' is up to date.
/Applications/Xcode.app/Contents/Developer/usr/bin/make  check-TESTS
PASS: gtest
============================================================================
Testsuite summary for IonMotion 0.0.1
============================================================================
# TOTAL: 1
# PASS:  1
# SKIP:  0
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0
============================================================================
22
Joel

単体テストプロジェクト(プロジェクト名:TestProject)のサンプルMakefile.amを次に示します。 GTESTとGMOCKによって異なります。

Makefile.am

#######################################
# The list of executables we are building seperated by spaces
# the 'bin_' indicates that these build products will be installed
# in the $(bindir) directory. For example /usr/bin
#bin_PROGRAMS=exampleProgram

# Because a.out is only a sample program we don't want it to be installed.
# The 'noinst_' prefix indicates that the following targets are not to be
# installed.
noinst_PROGRAMS=utTestProject

#######################################
# Build information for each executable. The variable name is derived
# by use the name of the executable with each non alpha-numeric character is
# replaced by '_'. So a.out becomes a_out and the appropriate suffex added.
# '_SOURCES' for example.

# Sources for the a.out 
utTestProject_SOURCES= \
    utTestProject.cpp

# Library dependencies
utTestProject_LDADD = \
    $(top_srcdir)/../TestProject/build/${Host}/libTestProject/.libs/libTestProject.a \
    ../$(PATH_TO_GTEST)/lib/libgtest.a \
    ../$(PATH_TO_GMOCK)/lib/libgmock.a 

# Compiler options for a.out
utTestProject_CPPFLAGS = \
    -std=c++11 \
    -I../$(PATH_TO_GTEST)/include \
    -I../$(PATH_TO_GMOCK)/include \
    -I$(top_srcdir)/include \
    -I$(top_srcdir)/..

TESTS = utTestProject

TESTS_ENVIRONMENT = export UT_FOLDER_PATH=$(top_srcdir)/utTestProject; \
                    export GTEST_OUTPUT="xml";

gtestのコンパイル:

# Useful vars
SourceVersionedArchiveFolderName="gtest-1.7.0"

#
# Make it
#
pushd .
cd ./${SourceVersionedArchiveFolderName}/make

make gtest.a
if [ $? != 0 ]; then
    echo "$0: Make failed"
    exit 1
fi

popd
2
ssk

GoogletestがAutotoolsの統合を公式に維持していないことは注目に値します:

CMakeに着手する前に、Visual Studio、Xcode、およびAutotools用の手動管理ビルドプロジェクト/スクリプトを提供しています。利便性のために引き続き提供していますが、積極的にメンテナンスされていません。上記のセクションの手順に従って、Google Testを既存のビルドシステムと統合することを強くお勧めします。

https://github.com/google/googletest/tree/master/googletest#legacy-build-scripts

CMakeを使用してGoogletestをビルドすることをお勧めします。

GoogleTestのソースコードをメインビルドで利用できるようにする方法はいくつかあります。

  • GoogleTestのソースコードを手動でダウンロードし、既知の場所に配置します。これは柔軟性が最も低いアプローチであり、継続的インテグレーションシステムなどでの使用が困難になる可能性があります。
  • メインプロジェクトのソースツリーに、GoogleTestのソースコードを直接コピーとして埋め込みます。これは多くの場合最も単純なアプローチですが、最新の状態に保つのが最も困難です。一部の組織では、この方法を許可しない場合があります。
  • GoogleTestをgitサブモジュールまたは同等のものとして追加します。これは常に可能または適切であるとは限りません。たとえば、Gitサブモジュールには、独自の長所と短所があります。
  • CMakeを使用して、ビルドの構成ステップの一部としてGoogleTestをダウンロードします。これはもう少し複雑ですが、他のメソッドの制限はありません。

https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project

0
nnyby