是否有支持Scons的标准错误报告/任务失败管理工具?
解决方案:在Scons中生成Jupyter测试失败报告
一、自定义Scons流程实现(推荐)
既然团队不愿切换到pytest,完全可以基于Scons+Jupyter nbconvert搭建一套带失败报告的测试流程,核心思路是:用Scons批量执行笔记本测试、单独记录每个笔记本的错误日志,最后汇总生成结构化报告。
1. 实现步骤
在你的SConstruct文件中添加以下逻辑:
- 定义自定义Builder,调用
jupyter nbconvert执行笔记本测试并捕获错误日志 - 批量处理所有目标笔记本
- 最后执行一个汇总脚本,从日志中提取失败信息生成报告
2. 示例代码
import os import subprocess def run_notebook_test(target, source, env): notebook = str(source[0]) log_file = str(target[0]) # 执行笔记本测试,允许继续执行错误单元格,输出日志到文件 proc = subprocess.run( ["jupyter", "nbconvert", "--execute", "--inplace", "--allow-errors", notebook], stderr=subprocess.STDOUT, stdout=open(log_file, "w"), text=True ) return proc.returncode def generate_failure_report(target, source, env): report_path = str(target[0]) failures = [] # 遍历所有日志文件,筛选失败的笔记本 for log_path in source: log_path = str(log_path) notebook_path = log_path[:-9] # 移除.test.log后缀 if not os.path.exists(log_path): continue with open(log_path, "r") as f: log_content = f.read() # 识别nbconvert执行失败的标记 if "Exception occurred" in log_content or "Error executing cell" in log_content: failures.append((notebook_path, log_content)) # 生成Markdown格式的报告 with open(report_path, "w") as f: f.write("# Jupyter Notebook Test Failure Report\n\n") if failures: f.write(f"### {len(failures)} 个笔记本测试失败\n\n") for nb, err in failures: f.write(f"#### 笔记本路径:{nb}\n\n") f.write("错误详情:\n```\n") f.write(err) f.write("\n```\n\n") else: f.write("✅ 所有笔记本测试通过!\n") return 0 # 初始化Scons环境 env = Environment() # 注册笔记本测试Builder env['BUILDERS']['NotebookTest'] = Builder(action=run_notebook_test) # 收集所有要测试的Jupyter笔记本(可根据路径调整Glob规则) notebooks = Glob("**/*.ipynb") # 为每个笔记本创建测试目标,生成对应日志文件 test_targets = [env.NotebookTest(f"{nb}.test.log", nb) for nb in notebooks] # 创建报告生成目标,依赖所有测试日志 report = env.Command("notebook_test_report.md", [t[0] for t in test_targets], generate_failure_report) # 设置默认执行目标:跑所有测试+生成报告 Default(report)
3. 使用方式
在CI环境中执行:
scons -k
执行完成后,会在当前目录生成notebook_test_report.md,里面清晰列出所有失败笔记本的路径和完整错误日志,直接查看即可定位问题。
二、现成工具选项(小众)
目前专门集成在Scons中的Jupyter测试报告工具比较小众,你可以尝试搜索scons-jupyter相关的第三方扩展,但这类工具维护性可能不如自定义方案,且需要额外安装依赖。相比之下,上面的自定义方案更灵活,完全贴合现有流程,不需要引入额外工具链。
内容的提问来源于stack exchange,提问作者Ben Farmer
相关产品推荐
相关产品推荐

