测试实践
概览
总结 RAPIDS 项目中使用的测试实践。
目标受众
开发者
项目负责人
运维人员
基础设施人员
总体目标:遵循开源生态系统进行基础设施选择
GitHub Actions
请在此处查看文档。
GitHub
- 所有项目都托管在 GitHub 上,以增强开源可见性
Docker
- 容器化软件的行业标准
- 允许隔离所有构建
代码风格 / 格式化
- 在每次提交时运行风格检查和/或自动格式化工具,以确保代码在合并到仓库之前以一种整洁一致的方式统一格式化
- 处理诸如最大行长、尾随空格、换行语义等问题
在使用代码格式化工具方面遵循开源生态系统
- C++
- Clang-Format (计划中)
- Python
- Flake8
- 使用 Black 进行自动格式化 (计划中)
单元测试
- 在每次提交时运行,以确保代码不会以损坏状态被推送
- 向 GitHub 报告,向最终用户提供有关具体问题是什么的反馈
- 在支持的操作系统 / CUDA / Python 版本上进行矩阵测试,并运行 CUDA-memcheck (计划中)
- 测试项目在有 GPU 和没有 GPU 的情况下都能成功构建,然后确保单元测试套件在有 GPU 的情况下能成功运行
- 测试构建 conda 和 pip 包
- 测试被设计为针对外部用户可见函数和内部函数的黑盒测试
- 编写测试时,会与 Pandas / Numpy / Scikit-Learn / NetworkX 等进行比较,以确保结果与最终用户的期望完全一致
在使用测试框架方面遵循开源生态系统
- C++
- Python
数据集
- 许多测试依赖于特定数据集的存在才能正确验证代码的正确性。有关更多详细信息,请参阅数据集。
集成 / 工作流测试与基准测试
- 每晚运行,以确保不同库按预期进行集成,类似于其他 Python 库的集成方式(例如 cuDF 与 cuML 集成,而 Pandas 与 SKLearn 集成)
- 除了检查运行是否成功且没有错误并检查正确性外,还测量工作流中的性能回归
- 将 Google Benchmark 的输出导入 ASV 面板,以便于查看
- 对每个工作流进行性能分析并导出 nvprof / nsight 分析结果,方便开发者进行分析 (计划中)
- 也允许自然地使用示例 / 工作流 Notebook 进行集成 / 工作流 / 性能测试
- 在支持的操作系统 / CUDA / Python 版本上进行矩阵测试
在使用测试框架方面遵循开源生态系统
- C++
- GTest
- Google Benchmark (计划中)
- Python
- Pytest
- Airspeed Velocity (ASV)
打包与发布
- 在打包和交付机制方面遵循开源生态系统
- Conda
- Pip
- Docker
- 发布版本
- 大约每 6 周发布一次,且没有已知的严重 bug
- 让用户获得一个稳定的发布版本,该版本在开发过程中不会引入性能回归或 bug
- 在发布包 / 容器之前,会执行全套单元 / 集成 / 工作流测试
- “夜间构建”
- 允许前沿用户安装最新的 conda 包来测试下一个版本中即将发布的新功能
- 每个项目在每次合并时都会创建 Conda 包
- Docker 容器每晚构建,并运行集成测试,必须通过测试后才能发布容器
测试实践示例
- cuDF 对 DLPack 的支持
- https://github.com/rapidsai/cudf/pull/913
- 带有 GTest 单元测试的 C++ 实现
- https://github.com/rapidsai/cudf/pull/1159
- 带有 PyTest 单元测试和与 CuPy/Chainer 集成正确性测试的 Python 绑定实现
- 在其他库的实现中发现了一些额外的问题,需要在 C++ 实现中进行一些修复
- https://github.com/rapidsai/cudf/pull/913
- cuDF 对字符串的支持
- https://github.com/rapidsai/cudf/pull/1032
- C++ 实现和 Python 绑定
- 最初依赖于另一个未发布的库版本,导致 CI 构建失败,并阻止合并到主仓库,直到该问题解决为止
- GTest 和 PyTest 单元测试,其结果逐步推动了 C++ 和 Python 的开发
- 大量使用单元测试参数化来有效地测试不同的函数参数,以获得足够的测试覆盖率
- https://github.com/rapidsai/cudf/pull/1032