Scheinfunktion in Python

Migel Hewage Nimesha 15 Februar 2024
  1. Einrichten und Installieren von Pytest Mock in Python
  2. Mock eine Funktion in Python
  3. Abschluss
Scheinfunktion in Python

Die Funktion unittest.mock oder Mock ist eine Bibliothek zum Testen in Python, mit der Sie Komponenten Ihres zu testenden Systems durch Mock-Objekte ersetzen und Aussagen darüber treffen können, wie die Teile verwendet wurden.

Die unittest.mock gibt eine Mock-Kernklasse, wodurch die Notwendigkeit beseitigt wird, eine Vielzahl von Stubs in Ihrer gesamten Testsuite zu erstellen.

Nach dem Ausführen eines Prozesses können Sie bestätigen, welche Methoden oder Attribute verwendet wurden und mit welchen Argumenten sie aufgerufen wurden. Sie können auch die Rückgabewerte angeben und die benötigten Attribute auf die übliche Weise setzen.

Darüber hinaus bietet Mock einen patch()-Dekorator, der das Patching-Modul und die Attribute auf Klassenebene innerhalb des Testumfangs handhaben kann, zusammen mit einem Helfer sentinel zum Erstellen eindeutiger Objekte.

Mock wurde für die Verwendung mit unittest erstellt und basiert auf dem action-to-assertion-Muster anstelle von record-to-replay, das in den meisten Mocking-Frameworks verwendet wird. Es gibt eine Rückportierung von unittest.mock für frühere Versionen von Python.

Einrichten und Installieren von Pytest Mock in Python

Im Gegensatz zu unittest ist pytest kein eingebautes Python-Paket und muss installiert werden. Dies kann durch Eingabe des folgenden Befehls im Terminal installiert werden.

pip install pytest

Als Hinweis gelten die Best Practices für unittest auch für pytest, so dass:

  1. Ein tests/-Verzeichnis ist erforderlich, um alle Unit-Tests zu enthalten.
  2. Dateinamen müssen immer mit tests_ beginnen.
  3. Funktionsnamen müssen immer mit the test beginnen.

Damit der Prüfer die durchgeführten Unit-Tests finden kann, müssen die Benennungsstandards eingehalten werden.

Die Installation von pytest-mock ist erforderlich, bevor Sie es verwenden können. So installieren Sie es mit pip:

pip install pytest-mock

Dies ist ein Plugin für Pytest. Daher wird Pytest installiert, falls Sie dies noch nicht getan haben.

Mock eine Funktion in Python

Erstellen Sie zunächst eine einfache Funktion get_os(), die uns mitteilt, ob wir Windows oder Linux als Betriebssystem verwenden.

Erstellen Sie eine Datei namens app.py wie folgt:

from time import sleep


def isWindows():
    # This sleep can be some complex operation
    sleep(5)
    return True


def get_os():
    return "Windows is the current OS" if isWindows() else "Linux is the current OS"

Diese Funktion verwendet die Funktion isWindows, um festzustellen, ob das aktuelle Betriebssystem Windows ist oder nicht. Unter der Annahme, dass diese isWindows-Funktion ziemlich komplex ist und einige Sekunden zum Ausführen benötigt, können wir hier diese langsame Funktion simulieren, indem wir das Programm bei jedem Aufruf für 5 Sekunden in den Ruhezustand versetzen.

Folgendes wäre ein pytest für die Funktion get_os():

Erstellen Sie eine Datei namens test_app.py zu pytest:

from app import get_os


def test_get_os():
    assert get_os() == "Windows is the current OS"

Da get_os() eine langsamere Funktion isWindows aufruft, verläuft der Test langsam. Dies ist in der folgenden Ausgabe der Ausführung von pytest zu sehen.

Es dauerte 5,02 Sekunden und kann je nach aktueller Instanz variieren.

Scheinfunktion Python - Ausgabe 1

Komponententests müssen schnell sein, und wir sollten in der Lage sein, Hunderte von Tests in Sekundenschnelle durchzuführen. Die Testsuite wird durch einen einzelnen Test verlangsamt, der 5 Sekunden dauert, sodass das Anwenden von Mocking unser Leben einfacher macht.

Wenn wir die langsame Funktion patchen, können wir das Verhalten der Funktion get_os() überprüfen, ohne 5 Sekunden zu verweilen.

Lassen Sie uns diese Funktion mit pytest-mock verspotten.

Pytest-mock bietet eine Einrichtung namens mocker und eine feine Schnittstelle zusätzlich zu Pythons integrierten Mocking-Konstrukten. Sie können einen Mocker verwenden, indem Sie die Mock- und Patch-Funktionen daraus aufrufen und sie als Argumente an Ihre Testfunktion senden.

In einem Fall, in dem Sie möchten, dass die Funktion isWindows True zurückgibt, ohne auf diese wertvollen 5 Sekunden zu warten, können wir sie wie folgt patchen:

mocker.patch("app.isWindows", return_value=True)

Hier muss isWindows als app.isWindows bezeichnet werden, da es sich um die Funktion im app-Modul handelt. Wenn wir nur isWindows patchen, wird es versuchen, eine Funktion namens isWindows in der Datei test_app zu patchen, die nicht existiert.

Das Format ist immer <Modulname>.<Funktionsname>, und es ist wichtig zu wissen, wie man richtig mockt.

Im Folgenden wird die geänderte Testfunktion nach dem Patch beschrieben:

from app import get_os

# using'mocker' fixture provided by pytest-mock


def test_get_os(mocker):
    # mocking the slow-going function and returning True always
    mocker.patch("app.isWindows", return_value=True)
    assert get_os() == "Windows is the current OS"

Dieser Test wird jetzt viel schneller beendet, wenn Sie ihn ausführen.

Scheinfunktion Python - Ausgabe 2

Wie Sie sehen können, dauerte der Test nur 0,02 Sekunden, also haben wir die langsame Funktion erfolgreich gepatcht und die Testsuite beschleunigt.

Ein weiterer Vorteil des Mockings besteht darin, dass Sie die Mock-Funktion dazu bringen können, alles zurückzugeben und sogar Fehler auszulösen, um zu testen, wie Ihr Code in diesen Szenarien verarbeitet wird.

Wenn Sie hier den Fall testen möchten, in dem isWindows False zurückgibt, schreiben Sie den folgenden Test:

from app import get_os


def test_os_isLinux(mocker):
    mocker.patch(
        "app.isWindows", return_value=False
    )  # set the return value to be False
    assert get_os() == "Linux is the current OS"

Die Mocks und Patches, die mit dem Mocker geliefert werden, sind alle funktionsbezogen, was bedeutet, dass sie nur mit dieser bestimmten Funktion verwendet werden können. Dadurch kommt es zu keinen Konflikten zwischen Patches für dieselbe Funktion in unterschiedlichen Tests.

Abschluss

Mocking ist die Praxis, die Anwendungskomponente, die Sie testen, durch ein Mock zu ersetzen, bei dem es sich um eine Dummy-Implementierung dieser Komponente handelt. Durch Mocking können wir Vorteile erzielen, wie z. B. eine erhöhte Geschwindigkeit, bei der schnellere Tests sehr vorteilhaft sind, das Vermeiden unerwünschter Nebenwirkungen während des Testens und so weiter.

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.

Verwandter Artikel - Python Mock