添加和运行测试

一套高质量的测试套件对于确保代码库的正确性和健壮性至关重要。在这里,我们提供如何运行单元测试的说明,以及如何添加新的测试。

目录

添加一个新的单元测试

Python 包: pytest

在目录下添加您的测试

参考 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。)

对于使用 DaskPySpark 等分布式框架进行测试:

# 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_CUDAUSE_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 的 官方文档