Conan包管理器:单元测试中如何使用资源文件?
针对你的Conan/CMake + Catch2项目,要让测试代码能正确读取test/resources下的资源文件,同时保证这些资源不会被打包到最终产品里,咱们可以这么一步步来:
1. 调整CMake配置,自动复制资源到测试输出目录
首先,在test目录下新增或修改CMakeLists.txt(如果根CMake已经通过add_subdirectory(test)引入了测试模块,直接在测试模块的CMake里加逻辑就行)。核心思路是把test/resources里的文件同步到测试可执行文件所在的目录,这样测试运行时用相对路径就能轻松找到资源。
举个具体的配置例子,假设你的测试目标叫my_unit_tests:
# 定义项目根目录下的测试资源路径 set(TEST_RESOURCES_ROOT ${CMAKE_SOURCE_DIR}/test/resources) # 定义测试二进制所在目录下的资源存放路径 set(TEST_OUTPUT_RESOURCES_DIR ${CMAKE_CURRENT_BINARY_DIR}/resources) # 批量获取所有资源文件 file(GLOB_RECURSE TEST_RESOURCE_FILES ${TEST_RESOURCES_ROOT}/*) # 逐个复制资源到输出目录 foreach(RESOURCE_FILE ${TEST_RESOURCE_FILES}) # 保留资源文件的相对结构(如果resources下有子目录也能正确复制) file(RELATIVE_PATH RELATIVE_PATH ${TEST_RESOURCES_ROOT} ${RESOURCE_FILE}) set(DEST_PATH ${TEST_OUTPUT_RESOURCES_DIR}/${RELATIVE_PATH}) # 创建目标目录(避免子目录不存在导致复制失败) get_filename_component(DEST_DIR ${DEST_PATH} DIRECTORY) file(MAKE_DIRECTORY ${DEST_DIR}) # 执行复制,文件变化时自动重新复制 configure_file(${RESOURCE_FILE} ${DEST_PATH} COPYONLY) endforeach() # 让测试目标依赖资源复制动作,确保构建测试前先同步资源 add_custom_target(copy_test_resources ALL DEPENDS ${TEST_OUTPUT_RESOURCES_DIR}) add_dependencies(my_unit_tests copy_test_resources)
2. 修改测试代码中的资源路径
原来的readFile("test/resources/resource1.xml")需要调整为相对测试二进制的路径:
readFile("resources/resource1.xml")
因为资源已经被复制到了测试可执行文件同目录的resources文件夹里,不管你在哪个目录运行测试,这个相对路径都能正确定位到文件。
3. 确保资源不混入最终产品
由于我们只在测试模块的CMake配置里处理这些资源,主产品的编译目标(比如src目录生成的库或可执行文件)完全不涉及test/resources的内容,所以这些资源绝对不会被打包到最终交付的产品里,完全符合你的需求。
额外小技巧
如果你的资源文件有更新,CMake的configure_file会自动检测到文件变化并重新复制,不用手动清理构建目录。另外,如果你用Conan的多配置生成器(比如cmake_multi),Debug/Release等不同配置的测试二进制会在各自子目录里,CMake也会自动把资源同步到对应配置的目录下,不用担心路径混乱。
内容的提问来源于stack exchange,提问作者Roel

