ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

This can be solved using CMake or using catkin.

The CMake way to solve this would be to create a template file which would have the location of the test data injected at build time.

Lets say you had a layout like this:

my_pkg/
--include/
--src/
--test/
----data/
------test.dat
----test_with_data.cpp
----test_with_data_settings.h.in

The data file might look like this:

1 2 3
3 4 7
100 -16 84

The test might look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

#include "test_with_data_settings.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open((std::string(TEST_DIR) + std::string("/test.dat")).c_str(), std::fstream::in);
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

The header file might look like:

#define TEST_DIR "@TEST_WITH_DATA_TEST_DIR@"

And the relavent CMake code:

get_filename_component(TEST_WITH_DATA_TEST_DIR "test/data" ABSOLUTE)
configure_file(test/test_with_data_settings.h.in test/test_with_data_settings.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/test)
catkin_add_gtest(${PROJECT_NAME}-test test/test_with_data.cpp)
if(TARGET ${PROJECT_NAME}-test)
  target_link_libraries(${PROJECT_NAME}-test add)
endif()

The catkin way to solve this would be to use the WORKING_DIRECTORY option of catkin_add_gtest inorder to have your tests run in a place relative to the data location.

So you would drop the settings header and your test would look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open("data/test.dat", std::fstream::in);
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

With this CMake code:

catkin_add_gtest(${PROJECT_NAME}2-test test/test_with_data2.cpp WORKING_DIRECTORY test)
if(TARGET ${PROJECT_NAME}2-test)
  target_link_libraries(${PROJECT_NAME}2-test add)
endif()

I have setup a demo package that demonstrates both methods here:

https://github.com/wjwwood/catkin_demos/tree/master/test_with_data

You can run them by making a workspace, and invoking catkin_make run_tests:

$ mkdir test_ws
$ cd test_ws
$ mkdir src
$ cd src
$ ln -s /path/to/catkin_demos/test_with_data ./
$ source /opt/ros/groovy  # OR ln -s /path/to/catkin ./
$ cd ..
$ catkin_make run_tests   # OR ./src/catkin/bin/catkin_make run_tests

This can be solved using CMake or using catkin.

The CMake way to solve this would be to create a template file which would have the location of the test data injected at build time.

Lets say you had a layout like this:

my_pkg/
--include/
--src/
--test/
----data/
------test.dat
----test_with_data.cpp
----test_with_data_settings.h.in

The data file might look like this:

1 2 3
3 4 7
100 -16 84

The test might look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

#include "test_with_data_settings.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open((std::string(TEST_DIR) + std::string("/test.dat")).c_str(), std::fstream::in);
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

The header file might look like:

#define TEST_DIR "@TEST_WITH_DATA_TEST_DIR@"

And the relavent CMake code:

get_filename_component(TEST_WITH_DATA_TEST_DIR "test/data" ABSOLUTE)
configure_file(test/test_with_data_settings.h.in test/test_with_data_settings.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/test)
catkin_add_gtest(${PROJECT_NAME}-test test/test_with_data.cpp)
if(TARGET ${PROJECT_NAME}-test)
  target_link_libraries(${PROJECT_NAME}-test add)
endif()

The catkin way to solve this would be to use the WORKING_DIRECTORY option of catkin_add_gtest inorder to have your tests run in a place relative to the data location.

So you would drop the settings header and your test would look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open("data/test.dat", std::fstream::in);
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

With this CMake code:

catkin_add_gtest(${PROJECT_NAME}2-test test/test_with_data2.cpp WORKING_DIRECTORY test)
if(TARGET ${PROJECT_NAME}2-test)
  target_link_libraries(${PROJECT_NAME}2-test add)
endif()

I have setup a demo package that demonstrates both methods here:

https://github.com/wjwwood/catkin_demos/tree/master/test_with_data

You can run them by making a workspace, and invoking catkin_make run_tests:

$ mkdir test_ws
$ cd test_ws
$ mkdir src
$ cd src
$ ln -s /path/to/catkin_demos/test_with_data ./
$ source /opt/ros/groovy /opt/ros/groovy/setup.bash  # OR ln -s /path/to/catkin ./
$ cd ..
$ catkin_make run_tests    # OR ./src/catkin/bin/catkin_make run_tests

This can be solved using CMake CMake or using catkin.catkin.

CMake Option:

The CMake way to solve this would be to create a template file which would have the location of the test data injected at build time.

Lets say you had a layout like this:

my_pkg/
--include/
--src/
--test/
----data/
------test.dat
----test_with_data.cpp
----test_with_data_settings.h.in

The data file might look like this:

1 2 3
3 4 7
100 -16 84

The test might look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

#include "test_with_data_settings.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open((std::string(TEST_DIR) + std::string("/test.dat")).c_str(), std::fstream::in);
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

The header file might look like:

#define TEST_DIR "@TEST_WITH_DATA_TEST_DIR@"

And the relavent CMake code:

get_filename_component(TEST_WITH_DATA_TEST_DIR "test/data" ABSOLUTE)
configure_file(test/test_with_data_settings.h.in test/test_with_data_settings.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/test)
catkin_add_gtest(${PROJECT_NAME}-test test/test_with_data.cpp)
if(TARGET ${PROJECT_NAME}-test)
  target_link_libraries(${PROJECT_NAME}-test add)
endif()

catkin Option:

The catkin way to solve this would be to use the WORKING_DIRECTORY option of catkin_add_gtest inorder to have your tests run in a place relative to the data location.

So you would drop the settings header and your test would look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open("data/test.dat", std::fstream::in);
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

With this CMake code:

catkin_add_gtest(${PROJECT_NAME}2-test test/test_with_data2.cpp WORKING_DIRECTORY test)
if(TARGET ${PROJECT_NAME}2-test)
  target_link_libraries(${PROJECT_NAME}2-test add)
endif()

I have setup a demo package that demonstrates both methods here:

https://github.com/wjwwood/catkin_demos/tree/master/test_with_data

You can run them by making a workspace, and invoking catkin_make run_tests:

$ mkdir test_ws
$ cd test_ws
$ mkdir src
$ cd src
$ ln -s /path/to/catkin_demos/test_with_data ./
$ source /opt/ros/groovy/setup.bash  # OR ln -s /path/to/catkin ./
$ cd ..
$ catkin_make run_tests              # OR ./src/catkin/bin/catkin_make run_tests

This can be solved using CMake or using catkin.

CMake Option:

The CMake way to solve this would be to create a template file which would have the location of the test data injected at build time.

Lets say you had a layout like this:

my_pkg/
--include/
--src/
--test/
----data/
------test.dat
----test_with_data.cpp
----test_with_data_settings.h.in

The data file might look like this:

1 2 3
3 4 7
100 -16 84

The test might look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

#include "test_with_data_settings.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open((std::string(TEST_DIR) + std::string("/test.dat")).c_str(), std::fstream::in);
  ASSERT_FALSE(in.fail());
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

The header file might look like:

#define TEST_DIR "@TEST_WITH_DATA_TEST_DIR@"

And the relavent CMake code:

get_filename_component(TEST_WITH_DATA_TEST_DIR "test/data" ABSOLUTE)
configure_file(test/test_with_data_settings.h.in test/test_with_data_settings.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/test)
catkin_add_gtest(${PROJECT_NAME}-test test/test_with_data.cpp)
if(TARGET ${PROJECT_NAME}-test)
  target_link_libraries(${PROJECT_NAME}-test add)
endif()

catkin Option:

The catkin way to solve this would be to use the WORKING_DIRECTORY option of catkin_add_gtest inorder to have your tests run in a place relative to the data location.

So you would drop the settings header and your test would look like this:

#include <fstream>
#include <string.h>

#include "gtest/gtest.h"

#include "test_with_data/add.h"

namespace {

class SomeTests : public ::testing::Test {};

TEST_F(SomeTests, test_add) {
  std::fstream in;
  in.open("data/test.dat", std::fstream::in);
  ASSERT_FALSE(in.fail());
  int op1, op2, expected;
  while (in >> op1 >> op2 >> expected) {
    EXPECT_EQ(expected, test_with_data::add(op1, op2));
  }
  in.close();
}

}

int main(int argc, char **argv) {
  try {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  }
  return 1;
}

With this CMake code:

catkin_add_gtest(${PROJECT_NAME}2-test test/test_with_data2.cpp WORKING_DIRECTORY test)
${PROJECT_SOURCE_DIR}/test)
if(TARGET ${PROJECT_NAME}2-test)
  target_link_libraries(${PROJECT_NAME}2-test add)
endif()

I have setup a demo package that demonstrates both methods here:

https://github.com/wjwwood/catkin_demos/tree/master/test_with_data

You can run them by making a workspace, and invoking catkin_make run_tests:

$ mkdir test_ws
$ cd test_ws
$ mkdir src
$ cd src
$ ln -s /path/to/catkin_demos/test_with_data ./
$ source /opt/ros/groovy/setup.bash  # OR ln -s /path/to/catkin ./
$ cd ..
$ catkin_make run_tests              # OR ./src/catkin/bin/catkin_make run_tests