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

Ubuntu22.04下使用pytest-qt的qtbot fixture出现Segmentation Fault问题

在Ubuntu 22.04使用pytest-qt的qtbot fixture时触发段错误

环境

  • Ubuntu 22.04
  • Python 3.10.4
  • Poetry 项目管理工具
  • PyQt6 6.5.1
  • pytest 7.4.0
  • pytest-qt 4.2.0

问题

测试用例中引入qtbot fixture后,运行pytest会出现Segmentation Fault;移除qtbot后测试可正常执行。以下是最小复现流程:

复现步骤

$ poetry new --src myproject
$ cd myproject
$ poetry add pyqt6
$ poetry add --group=dev pytest
$ poetry add --group=dev pytest-qt
$ cat <<'END' > pytest.ini
[pytest]
qt_api=pyqt6
END
$ cat <<'END' > src/myproject/main.py
from PyQt6.QtWidgets import QApplication
def qapp(app: QApplication) -> None:  # 待测试函数
    app.quit()
END
$ cat <<'END' > tests/test_main.py  # 测试文件
import pytest
from PyQt6.QtWidgets import QApplication
import myproject.main
from typing import Any
QtBot = Any  # 缺失类型提示
def test_app(qtbot: QtBot) -> None:
    app = QApplication([])
    myproject.main.qapp(app)
    assert 1 == 1
END
$ poetry install
$ poetry shell
$ pytest

错误日志

============================================================================ test session starts ============================================================================
platform linux -- Python 3.10.4, pytest-7.4.0, pluggy-1.2.0
PyQt6 6.5.1 -- Qt runtime 6.5.1 -- Qt compiled 6.5.1
rootdir: /home/hakon/test/python/pytest-qt/qtbot/myproject
plugins: qt-4.2.0
collected 1 item                                                                                                                                                             

tests/test_main.py Fatal Python error: Segmentation fault

Current thread 0x00007f24e2fc1740 (most recent call first):
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/python.py", line 194 in pytest_pyfunc_call
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/python.py", line 1788 in runtest
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 169 in pytest_runtest_call
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 262 in <lambda>
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 341 in from_call
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 261 in call_runtest_hook
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 222 in call_and_report
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 133 in runtestprotocol
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 114 in pytest_runtest_protocol
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 349 in pytest_runtestloop
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 324 in _main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 270 in wrap_session
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 317 in pytest_cmdline_main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/config/__init__.py", line 166 in main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/config/__init__.py", line 189 in console_main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/bin/pytest", line 8 in <module>

Extension modules: PyQt6.QtCore, PyQt6.QtGui, PyQt6.QtWidgets, PyQt6.QtTest (total: 4)
Segmentation fault (core dumped)

解决方案

问题根源

qtbot fixture内部会自动创建一个QApplication实例,而你在测试代码中又手动创建了另一个实例。Qt规定一个进程只能存在一个QApplication实例,重复创建会导致底层资源冲突,最终触发段错误。

修复代码

修改tests/test_main.py,使用qtbot已创建的QApplication实例,不要手动初始化:

import pytest
import myproject.main
from pytestqt.qtbot import QtBot  # 导入正确的类型提示

def test_app(qtbot: QtBot) -> None:
    # 直接使用qtbot自带的app实例
    myproject.main.qapp(qtbot.app)
    assert 1 == 1

或者通过QApplication.instance()获取已存在的实例:

import pytest
from PyQt6.QtWidgets import QApplication
import myproject.main
from pytestqt.qtbot import QtBot

def test_app(qtbot: QtBot) -> None:
    app = QApplication.instance()
    myproject.main.qapp(app)
    assert 1 == 1

额外提示

  • pytest-qt会自动管理QApplication的生命周期,测试开始前创建,测试结束后销毁,无需手动处理。
  • 导入from pytestqt.qtbot import QtBot代替Any,能获得正确的类型提示,提升开发体验。

内容的提问来源于stack exchange,提问作者Håkon Hægland

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:30:53