pytest-qt icon indicating copy to clipboard operation
pytest-qt copied to clipboard

Proposal: add `qmlloader` fixture

Open nrbnlulu opened this issue 2 years ago • 6 comments

Hi I created this nice fixture and wanted to ask if it would be usefull to contribute it here? It supports loading QML from strings or from file and retrieving the loaded item with ease.

T = TypeVar("T")

@define(slots=False)
class QmlTestCase:
    bot: QtBot
    engine: QQmlApplicationEngine = field(factory=QQmlApplicationEngine)

    def __attrs_post_init__(self):
        main = Path(__file__).parent / "qmltester.qml"
        self.engine.load(main.resolve(True))

    @property
    def _loader(self) -> QQuickItem:
        self.root = self.engine.rootObjects()[0]
        return self.root.findChild(QQuickItem, "contentloader")

    def load(self, path: Path) -> QQuickItem:
        self.bot.wait(100)
        self._loader.setProperty("source", str(path.resolve(True)))
        return self._loader.property("item")

    def loads(self, content: str) -> QQuickItem:
        self.comp = QQmlComponent(self.engine)
        self.comp.setData(content.encode("utf-8"), QUrl())
        self._loader.setProperty("source", "")
        self._loader.setProperty("sourceComponent", self.comp)
        return self._loader.property("item")

    def find(self, objectname: str, type: T = QQuickItem) -> T:
        return self.window.findChild(type, objectname)


@pytest.fixture()
def qmlloader(qtbot):
    return QmlTestCase(qtbot)

Usage:

@pytest.mark.parametrize("status", iter(object_with_enum.Status))
def test_accessible_from_qml(qmlloader, status):
    qml = (
        """
import QtQuick
import QtGql 1.0 as GQL

Rectangle {
    property int enumValue: GQL.Enums.%s
}
"""
        % status.name
    )

    EnumTestCase.compile()
    item = qmlloader.loads(qml)
    assert item.property("enumValue") == status.value

nrbnlulu avatar Feb 01 '23 08:02 nrbnlulu

That's interesting!

I have never used QtQuick myself, but this looks like a welcome addition to pytest-qt.

I think we should name it qmlbot (or something like this) in case we want to add more helper functions to it. Other than that, this would be a great contribution.

nicoddemus avatar Feb 01 '23 11:02 nicoddemus

BTW why not use qtpy to manage the diffrent bindings?

nrbnlulu avatar Feb 01 '23 12:02 nrbnlulu

Did not know about it when pytest-qt was created, never bothered to depend on qtpy.

nicoddemus avatar Feb 01 '23 12:02 nicoddemus

They support type hints, I would suggest to migrate to qtpy, I can help if you want

nrbnlulu avatar Feb 01 '23 12:02 nrbnlulu

They support type hints, I would suggest to migrate to qtpy, I can help if you want

Not against it, however we need to keep the existing support of selecting backends via environment variables (did not look into qtpy to see how to accomplish that).

nicoddemus avatar Feb 01 '23 13:02 nicoddemus

Created #477 to track this. :+1:

nicoddemus avatar Feb 01 '23 13:02 nicoddemus