pyqtest-qt fail on GitHub Action

151 Views Asked by At

[Edit 9/12/2023 added 'xvfb-run' to 'test.sh' as suggested here, but still pytest still fails with the same seg fault.]

I'm getting a segmentation fault when unit testing PyQT6 app with GitHub Actions, and pytest-qt.

Here in my dummy repo, I have .github/workflows/test.yml as follows:

name: unit-tests
run-name: Run unit tests after push by @${{ github.actor }}
on:
  push:
    branches: [ master ]
jobs:
  unit-test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os : [ubuntu-latest]
        python-version: [ "3.9" ]
    env:
      DISPLAY: ':99.0'
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 x11-utils libegl1 xvfb qt6-base-dev
          /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX
          pip install --upgrade pip
          sudo pip install -r requirements.txt
      - name: Test with pytest
        run: |
          sudo chmod +x ./test.sh
          sudo -E xvfb-run --auto-servernum ./test.sh

I'm using the the GitHub Action configuration suggested by pytest-qt's documentation.

Here's my install dependencies step:

sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 x11-utils libegl1
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX
sudo apt install qt6-base-dev
pip install -r requirements.txt

The first two lines comes from the pytest-qt's documentation as mentioned before. When that didn't work out, I added sudo apt install qt6-base-dev as suggested by one of the answers here.

The test.sh simply runs pytest DummyTest.py.

DummyTest.py is a simple PyQT example:

import sys

import pytest
from PyQt6 import QtCore, QtWidgets
from PyQt6.QtWidgets import QMainWindow, QPushButton


# Import your application module here
# from your_app_module import YourMainWindow

# A dummy PyQt application for testing
class DummyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.button = QPushButton("Click me", self)
        self.button.clicked.connect(self.on_button_click)

    def on_button_click(self):
        self.button.setText("Clicked!")

@pytest.fixture
def app(qtbot):
    # Create a QApplication instance for testing
    test_app = QtWidgets.QApplication(sys.argv)

    # Create a dummy application window and show it
    window = DummyApp()
    window.show()

    # QtBot is used to simulate user actions
    qtbot.addWidget(window)

    yield window

    # Clean up after the test
    window.close()

def test_button_click(app, qtbot):
    # faulthandler.disable()
    # Simulate a button click
    qtbot.mouseClick(app.button, QtCore.Qt.MouseButton.LeftButton)

    # Assert that the button text changes as expected
    assert app.button.text() == "Clicked!"

pytest DummyTest.py runs fine on my local computer.

But as you can see here on the failed GitHub jobs. It fails with a segmentation fault.

============================= test session starts ==============================
platform linux -- Python 3.9.18, pytest-7.4.2, pluggy-1.3.0
PyQt6 6.5.2 -- Qt runtime 6.5.2 -- Qt compiled 6.5.2
rootdir: /home/runner/work/Qt6TestApp/Qt6TestApp
plugins: qt-4.2.0
collected 1 item

Fatal Python error: Aborted

Current thread 0x00007f6298f03b80 (most recent call first):
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pytestqt/plugin.py", line 66 in qapp
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 902 in call_fixture_func
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 1123 in pytest_fixture_setup
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_callers.py", line 77 in _multicall
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_manager.py", line 115 in _hookexec
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_hooks.py", line 493 in __call__
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 1069 in execute
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 693 in _compute_fixture_value
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 607 in _get_active_fixturedef
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 585 in getfixturevalue
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/fixtures.py", line 566 in _fillfixtures
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/python.py", line 1795 in setup
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 494 in setup
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 157 in pytest_runtest_setup
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_callers.py", line 77 in _multicall
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_manager.py", line 115 in _hookexec
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_hooks.py", line 493 in __call__
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 262 in <lambda>
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 341 in from_call
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 261 in call_runtest_hook
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 222 in call_and_report
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 127 in runtestprotocol
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/runner.py", line 114 in pytest_runtest_protocol
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_callers.py", line 77 in _multicall
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_manager.py", line 115 in _hookexec
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_hooks.py", line 493 in __call__
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/main.py", line 350 in pytest_runtestloop
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_callers.py", line 77 in _multicall
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_manager.py", line 115 in _hookexec
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_hooks.py", line 493 in __call__
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/main.py", line 325 in _main
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/main.py", line 271 in wrap_session
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/main.py", line 318 in pytest_cmdline_main
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_callers.py", line 77 in _multicall
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_manager.py", line 115 in _hookexec
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/pluggy/_hooks.py", line 493 in __call__
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/config/__init__.py", line 169 in main
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/_pytest/config/__init__.py", line 192 in console_main
  File "/opt/hostedtoolcache/Python/3.9.18/x64/bin/pytest", line 8 in <module>
./test.sh: line 1:  2529 Aborted                 (core dumped) pytest DummyTest.py
DummyTest.py 
Error: Process completed with exit code 134.

Without be able to run this simple example, it almost feel like GitHub runners lacks support for testing PyQt apps at this point... Could anyone spot what might be missing here?

0

There are 0 best solutions below