You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pytest+Selenium+Jpype时偶发'fatal Python error: Bus error'问题求助

解决pytest+Selenium+Jpype偶发'fatal Python error: Bus error'问题

问题背景

测试脚本基于pytest和Selenium,偶发出现fatal Python error: Bus error,错误触发在conftest.py的fin函数中,涉及Extent报告的flush()和Jpype的shutdownJVM()操作。未使用套接字、线程等需要手动内存管理的功能,用mprof排查内存泄漏未复现问题,偶发特性导致定位困难。

相关代码:

@pytest.fixture(scope="session")
def report_util(request):
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    extent = ExtentReports()
    if not os.path.exists("../reports/"):
        os.makedirs("../reports/")
    extent_reporter = ExtentSparkReporter(f'../reports/report_{timestamp}.html')
    extent_reporter.config().thumbnailForBase64(True)
    extent_reporter.config().setCss("img {width: 400px;}")
    extent.attachReporter(extent_reporter)

    def fin():
        try:
            extent.flush()
            jp.shutdownJVM()
        except Exception as e:
            print(f"Exception during teardown: {e}")
            raise

    request.session.addfinalizer(fin)

    return extent

可能的原因与修复方案

1. 调整JVM关闭时机与资源释放顺序

Bus error通常源于非法内存访问,这里大概率是Jpype关闭JVM时,Extent的Java对象仍被Python引用,导致内存访问冲突。可以通过以下步骤确保资源完全释放:

  • 手动删除Extent相关对象的引用
  • 强制触发Python垃圾回收
  • 短暂延迟等待Java侧资源清理完成后再关闭JVM

修改后的fin函数示例:

def fin():
    try:
        extent.flush()
        # 手动释放Extent相关Python引用
        del extent
        del extent_reporter
        # 强制触发垃圾回收,清理未引用的对象
        import gc
        gc.collect()
        # 短暂延迟,确保Java侧完成资源释放
        import time
        time.sleep(0.5)
        # 关闭JVM
        jp.shutdownJVM()
    except Exception as e:
        print(f"Exception during teardown: {e}")
        raise

2. 确保Jpype JVM的初始化与关闭唯一

检查JVM初始化逻辑,确保整个测试会话中JVM只初始化一次,避免重复初始化或提前关闭导致的内存异常。比如将Jpype的初始化逻辑放在同一个session级fixture中,和报告工具绑定。

3. 升级Jpype与ExtentReports版本

旧版本的Jpype和ExtentReports(尤其是Java实现的部分)可能存在跨语言交互的内存bug,尝试升级到最新稳定版:

  • 升级Jpype:pip install --upgrade jpype1
  • 确保使用兼容的ExtentReports Python绑定版本

4. 调整pytest finalizer的执行顺序

pytest的finalizer按反向添加顺序执行,如果其他fixture持有Java对象且finalizer执行晚于当前报告fixture,会导致JVM关闭时仍有Java对象活跃。可以:

  • 将report_util fixture的依赖声明为其他fixture之后,确保先清理其他Java资源
  • 手动调整finalizer的添加顺序,优先执行非报告相关的资源清理

内容的提问来源于stack exchange,提问作者Aeraf khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 14:20:12