【问题标题】:How can I use Google Test with my project that builds via autotools?如何在通过自动工具构建的项目中使用 Google Test?
【发布时间】:2016-06-30 03:49:33
【问题描述】:

似乎有一些答案有点,有点道理,但我不知道如何执行。而且我还没有找到一个全面的答案。

第一个问题

Google Test 不应是已安装的库,而应与项目一起构建。 (请参阅FAQ。)据我所知,这意味着 Google 测试库是我的单元测试的依赖项,并且应该在我第一次在我的项目中运行“make check”时构建。这应该在某个目录中构建 Google 测试库。我不知道该怎么做。它提到了一些已弃用的 autotools 脚本,我不确定他们在说什么或如何正确地指出我的构建。

第二个问题

假设构建成功,我该如何编写一个使用本地编译版本的 Google 测试来运行测试的测试?我假设有一堆 Makefile.am 命令放在我的测试目录中。但它们是什么?什么是使用 Google Test 的单元测试示例?

【问题讨论】:

    标签: c++ unit-testing automated-tests autotools googletest


    【解决方案1】:

    我已经满意地解决了这个问题!我现在将完全继续前进。这基本上是要求一个教程。有很多必须做出的决定,希望是合乎逻辑的,以便 Google 测试与自动工具很好地吻合。所以我提前为冗长的答案道歉,但所有细节都应该在那里。

    第一个问题

    为了理解答案,需要稍微改写问题。我们正在将 Google Test 编译为我们的测试代码将链接到的库。将不会安装该库。我们要问的问题是

    "我们如何配置 autotools 以将 Google Test 编译为库 我们的测试代码可以链接到哪个?”

    为此,我们需要下载 Google Test 并将其放入我们的项目中。我使用 Github,所以我通过在我的项目的根路径中添加一个子模块来做到这一点:

    $ git submodule add git@github.com: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)
    

    我需要按照instructions 进行编译。我只希望在运行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 中启用子目录对象。这是通过将其添加到 AM_INIT_AUTOMAKE 行来完成的。我还需要在 AC_CONFIG_FILES 中包含 makefile。我们还想使用 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 时编译,如果我们只想makemake install 时不编译它可以节省时间。

    第二个问题

    现在,需要改进第二个问题:您如何 (a) 创建一个测试 (b) 链接到 Google 测试库并因此使用它们?这些问题有点交织在一起,所以我们马上回答。

    创建测试只需将以下代码放入位于/tests/gtest.cppgtest.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”,因此我们需要确保我们告诉 automake 包含一个具有 gtest/gtest.h 的目录。

    接下来,我们需要告诉 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 链接到 libgtest.la,它将被编译到 /tests 目录中。 Google 希望我们使用 gtest_LDFLAGS 行来启用 pthread。最后,我们需要包含头文件“gtest/gtest.h”所在的位置,即 gtest_CPPFLAGS 行。 Google 还希望我们包含 /googletest/googletest 位置,并包含

    现状: Google Test 库libgtest.la 将与make 一起编译到目录/tests 中,但不会被安装。二进制 gtest 只会用make check 编译,但不会安装。

    接下来我们要告诉 automake 实际运行编译后的二进制 gtest 并报告错误。这是通过在/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
    

    现在,来自/make checkautoreconf -fiv(注意任何错误并希望修复它们),你应该得到一个运行的测试:

    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
    ============================================================================
    

    【讨论】:

    • Makefile.am 的初始示例从libgtest_la_SOURCES 中省略了src/ 目录组件。否则写得很好。
    • 引物的链接应该使用小写的 p (primer.md),但我无法进行单字符编辑。
    • 如何使用 CMake 实现这一目标?
    • 谢谢,在这里使用了您的解决方案:github.com/CarloWood/ai-evio-testsuite/blob/master/tests/…
    • @RyanH。谢谢你。我已经解决了这个问题以及更多问题。
    【解决方案2】:

    这是单元测试项目(项目名称: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
    

    【讨论】:

    • 你从哪里得到的?还是你自己编的??
    • 我从我自己的项目中提取了这个。希望对您有所帮助!
    • 看起来这可以回答我关于用于单元测试的 Makefile.am 的问题。但是当你运行 make check 时如何让 gtest 编译呢?我没有看到任何会导致 gtest 编译的链接...
    • 用安装脚本更新了答案。它适用于mac os x。您可以复制输出,即 .a 并包含文件以适合您的包含路径。
    • 难道我们不想要安装脚本吗?难道我们不希望您的测试(看起来您正在调用 utTestProject)依赖于某种方式来编译 gtest 吗?我想这会将任何 Google 测试依赖项添加到您的项目中
    【解决方案3】:

    值得注意的是,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

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多