【问题标题】:find external test file for unit test by relative path c++ cmake guest通过相对路径c ++ cmake guest查找用于单元测试的外部测试文件
【发布时间】:2014-10-02 09:11:09
【问题描述】:

为 c++ 项目的单元测试访问外部测试文件的正确方法是什么?我正在使用 CMake 和 Gtest。

这是目录结构的示例。

Project
   -src
       -test (unit tests here)
   -test-data (data file here)

谢谢!

【问题讨论】:

    标签: c++ unit-testing cmake googletest


    【解决方案1】:

    我更喜欢查找与可执行测试相关的测试数据。为此,我通常会在一些 TestHelpers.h 中定义一个辅助方法,然后传递我要解析的文件的相对路径。

    inline std::string resolvePath(const std::string &relPath)
    {
        namespace fs = std::tr2::sys;
        // or namespace fs = boost::filesystem;
        auto baseDir = fs::current_path();
        while (baseDir.has_parent_path())
        {
            auto combinePath = baseDir / relPath;
            if (fs::exists(combinePath))
            {
                return combinePath.string();
            }
            baseDir = baseDir.parent_path();
        }
        throw std::runtime_error("File not found!");
    }
    

    要使用它,我去:

    std::string foofullPath = resolvePath("test/data/foo.txt");
    

    只要我的执行目录在项目根目录的后代上运行,这就会为我提供测试文件的完整路径。

    【讨论】:

      【解决方案2】:

      在您的 CMakefile 中,添加您的测试并设置一些带有数据路径的环境变量。

      add_test(mytests ${PROJECT_BINARY_DIR}/unittests)
      set_tests_properties(mytests PROPERTIES 
                           ENVIRONMENT
                           DATADIR=${CMAKE_CURRENT_SOURCE_DIR}/tests/testvectors)
      

      您可以稍后在任何测试中从环境中检索DATADIR

      你的另一个选择是定义一个不同的工作目录

      set_tests_properties(mytests PROPERTIES
              WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)
      

      在我看来,这是一种侵入性较小且更简单的方法。

      【讨论】:

      • 我对带有 ENVIRONMENTWORKING_DIRECTORY 指令的 set_tests_properties() cmake 命令不满意。两者似乎都不适用于 Visual Studio 2019。我已经从运行器中转储了所有环境变量,并从运行器中转储了当前工作目录,它们都保持不变。我怀疑这是 Visual Studio 的问题,而不是 cmake 的问题。
      【解决方案3】:

      将文件名传递给 gtest 参数:

      add_executable(foo ...)
      enable_testing()
      add_test(FooTest foo "${CMAKE_CURRENT_LIST_DIR}/data/input.file")
      

      获取gtest解析输入后的参数:

      int main(int argc, char** argv) {
        ::testing::InitGoogleTest(&argc, argv);
        assert(argc == 2); // gtest leaved unparsed arguments for you
      

      并将其保存到某个全局 *:

        file_name = argv[1];
        return RUN_ALL_TESTS();
      

      * 通常污染全局命名空间不是一个好主意,但我认为测试应用程序很好

      相关

      【讨论】:

      • 这看起来很棒!当我尝试实现它时, argv 没有参数。有什么建议吗?
      • argc/argvInitGoogleTest 之前和之后每次都相同,它们只包含可执行路径而不包含任何参数
      • 作为项目的一部分,我正在 Xcode 中运行测试。我认为它直接运行可执行文件。当我从命令行运行 Ctest 时,它说没有找到任何测试。我可能会遗漏一些正确的 Ctest 设置,但如果你能指导我一个很好的项目示例,该项目正在做我想做的事情(使用 c++、Gtest、CMake 和外部测试文件),我应该能够弄明白。我只是找不到一个很好的例子。谢谢!
      • 这太完美了!谢谢!
      【解决方案4】:

      您可以使用CMAKE_SOURCE_DIR(提供顶级 cmake 目录的绝对路径)变量来定义路径并将其传递给测试脚本。

      【讨论】:

      • 如何从 c++ 代码中访问它?你能帮我举个简单的例子吗?
      • 您不能直接从 c++ 代码访问它,您需要以某种方式提供给运行测试的二进制文件。我从来没有使用过 Gtest,所以我不知道在那种情况下这怎么可能。如果您需要的数据不是很大,您也可以通过 CMake 复制到那里(请参阅file(COPY ...))。有很多方法可以实现这一点,但很大程度上取决于您的 CMake/build/Project/Test 结构如何使其良好
      • 我正在尝试通过 c++ 代码中的相对路径访问文件,因此我不需要根据我的系统对文件路径进行硬编码。 open(test-data/dataFile.txt)
      • 根据您发布的示例结构,您可以执行类似open(../../test-data/dataFile.txt) 的操作。但我假设您正在寻找更灵活的东西。
      猜你喜欢
      • 2020-04-28
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 2017-04-19
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多