find external test file for unit test by relative path c++ cmake guest
Pass the file name to gtest arguments:
add_executable(foo ...)
enable_testing()
add_test(FooTest foo "${CMAKE_CURRENT_LIST_DIR}/data/input.file")
get the parameter after gtest parse input:
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
assert(argc == 2); // gtest leaved unparsed arguments for you
and save it to some global *:
file_name = argv[1];
return RUN_ALL_TESTS();
* Usually it's not a very good idea to pollute the global namespace but I think it's fine for testing app
Related
- How to pass parameters to the gtest
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.
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.