添加和运行测试
一套高质量的测试套件对于确保代码库的正确性和健壮性至关重要。在这里,我们提供如何运行单元测试的说明,以及如何添加新的测试。
目录
添加一个新的单元测试
Python 包: pytest
在目录下添加您的测试
tests/python/ 的链接
tests/python-gpu/ (如果你在测试GPU代码)
tests/test_distributed. (如果使用了分布式框架)
参考 PyTest 教程 以学习如何为 Python 代码编写测试。
你可以按照 这一节 中的说明来运行你的测试。
C++: Google 测试
在目录 tests/cpp/ 下添加你的测试。参考 这篇关于使用Google Test的优秀教程。
你可以按照 这一节 中的说明来运行你的测试。注意。需要 Google Test 版本 1.8.1 或更高。
JVM 包:JUnit / scalatest
XGBoost 的 JVM 包(XGBoost4J / XGBoost4J-Spark)使用 Maven 标准目录布局。具体来说,JVM 包的测试位于以下位置:
要为Java代码编写测试,请参阅 JUnit 5 教程。要为Scala编写测试,请参阅 Scalatest 教程。
你可以按照 这一节 中的说明来运行你的测试。
R 包:testthat
将您的测试添加到目录 R-package/tests/testthat 下。参考 这篇关于 testthat 的优秀教程。
你可以按照 这一节 中的说明来运行你的测试。
本地运行单元测试
R 包
运行
python ./tests/ci_build/test_r_package.py --task=check
在项目目录的根目录下。该命令构建并检查 XGBoost r-package。或者,如果您只想运行测试,可以在安装 XGBoost 后使用以下命令:
cd R-package/tests/
Rscript testthat.R
JVM 包
Maven 被使用
mvn test
Python 包: pytest
要运行 Python 单元测试,首先安装 pytest 包:
pip3 install pytest
然后根据 构建共享库 中的说明编译 XGBoost。最后,在项目根目录下调用 pytest:
# Tell Python where to find XGBoost module
export PYTHONPATH=./python-package
pytest -v -s --fulltrace tests/python
此外,要测试 CUDA 代码,请运行:
# Tell Python where to find XGBoost module
export PYTHONPATH=./python-package
pytest -v -s --fulltrace tests/python-gpu
(在此步骤中,您应该已经编译了启用了CUDA的XGBoost。)
对于使用 Dask
和 PySpark
等分布式框架进行测试:
# Tell Python where to find XGBoost module
export PYTHONPATH=./python-package
pytest -v -s --fulltrace tests/test_distributed
C++: Google 测试
要构建和运行C++单元测试,请在运行CMake时启用测试:
mkdir build
cd build
cmake -GNinja -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON -DUSE_CUDA=ON -DUSE_NCCL=ON ..
ninja
./testxgboost
像 USE_CUDA
、USE_DMLC_GTEST
这样的标志是可选的。关于如何从源码构建 XGBoost 的更多信息,请参阅 从源码构建。也可以使用 ctest 工具运行所有单元测试,该工具提供了更高的灵活性。例如:
ctest --verbose
如果你需要在Windows上使用VS的调试器调试错误,你可以在 test_main.cc 中添加gtest标志:
::testing::GTEST_FLAG(filter) = "Suite.Test";
::testing::GTEST_FLAG(repeat) = 10;
Sanitizers: 检测内存错误和数据竞争
默认情况下,净化器会捆绑在 GCC 和 Clang/LLVM 中。可以使用 GCC >= 4.8 或 LLVM >= 3.1 启用净化器,但某些发行版可能会单独打包净化器。以下是支持的净化器及其相应的库名称列表:
地址清理器:libasan
未定义的清理器:libubsan
泄漏检测器: liblsan
线程清理器: libtsan
内存清理器是 LLVM 独有的,因此在 XGBoost 中不受支持。使用最新版本的编译器如 gcc-9,当指定清理器标志时,编译器驱动程序应能够自动链接运行时库。
如何使用 sanitizers 构建 XGBoost
可以通过指定 -DUSE_SANITIZER=ON 来构建支持 sanitizer 的 XGBoost。默认情况下,当您打开 USE_SANITIZER 标志时,会使用地址 sanitizer 和泄漏 sanitizer。您始终可以通过提供一个以分号分隔的 sanitizer 列表来更改默认设置,将其传递给 ENABLED_SANITIZERS。请注意,线程 sanitizer 与其他两个 sanitizer 不兼容。
cmake -DUSE_SANITIZER=ON -DENABLED_SANITIZERS="address;undefined" /path/to/xgboost
默认情况下,CMake 会在常规系统路径中搜索 sanitizers,您也可以提供一个指定的 SANITIZER_PATH。
cmake -DUSE_SANITIZER=ON -DENABLED_SANITIZERS="address;undefined" \
-DSANITIZER_PATH=/path/to/sanitizers /path/to/xgboost
如何在使用CUDA支持的情况下使用清理器
在 CUDA 上运行带有地址清理器 (asan) 的 XGBoost 会引发内存错误。要正确使用带有 CUDA 的 asan,您需要通过 ASAN_OPTIONS 环境变量配置 asan:
ASAN_OPTIONS=protect_shadow_gap=0 ${BUILD_DIR}/testxgboost
其他净化器运行时选项
默认情况下,未定义的清理器不会打印回溯。您可以通过导出环境变量来启用它:
UBSAN_OPTIONS=print_stacktrace=1 ${BUILD_DIR}/testxgboost
详情请参阅 sanitizers 的 官方文档。