find external test file for unit test by relative path c++ cmake guest

10,196

Solution 1

I prefer to find my test data relative to my executable test. To do so, I usually define a helper method in some TestHelpers.h and then pass the relative path of the file I'm looking to resolve.

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!");
}

To use it, I go:

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

and that gives me a full path of the test file as long as my executing directory runs from on a descendant of the project's root directory.

Solution 2

In your CMakefile, add your tests and set some an environment variable with the path to you data.

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

You can later retrieve the DATADIR from the environment in any test.

You other option is to define a different working directory

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

In my opinion, this is the less intrusive and simpler way.

Solution 3

You could use the CMAKE_SOURCE_DIR (gives absolute path of the top level cmake directory) variable to define the path and pass it to the test script.

Share:
10,196
Teancum
Author by

Teancum

Updated on June 03, 2022

Comments

  • Teancum
    Teancum almost 2 years

    What would be the proper way to access an external test file for the unit test of a c++ project? I am using CMake and Gtest.

    This is a sample of the directory structure.

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

    Thanks!

  • Teancum
    Teancum over 9 years
    How would I access this from the c++ code? Could you help me with a simple example?
  • lazycoder
    lazycoder over 9 years
    You can't access that from the c++ code directly, you would need to somehow feed to the binary that runs the test. I've never used Gtest so I don't how that might be possible in that context. If the data is you need is not very large you also could copy there via CMake (see file(COPY ...)). There are a lot ways you can achieve this, but depends very heavily on your CMake/build/Project/Test structure how to make it good .
  • Teancum
    Teancum over 9 years
    I am trying to access the file by the relative path in the c++ code so I do not need to hard code the file path based on my system. open(test-data/dataFile.txt)
  • lazycoder
    lazycoder over 9 years
    Based on the sample structure you posted, you can just do something like open(../../test-data/dataFile.txt). But I assumed you are looking for something more flexible.
  • skelliam
    skelliam over 2 years
    I'm not having luck with set_tests_properties() cmake command with either the ENVIRONMENT or the WORKING_DIRECTORY directives. Neither one seem to work in Visual Studio 2019. I've dumped all environment variables from within the runner and dumped the current working directory from within the runner, and they both remain unchanged. I suspect it is an issue with Visual Studio and not cmake however.