pytest-qtを使用してテストするときに致命的なPythonエラーが発生するのはなぜですか?

Nov 22 2020

pytest-qtを使用した最初のテストは、致命的なPythonエラーですぐに失敗しました。私はコードをこれに減らしました(決して合格しないが、クラッシュするべきではないテスト):

from PyQt5 import QtCore as qtc


class sut(qtc.QObject):
    sig_sig_sputnik = qtc.pyqtSignal()

    def __init__(self):
        super().__init__()

    def listen(self):
        pass


def test_emit(qtbot):
    uut = sut()
    with qtbot.waitSignal(sut.sig_sig_sputnik, raising=True):
        uut.listen()

これの実行は次の場合に失敗します:

=== test session starts ====
platform linux -- Python 3.6.9, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
PyQt5 5.10.1 -- Qt runtime 5.12.9 -- Qt compiled 5.9.5
rootdir: [~]/src/npsw/frameworks/rtx, inifile: pytest.ini
plugins: qt-3.3.0, metadata-1.10.0, html-2.1.1, jnj-radish-1.4.0
collected 1 item                                                                                                                                                             

test_min.py Fatal Python error: Aborted

Current thread 0x00007f7c8411c740 (most recent call first):
  File "[~]/.local/lib/python3.6/site-packages/pytestqt/plugin.py", line 57 in qapp
  File "[~]/.local/lib/python3.6/site-packages/_pytest/fixtures.py", line 792 in call_fixture_func
  File "[~]/.local/lib/python3.6/site-packages/_pytest/fixtures.py", line 964 in pytest_fixture_setup
[boilerplate pytest stack from here on down]

障害はqappフィクスチャで発生しますが、テストはqtbot(それqapp自体を使用する)を使用していることに注意してください。

PyQt5、Qtランタイム、およびコンパイルされたQt(出力の2行目)に表示されるバージョン間に不一致があることを認識しています。私の18.04Ubuntuシステムには(標準のバイオニックPPAからの)システム全体のQtとしてQt5.9がありますが、開発グループは5.12を使用しています。5.12ランタイムは特定の場所にインストールされ、この実行でLD_LIBRARY_PATHはその場所を指します。この設定を使用しないと、pytestが実行を開始する前に別のエラーが発生します。

INTERNALERROR> ImportError: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5: symbol _ZNK15QDateTimeParser5parseER7QStringRiRK9QDateTimeb version Qt_5_PRIVATE_API not defined in file libQt5Core.so.5 with link time reference

回答

MikeC Nov 24 2020 at 22:33

当然のことながら、Qt5.12ライブラリーが単にフォルダーにコピーされるという構成上の問題があります。私は次のように回避策を作成することができました:

sudo mkdir /usr/bin/platforms
sudo ln -s /our/local/libqxcb.so /usr/bin/platforms/libqxcb.so

これは、このクラッシュなしでテストを実行するのに十分でした。

pytest-qtサイトのFlorianが私にアドバイスしたように、このPythonは次のとおりです。

from PyQt5.QtWidgets import QApplication
app = QApplication([])

また失敗しますが、多くの情報がありません。それから私はへのヒントを得ました

export QT_DEBUG_PLUGINS=1

そして、追加の診断情報が私にそのplatformsフォルダを示しました。