[PYTHON] Testgetriebenes Entwicklungsstart mit PySide & Pytest

Einführung

Ergänzender Artikel zum Thema "Testgetriebenes Entwicklungsstart mit PySide & Pytest" auf der PySide-Studiensitzung. Und ein Hinweis zur testgetriebenen Entwicklung mit PySide und Pytest.

image.png

Entwicklungsumgebung

Windows 10 Python 3.7.7 Pytest

Beispieldatei

GitHub

Erstwartung

Verzeichnis- und Dateivorbereitung

Verzeichnis


root
  |- sample
  |    |- __init__.py
  |    |- gui.py
  |- tests
  |    |- __init__.py
  |    |- conftest.py
  |    |- unit
  |        |- test_gui.py
  |- requirments.txt

Die Quelle des Tools hier, gui.py, ist wie folgt.

sample/gui.py


import sys
from PySide2 import QtCore
from PySide2 import QtWidgets


class SampleDialog(QtWidgets.QDialog):

    def __init__(self, *args):
        super(SampleDialog, self).__init__(*args)
        
        self.number = 0

        self.setWindowTitle('Hello, World!')
        self.resize(300, 200)

        layout = QtWidgets.QVBoxLayout()

        self.label = QtWidgets.QLabel(str(self.number))

        layout.addWidget(self.label)

        self.button = QtWidgets.QPushButton('Add Count')
        self.button.clicked.connect(self.add_count)
        self.button.setMinimumSize(200, 100)

        layout.addWidget(self.button)

        self.setLayout(layout)
        self.resize(200, 100)


    def add_count(self):
        self.number += 2
        self.label.setText(str(self.number))


def main():
    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)
    gui = SampleDialog()
    gui.show()
    
    app.exec_()
    

if __name__ == '__main__':
    main()
    

Das Erscheinungsbild bei der Ausführung ist wie folgt. image.png

Schreiben Sie die erforderlichen Module in die Datei resources.txt

PySide2
Pytest

Erstellen Sie eine venv-Umgebung

  1. Wechseln Sie in das Stammverzeichnis
  2. python -m venv .venv
  3. Aktivieren Sie die venv-Umgebung: .venv \ Script \ Activate.bat
  4. pip install -r requirements.txt

Verbinden Sie den Pfad mit conftest.py mit dem Modul

tests/conftest.py


import os
import sys

sys.path.append(os.path.dirname(os.path.abspath(__file__)))

Laut Pytest-Beamten wird empfohlen, die Installation mit "pip install -e" mithilfe von setup.py (https://docs.pytest.org/en/latest/goodpractices.html) durchzuführen Abhängig von der jeweiligen Umgebung (in meinem Fall der Tool-Release-Umgebung des Techcnial Artist-Teams (einschließlich DCC-Tools)) ist es möglicherweise nicht immer möglich, eine Pip-Umgebung bereitzustellen.

In einem solchen Fall möchten Sie möglicherweise keine zusätzliche Verzeichnisstruktur verwenden. Verwenden Sie daher conftest.py und legen Sie den Pfad zum Stammverzeichnis fest, wenn Sie Pytest ausführen.

Natürlich ist es im Fall einer Verteilungsumgebung, die "pip install" voraussetzt, besser, setup.py unter root zu platzieren, damit "pip intall -e." Durchgeführt werden kann, damit "pip install" ausgeführt werden kann.

Wenn Sie ein Modul haben, das Sie für ein externes Tool wie Maya oder eine interne Bibliothek benötigen, sollten Sie den Pfad hier durchgehen.

Implementierung von Testcode

Testdatei in Pytest

Im Moment sind die folgenden grundlegenden Verhaltensweisen zu beachten. (Eigentlich gibt es noch mehr, siehe bitte das Dokument)

Schreiben Sie einen Test

tests/unit/test_gui.py


import sys

from PySide2 import QtCore
from PySide2 import QtWidgets
from PySide2 import QtTest


def test_add_count():
    from sample import gui

    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)
    gui = gui.SampleDialog()
    gui.show()

    QtTest.QTest.mouseClick(gui.button, QtCore.Qt.LeftButton)
    n1 = gui.number

    QtTest.QTest.mouseClick(gui.button, QtCore.Qt.LeftButton)
    n2 = gui.number
    assert abs(n2 - n1) == 1

Verwenden Sie QtTest

Hier kommt QtTest, das PySide als Modul zum Testen bereitstellt.

Der Benutzer erkennt, dass "durch Klicken auf die Schaltfläche" die Zahl auf dem Etikett um 1 erhöht wird. Um dieses Verhalten zu korrigieren, wird "durch Klicken auf die Schaltfläche" im Test simuliert. Muss getan werden. Hier bietet QtTest eine Funktion zur Simulation seines Betriebs mithilfe von "QtTest.QTest.mouseClick ()".

Mit anderen Worten, im obigen test_add_count führt QtTest Folgendes aus:

  1. Im ersten QtTest.QTest.mousClicke () klicken Sie mit der linken Maustaste auf die GUI-Schaltfläche.
  2. Speichern Sie den Wert der Nummernklassenvariablen zu diesem Zeitpunkt als n1
  3. Im folgenden QtTest.QTest.mousClicke () klicken Sie mit der linken Maustaste auf die GUI-Schaltfläche.
  4. Speichern Sie den Wert der Zahlenklassenvariablen beim zweiten Klicken als n2.
  5. Vergleichen Sie mit assert die beiden gespeicherten Werte und stellen Sie sicher, dass die Differenz 1 beträgt.

Auf diese Weise können Sie sicherstellen, dass die Änderungen, die Sie beim Klicken auf die Schaltfläche ** vornehmen, korrekt sind, und zwar mit einer einzigen Erhöhung der Anzahl **.

Führen Sie den Testbefehl aus

Führen Sie einfach den Befehl aus, um den Test vorerst im Stammverzeichnis auszuführen.

pytest .

Dann wird das folgende Ergebnis erhalten.

======================================= test session starts ========================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: D:\Develop\Python\_learn\test_pytest_pyside
collected 1 item

tests\unit\test_gui.py F                                                                      [100%]

============================================= FAILURES =============================================
__________________________________________ test_add_count __________________________________________

    def test_add_count():
        from sample import gui

        app = QtWidgets.QApplication.instance()
        if app is None:
            app = QtWidgets.QApplication(sys.argv)
        gui = gui.SampleDialog()
        gui.show()

        QtTest.QTest.mouseClick(gui.button, QtCore.Qt.LeftButton)
        n1 = gui.number

        QtTest.QTest.mouseClick(gui.button, QtCore.Qt.LeftButton)
        n2 = gui.number
>       assert abs(n2 - n1) == 1
E       assert 2 == 1
E        +  where 2 = abs((4 - 2))

tests\unit\test_gui.py:22: AssertionError
===================================== short test summary info ======================================
FAILED tests/unit/test_gui.py::test_add_count - assert 2 == 1
======================================== 1 failed in 0.67s =========================================

Um dies zu erklären, Wie Sie dem Code im Test entnehmen können, können wir sehen, dass add_count die Absicht des Entwicklers hat **, dass die Differenz zwischen den Werten des ersten und des nächsten Laufs 1 beträgt. Wenn Sie sich jedoch den Quellcode ansehen, heißt dort "self.number + = 2", ** entgegen der Absicht des Entwicklers **, der Unterschied im Ergebnis der ausgeführten Verarbeitung "durch Klicken auf die Schaltfläche". Es ist ersichtlich, dass das Ergebnis von 2 erhalten wurde.

Wenn Sie dies nun in "self.number + = 1" ändern und auf "um 1 erhöhen (dh der Unterschied, der immer zunimmt, ist 1)" setzen, erhalten Sie das folgende Ergebnis, wenn Sie "pytest" ausführen.

======================================= test session starts ========================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: D:\Develop\Python\_learn\test_pytest_pyside
collected 1 item

tests\unit\test_gui.py .                                                                      [100%]

======================================== 1 passed in 0.70s =========================================

Auf diese Weise wurde das Ergebnis des erfolgreichen Tests erhalten.

Zusammenfassung

Wie oben erwähnt, kann Pytest den Testcode automatisch abrufen oder conftest.py verwenden, um die Umgebungseinstellungen vorzubereiten, die Sie im Voraus annehmen möchten, sodass verschiedene exklusive Umgebungen automatisch mit weniger Code erstellt werden können. Sie können mit bauen. PySide hat im Voraus eine Funktion namens QtTest, und Sie können sehen, dass Sie damit das Verhalten von Gui simulieren können.

Wenn Sie genau hinschauen, hat Pytest viel mehr Funktionen und QtTest hat auch viele Funktionen. Ich hoffe, Sie können durch diesen Start verschiedene Tests implementieren.

Recommended Posts

Testgetriebenes Entwicklungsstart mit PySide & Pytest
Testgetriebene Entwicklung mit Django Teil 3
Testgetriebene Entwicklung mit Django Teil 6
Testgetriebene Entwicklung mit Django Teil 2
Testgetriebene Entwicklung mit Django Teil 1
Testgetriebene Entwicklung mit Django Teil 5
Testen Sie den Kolben mit einem Pytest
Testen Sie die Standardausgabe mit Pytest
[Test Driven Development (TDD)] Kapitel 21 Zusammenfassung
Kontrollieren von Testwiederholungen mit Luigi + pytest
Primzahlbeurteilung mit Python
Mit Codetest stärken ⑦
Mit Codetest stärken ⑨
Verwenden Sie Mock mit Pytest
Mit Codetest stärken ⑤
Mit Codetest stärken ④
Primzahlbeurteilung mit Python
Mit Codetest stärken ②
Mit Codetest stärken ①
Mit Codetest stärken ⑧
Mit Codetest stärken ⑨
Tutorial für die testgetriebene Entwicklung (TDD) mit Flask-2-Dekorateuren
Tutorial für die testgetriebene Entwicklung (TDD) mit Flask-1 Test Client Edition