continuous-integrationpyqt5bitbucketpytestpytest-qt

Running CI tests with PyQT


I am setting up a CI Bitbucket pipeline for my team. We are using pytest and pytest-qt to test our software. The tests run locally without any issue, but the build fails using pipeline. Here is the pipeline yml:

image: python:3.9

pipelines:
  default:
    - parallel:
      - step:
          name: Test
          caches:
            - pip
          script:
            - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
            - pip install pytest
            - pip install pytest-qt
            - pytest -v tools/IntegrationTests.py --junitxml=test-reports/report.xml

The file requirements.txt contains several modules including:

PyQt5==5.15.4
PyQt5-Qt5==5.15.2

And here is the output when trying to build:

+ pytest -v tools/IntegrationTests.py --junitxml=test-reports/report.xml
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/_pytest/main.py", line 265, in wrap_session
INTERNALERROR>     config._do_configure()
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/_pytest/config/__init__.py", line 982, in _do_configure
INTERNALERROR>     self.hook.pytest_configure.call_historic(kwargs=dict(config=self))
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pluggy/hooks.py", line 308, in call_historic
INTERNALERROR>     res = self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR>     self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pytestqt/plugin.py", line 203, in pytest_configure
INTERNALERROR>     qt_api.set_qt_api(config.getini("qt_api"))
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pytestqt/qt_compat.py", line 104, in set_qt_api
INTERNALERROR>     self.QtGui = _import_module("QtGui")
INTERNALERROR>   File "/usr/local/lib/python3.9/site-packages/pytestqt/qt_compat.py", line 100, in _import_module
INTERNALERROR>     m = __import__(_root_module, globals(), locals(), [module_name], 0)
INTERNALERROR> ImportError: libGL.so.1: cannot open shared object file: No such file or directory

What I get from that is that Qt is not properly installed remotely, thus the tests cannot run.

My question is: can GUI be tested in CI, and if yes, how?

EDIT:

I have broke down to test only the import of PyQt and it boiled down to this test suite:

def test_import_widgets():
    from PyQt5 import QtWidgets


def test_import_core():
    from PyQt5 import QtCore


def test_import_gui():
    from PyQt5 import QtGui


def test_import_qt():
    from PyQt5.QtCore import Qt

Which have resulted in the following results:

2 / 4 tests failed
BasicsTests.test_import_guitools
<1s
ImportError: libGL.so.1: cannot open shared object file: No such file or directory
def test_import_gui():
>       from PyQt5 import QtGui
E       ImportError: libGL.so.1: cannot open shared object file: No such file or directory
tools/BasicsTests.py:50: ImportError
BasicsTests.test_import_widgetstools
<1s
ImportError: libGL.so.1: cannot open shared object file: No such file or directory
def test_import_widgets():
>       from PyQt5 import QtWidgets
E       ImportError: libGL.so.1: cannot open shared object file: No such file or directory
tools/BasicsTests.py:42: ImportError

Solution

  • You have to install the Qt dependencies:

    image: python:3.9
    
    pipelines:
      default:
        - parallel:
          - step:
              name: Test
              caches:
                - pip
              script:
                - apt-get update && apt-get autoclean
                - apt-get install -y '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
                - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
                - pip install pytest
                - pip install pytest-qt
                - pytest -v tools/IntegrationTests.py --junitxml=test-reports/report.xml