Course
Wie man Pytest für Unit-Tests verwendet
Testen ist ein wichtiges Thema in der Softwareentwicklung. Bevor ein Softwareprodukt in die Hände eines Endnutzers gelangt, hat es wahrscheinlich mehrere Tests durchlaufen, z. B. Integrationstests, Systemtests und Akzeptanztests. Die Idee hinter diesen intensiven Tests ist es, sicherzustellen, dass die Anwendung so funktioniert, wie es die Endnutzer erwarten. Dieser Ansatz für das Testen ist als verhaltensorientierte Entwicklung (BDD) bekannt.
In letzter Zeit ist das Interesse an testgetriebener Entwicklung (TDD) unter Entwicklern stark gestiegen. In die Tiefe zu gehen, würde den Rahmen dieses Artikels sprengen, aber die Grundidee ist, dass der traditionelle Prozess von Entwicklung und Testen umgekehrt wird - du schreibst zuerst deine Unit-Tests und implementierst dann Codeänderungen, bis die Tests erfolgreich sind.
In diesem Artikel werden wir uns auf Unit-Tests konzentrieren und insbesondere darauf, wie man sie mit dem beliebten Python-Testframework Pytest durchführt.
Was sind Einheitstests?
Unit-Tests sind eine Form von automatisierten Tests - das bedeutet einfach, dass der Testplan von einem Skript und nicht manuell von einem Menschen ausgeführt wird. Sie dienen als erste Stufe des Softwaretests und werden in der Regel in Form von Funktionen geschrieben, die das Verhalten verschiedener Funktionalitäten innerhalb eines Softwareprogramms überprüfen.
Die Ebenen des Softwaretestens
Die Idee hinter diesen Tests ist, dass Entwickler die kleinste Codeeinheit isolieren können, die logisch sinnvoll ist, und testen, ob sie sich wie erwartet verhält. Mit anderen Worten: Unit-Tests überprüfen, ob die einzelnen Komponenten eines Softwareprogramms so funktionieren, wie die Entwickler es beabsichtigt haben.
Idealerweise sollten diese Tests ziemlich klein sein - je kleiner, desto besser. Ein Grund für das Erstellen kleinerer Tests ist, dass der Test effizienter ist, da der Testcode durch das Testen kleinerer Einheiten viel schneller ausgeführt werden kann. Ein weiterer Grund für das Testen kleinerer Komponenten ist, dass du dadurch einen besseren Einblick in das Verhalten des granularen Codes beim Zusammenführen bekommst.
Warum brauchen wir Unit-Tests?
Die allgemeine Begründung, warum es wichtig ist, Unit-Tests durchzuführen, ist, dass Entwickler/innen sicherstellen müssen, dass der von ihnen geschriebene Code den Qualitätsstandards entspricht, bevor er in die Produktionsumgebung gelangen kann. Es gibt jedoch noch weitere Faktoren, die dazu beitragen, dass Einheitstests notwendig sind. Lass uns einige dieser Gründe näher betrachten.
Schont Ressourcen
Die Durchführung von Unit-Tests hilft Entwicklern, Codefehler während der Softwareerstellung zu erkennen und verhindert, dass sie in den weiteren Entwicklungszyklus übergehen. Dadurch werden Ressourcen geschont, da die Entwickler nicht die Kosten für die Behebung von Fehlern zu einem späteren Zeitpunkt in der Entwicklung tragen müssen - das bedeutet auch, dass die Endnutzer seltener mit fehlerhaftem Code konfrontiert werden.
Extra Dokumentation
Ein weiterer guter Grund für die Durchführung von Unit-Tests ist, dass sie als zusätzliche Ebene der lebendigen Dokumentation für dein Softwareprodukt dienen. Entwickler können sich einfach auf die Unit-Tests beziehen, um ein ganzheitliches Verständnis des Gesamtsystems zu erhalten, da sie detailliert beschreiben, wie sich die kleineren Komponenten verhalten sollten.
Selbstvertrauen stärken
Es ist sehr einfach, subtile Fehler in deinem Code zu machen, während du eine Funktion erstellst. Die meisten Entwicklerinnen und Entwickler sind sich jedoch einig, dass es viel besser ist, die Sollbruchstellen in einer Codebasis zu identifizieren, bevor sie in die Produktionsumgebung eingesetzt wird: Unit-Tests bieten Entwicklern diese Möglichkeit.
Man kann mit Fug und Recht behaupten, dass "Code, der mit Unit-Tests abgedeckt ist, als zuverlässiger angesehen werden kann als Code, der nicht abgedeckt ist." Zukünftige Fehler im Code können viel schneller entdeckt werden als Code ohne Testabdeckung, was Zeit und Geld spart. Die Entwickler profitieren auch von der zusätzlichen Dokumentation, damit sie die Codebasis schneller verstehen können. Außerdem haben sie die Gewissheit, dass ein Fehler in ihrem Code von den Unit-Tests und nicht von einem Endbenutzer erkannt wird.
Python Test-Frameworks
Python hat im Laufe der Jahre enorm an Popularität gewonnen. Mit dem Wachstum von Python ist auch die Zahl der Test-Frameworks gestiegen, so dass eine Fülle von Tools zur Verfügung steht, mit denen du deinen Python-Code testen kannst. Es würde den Rahmen dieses Artikels sprengen, auf jedes einzelne Tool einzugehen, aber wir werden einige der gängigsten Python-Test-Frameworks vorstellen.
unittest
Unittest ist ein eingebautes Python-Framework für Unit-Tests. Es wurde von einem Unit-Testing-Framework namens JUnit aus der Programmiersprache Java inspiriert. Da es bereits mit der Sprache Python ausgeliefert wird, müssen keine zusätzlichen Module installiert werden, und die meisten Entwickler nutzen es, um mit dem Testen zu beginnen.
Pytest
Pytest ist wahrscheinlich das am weitesten verbreitete Python-Testframework überhaupt - das bedeutet, dass es eine große Community hat, die dich unterstützt, wenn du nicht weiterkommst. Es ist ein Open-Source-Framework, das es Entwicklern ermöglicht, einfache, kompakte Testsuiten zu schreiben und dabei Unit-Tests, funktionale Tests und API-Tests zu unterstützen.
doctest
Das Doctest-Framework vereint zwei Kernkomponenten der Softwareentwicklung: Dokumentation und Testen. Diese Funktion stellt sicher, dass alle Softwareprogramme gründlich dokumentiert und getestet werden, um sicherzustellen, dass sie ordnungsgemäß funktionieren. doctest wird mit der Standardbibliothek von Python geliefert und ist ziemlich einfach zu erlernen.
nose2
Nose2, der Nachfolger des Nose-Regiments, ist im Wesentlichen ein Unittest mit Plugins. nose2 wird oft als "erweiterte Unit-Tests" oder "Unit-Tests mit einem Plugin" bezeichnet, da es eng mit dem in Python integrierten Unit-Testing-Framework verbunden ist. Da es praktisch eine Erweiterung des Unittest-Frameworks ist, ist nose2 für diejenigen, die mit Unittest vertraut sind, unglaublich einfach zu übernehmen.
Bezeuge
Testify, ein Python-Framework für Unit-, Integrations- und Systemtests, ist allgemein als das Framework bekannt, das Unittest und Nose ersetzen soll. Das Framework ist vollgepackt mit umfangreichen Plugins und hat eine recht einfache Lernkurve, wenn du bereits mit Unittest vertraut bist.
Hypothese
Hypothesis ermöglicht es Entwicklern, Unit-Tests zu erstellen, die einfacher zu schreiben und leistungsfähig sind, wenn sie ausgeführt werden. Da das Framework zur Unterstützung von Data-Science-Projekten entwickelt wurde, hilft es dir bei der Erstellung deiner Tests, Randfälle zu finden, die nicht so offensichtlich sind, indem es Beispiele für Eingaben generiert, die mit bestimmten von dir definierten Eigenschaften übereinstimmen.
Für unser Tutorial werden wir pytest verwenden. Im nächsten Abschnitt erfährst du, warum du dich für Pytest und nicht für die anderen von uns aufgeführten Anbieter entscheiden solltest.
Warum Pytest verwenden?
Abgesehen von der großen unterstützenden Community hat pytest mehrere Faktoren, die es zu einem der besten Tools für die Durchführung deiner automatisierten Testsuite in Python machen. Die Philosophie und die Funktionen von Pytest zielen darauf ab, das Testen von Software zu einer besseren Erfahrung für Entwickler zu machen. Die Macher von Pytest haben dieses Ziel unter anderem dadurch erreicht, dass sie die Menge an Code, die für die Ausführung gängiger Aufgaben erforderlich ist, deutlich reduziert haben und es möglich machen, erweiterte Aufgaben mit umfangreichen Befehlen und Plug-ins auszuführen.
Es gibt noch weitere Gründe, Pytest zu verwenden:
Leicht zu lernen
Pytest ist extrem einfach zu erlernen: Wenn du verstehst, wie das Schlüsselwort assert in Python funktioniert, bist du schon auf dem besten Weg, das Framework zu beherrschen. Tests mit pytest sind Python-Funktionen mit vorangestelltem "test_" oder "_test" am Funktionsnamen - du kannst aber auch eine Klasse verwenden, um mehrere Tests zu gruppieren. Insgesamt ist die Lernkurve für pytest viel flacher als die von Unittest, da du keine neuen Konstrukte lernen musst.
Filterung testen
Du möchtest vielleicht nicht alle deine Tests bei jeder Ausführung durchführen - das kann der Fall sein, wenn deine Testsuite wächst. Manchmal möchtest du vielleicht ein paar Tests für eine neue Funktion isolieren, um während der Entwicklung schnelles Feedback zu erhalten, und dann die gesamte Suite ausführen, sobald du sicher bist, dass alles wie geplant funktioniert. Pytest bietet drei Möglichkeiten, wie du Tests isolieren kannst: 1) die namensbasierte Filterung, die pytest anweist, nur die Tests auszuführen, deren Namen mit dem angegebenen Muster übereinstimmen 2) das Verzeichnis-Scoping, eine Standardeinstellung, die pytest anweist, nur Tests auszuführen, die sich im oder unter dem aktuellen Verzeichnis befinden und 3) die Testkategorisierung, mit der du Kategorien für Tests definieren kannst, die pytest ein- oder ausschließen soll.
Parametrisierung
Pytest hat einen eingebauten Dekorator namens parametrize, der die Parametrisierung von Argumenten für eine Testfunktion ermöglicht. Wenn die Funktionen, die du testest, Daten verarbeiten oder eine generische Transformation durchführen, musst du also nicht mehrere ähnliche Tests schreiben. Wir werden später im Artikel mehr über die Parametrisierung erfahren.
Wir hören hier auf, aber die Liste der Gründe, warum pytest ein großartiges Werkzeug für deine automatisierte Testsuite ist, geht weiter.
Pytest vs. Unittest
Trotz all dieser Gründe, die wir oben genannt haben, kann man die Idee, pytest zu verwenden, immer noch anzweifeln, weil es sich um ein Framework eines Drittanbieters handelt - "wozu ein Framework installieren, wenn es bereits ein eingebautes gibt?" Das ist ein gutes Argument, aber um uns in diesem Streit den Rücken freizuhalten, geben wir dir ein paar Dinge zu bedenken.
Hinweis: Wenn du bereits von pytest überzeugt bist, kannst du den nächsten Abschnitt überspringen, in dem wir uns mit der Verwendung des Frameworks befassen.
Weniger Textbausteine
Bei Unittest müssen Entwickler Klassen erstellen, die vom TestCase-Modul abgeleitet sind, und dann die Testfälle als Methoden in der Klasse definieren.
"""
An example test case with unittest.
See: https://docs.python.org/3/library/unittest.html
"""
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
Bei Pytest hingegen musst du nur eine Funktion mit vorangestelltem "test_" definieren und die Assert-Bedingungen darin verwenden.
"""
An example test case with pytest.
See: https://docs.pytest.org/en/6.2.x/index.html
"""
# content of test_sample.py
def inc(x):
return x + 1
def test_answer():
assert inc(3) == 5
Beachte den Unterschied in der Menge des benötigten Codes; unittest hat eine beträchtliche Menge an Boilerplate-Code, der als Mindestanforderung für jeden Test dient, den du durchführen möchtest. Es ist also sehr wahrscheinlich, dass du denselben Code mehrmals schreiben musst. Pytest hingegen verfügt über umfangreiche integrierte Funktionen, die diesen Arbeitsablauf vereinfachen, indem sie die Menge an Code reduzieren, die zum Schreiben von Testfällen erforderlich ist.
Ausgabe
Die Ergebnisse, die die einzelnen Rahmenwerke liefern, sind sehr unterschiedlich. Hier ist ein Beispiel für die Ausführung eines Pytests:
"""
See: https://docs.pytest.org/en/6.2.x/index.html
"""
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-1.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 1 item
test_sample.py F [100%]
================================= FAILURES =================================
_______________________________ test_answer ________________________________
def test_answer():
> assert inc(3) == 5
E assert 4 == 5
E + where 4 = inc(3)
test_sample.py:6: AssertionError
========================= short test summary info ==========================
FAILED test_sample.py::test_answer - assert 4 == 5
============================ 1 failed in 0.12s =============================
Der obige Testfall ist fehlgeschlagen, aber beachte, wie detailliert die Aufschlüsselung des Fehlers ist. Das macht es Entwicklern leichter zu erkennen, wo die Fehler in ihrem Code sind, was bei der Fehlersuche sehr hilfreich ist. Als zusätzlichen Bonus gibt es auch einen Gesamtstatusbericht für die Testsuite, der uns die Anzahl der fehlgeschlagenen Tests und die Dauer des Tests anzeigt.
Schauen wir uns ein Beispiel für einen fehlgeschlagenen Testfall mit Unittest an.
import unittest
def square(n):
return n*n
def cube(n):
return n*n*n
class TestCase(unittest.TestCase):
def test_square(self):
self.asserEquals(square(4), 16)
def test_cube(self):
self.assertEquals(cube(4), 16)
Wenn wir das Skript ausführen, erhalten wir die folgende Ausgabe:
---------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (errors=1)
Die obige Ausgabe verrät uns, dass zwei Tests in 0,001s durchgeführt wurden und einer fehlgeschlagen ist, aber nicht viel mehr. Letztendlich liefert pytest viel informativeres Feedback, was bei der Fehlersuche sehr hilfreich ist.
Alles in allem sind sowohl pytest als auch unittest großartige Werkzeuge für automatisierte Tests in Python. Einige Python-Entwickler bevorzugen pytest aufgrund seiner Kompaktheit und Effizienz gegenüber seinen Pendants. Außerdem ist es extrem einfach zu übernehmen und es gibt verschiedene Funktionen, die du nutzen kannst, um eine effektive Testsuite zu erstellen.
Nun zum Hauptteil dieses Artikels. Wir haben besprochen, was Unit Testing ist und warum pytest ein großartiges Werkzeug für automatisierte Tests in Python ist. Schauen wir uns nun an, wie man das Tool benutzt.
Pytest-Anleitung
Schauen wir uns an, wie das Python-Testing-Framework funktioniert, über das wir gerade gesprochen haben.
Der erste Schritt ist die Installation des Pakets, die mit einem einfachen pip-Befehl durchgeführt werden kann.
Hinweis: Die Entwickler von pytest empfehlen dir, venv für die Entwicklung und pip für die Installation deiner Anwendung, der Abhängigkeiten und von pytest selbst zu verwenden.
pip install -U pytest
Als Nächstes überprüfst du mit folgendem Befehl, ob das Framework installiert wurde:
>>>> pytest --version
pytest 7.1.2
Alles ist installiert. Jetzt kannst du damit beginnen, einige Tests durchzuführen.
Einen einfachen Test erstellen
Mit Pytest ist es ganz einfach, einen Test zu erstellen. Um diese Funktion zu demonstrieren, haben wir ein Skript namens calcualte_age.py erstellt. Dieses Skript hat nur eine Funktion, get_age, die dafür verantwortlich ist, das Alter eines Benutzers anhand seines Geburtsdatums zu berechnen.
import datetime
def get_age(yyyy:int, mm:int, dd:int) -> int:
dob = datetime.date(yyyy, mm, dd)
today = datetime.date.today()
age = round((today - dob).days / 365.25)
return age
Pytest führt alle Python-Dateien aus, die den Namen test_ vorangestellt oder _test an den Namen des Skripts angehängt haben. Um genauer zu sein, folgt pytest den folgenden Konventionen für die Testfindung [Quelle: Dokumentation]:
- Wenn keine Argumente angegeben werden, beginnt die pytest-Sammlung in den Testpfaden, wenn diese konfiguriert sind: Die Testpfade sind eine Liste von Verzeichnissen, die pytest durchsucht, wenn keine bestimmten Verzeichnisse, Dateien oder Test-IDs angegeben werden.
- Pytest würde dann in Verzeichnisse rekursieren, es sei denn, du hast ihm gesagt, dass er das nicht tun soll, indem du norecursedirs gesetzt hast; Er sucht nach Dateien, die mit test_*.py beginnen oder in *_test.py enden
- In diesen Dateien würde pytest Testaufgaben in der folgenden Reihenfolge sammeln:
- Vorangestellte Testfunktionen oder Methoden außerhalb der Klasse
- Vorangestellte Testfunktionen oder -methoden innerhalb von Testklassen mit vorangestelltem Test, die keine __init__-Methode haben.
Wir haben keine Argumente angegeben, aber wir haben ein weiteres Skript im selben Verzeichnis mit dem Namen test_calculate_age.py erstellt: So wird der Test entdeckt, wenn die Verzeichnisse wieder aufgerufen werden. In diesem Skript haben wir einen einzigen Test, test_get_age, um zu überprüfen, ob unsere Funktion richtig funktioniert.
Hinweis: Das ist eine gute Idee, wenn du mehrere Funktionstests hast oder den Testcode und den Anwendungscode aus einem anderen Grund getrennt halten willst.
from calculate_age import get_age
def test_get_age():
# Given.
yyyy, mm, dd = map(int, "1996/07/11".split(""))
# When.
age = get_age(yyyy, mm, dd)
# Then.
assert age == 26
Um den Test durchzuführen, führe den folgenden Befehl in der Eingabeaufforderung aus:
py -m pytest
Die Ausgabe eines erfolgreichen pytest-Laufs.
Und das ist alles.
Aber was ist, wenn wir Daten bereitstellen müssen, damit unsere Tests erfolgreich sind? Sag hallo zu pytest fixtures.
Pytest Fixtures
Die unschätzbare Funktion der Fixtures von Pytest ermöglicht es Entwicklern, Daten in die Tests einzuspeisen. Sie sind im Wesentlichen Funktionen, die vor jeder Testfunktion ausgeführt werden, um den Status unserer Tests zu verwalten. Wenn wir zum Beispiel mehrere Tests haben, die alle dieselben Daten verwenden, können wir eine Fixture verwenden, um die wiederholten Daten mit einer einzigen Funktion zu ziehen.
import pytest
from sklearn.model_selection import train_test_split
from fraud_detection_model.config.core import config
from fraud_detection_model.processing.data_manager import (
load_datasets,
load_interim_data
)
@pytest.fixture(scope="session")
def pipeline_inputs():
# import the training dataset
dataset = load_datasets(transaction=config.app_config.train_transaction, identity=config.app_config.train_identity, )
# divide train and test
X_train, X_test, y_train, y_test = train_test_split(
dataset[config.model_config.all_features], dataset[config.model_config.target],
test_size=config.model_config.test_size,
stratify=dataset[config.model_config.target],
random_state=config.model_config.random_state)
return X_train, X_test, y_train, y_test
Im obigen Code haben wir eine Fixture mit dem pytest.fixture Dekorator erstellt. Beachte, dass der Scope auf "session" gesetzt ist, um pytest mitzuteilen, dass die Fixture am Ende der Testsitzung zerstört werden soll.
Hinweis: Unsere Fixtures werden in conftest.py gespeichert.
Der Code verwendet eine Funktion, die wir aus einem anderen Modul importiert haben, um zwei csv-Dateien in den Speicher zu laden und sie zu einem einzigen Datensatz zusammenzuführen. Danach wird der Datensatz in eine Trainings- und eine Testmenge aufgeteilt und von der Funktion zurückgegeben.
Um dieses Fixture in unseren Tests zu verwenden, müssen wir es als Parameter an unsere Testfunktion übergeben. In diesem Beispiel verwendest du unser Fixture in unserem test_pipeline.py Testskript wie folgt:
import pandas as pd
from pandas.api.types import is_categorical_dtype, is_object_dtype
from fraud_detection_model import pipeline
from fraud_detection_model.config.core import configfrom fraud_detection_model.processing.validation import validate_inputs
def test_pipeline_most_frequent_imputer(pipeline_inputs):
# Given
X_train, _, _, _ = pipeline_inputs assert all( x in X_train.loc[:, X_train.isnull().any()].columns for x in config.model_config.impute_most_freq_cols )
# When
X_transformed = pipeline.fraud_detection_pipe[:1].fit_transform(X_train[:50])
# Then
assert all( x not in X_transformed.loc[:, X_transformed.isnull().any()].columns for x in config.model_config.impute_most_freq_cols )
def test_pipeline_aggregate_categorical(pipeline_inputs):
# Given
X_train, _, _, _ = pipeline_inputs
assert X_train["R_emaildomain"].nunique() == 60
# When
X_transformed = pipeline.fraud_detection_pipe[:2].fit_transform(X_train[:50])
# Then
assert X_transformed["R_emaildomain"].nunique() == 2
Mach dir nicht zu viele Gedanken darüber, was der Code macht. Das Wichtigste, was wir hervorheben wollen, ist, dass wir die Notwendigkeit, redundanten Code zu schreiben, deutlich reduziert haben, weil wir eine Fixture erstellt haben, die wir als Parameter übergeben, um Daten in unsere Tests zu ziehen.
Es gibt jedoch Situationen, in denen die Halterungen zu viel des Guten sind. Wenn zum Beispiel die Daten, die in deine Tests gezogen werden, in jedem Testfall erneut verarbeitet werden müssen - das ist praktisch das Äquivalent dazu, deinen Code mit mehreren einfachen Objekten zu überladen. Fixtures werden in deiner Testsuite wahrscheinlich eine zentrale Rolle spielen, aber um zu erkennen, wann du sie verwenden oder vermeiden solltest, brauchst du viel Übung und Überlegung.
Pytest parametrisieren
Fixtures sind toll, wenn du mehrere Tests mit denselben Eingängen durchführst. Was ist, wenn du eine einzelne Funktion mit leichten Variationen der Eingaben testen willst? Eine Lösung ist, mehrere verschiedene Tests mit unterschiedlichen Fällen zu schreiben.
def test_eval_addition():
assert eval("2 + 2") == 4
def test_eval_subtraction():
assert eval("2 - 2") == 0
def test_eval_multiplication():
assert eval("2 * 2") == 4
def test_eval_division():
assert eval("2 / 2") == 1.0
Diese Lösung funktioniert zwar, ist aber nicht die effizienteste: Zunächst einmal gibt es eine Menge Standardcode. Eine bessere Lösung ist die Verwendung des Dekorators pytest.mark.parametrize(), um die Parametrisierung von Argumenten für eine Testfunktion zu ermöglichen. So können wir eine einzige Testspezifikation definieren, und pytest testet dann die verschiedenen Parameter, die wir für uns angeben.
So würden wir den obigen Code umschreiben, wenn wir die Parametrisierung verwenden würden:
import pytest
@pytest.mark.parametrize("test_input, expected_output", [("2+2", 4), ("2-2", 0), ("2*2", 4), ("2/2", 1.0)])
def test_eval(test_input, expected_output):
assert eval(test_input) == expected_output
Der @parametrize-Dekorator definiert vier verschiedene Testeingaben und erwartete Werte, die die Funktion test_eval ausführen soll - das bedeutet, dass die Funktion viermal nacheinander mit jedem Wert ausgeführt wird.
Die Ausgabe von pytest für parametrize test
In diesem Artikel haben wir die folgenden Themen behandelt:
- was Einheitstests sind
- warum wir Unit-Tests brauchen
- verschiedene Test-Frameworks in Python
- Warum pytest so nützlich ist
- wie man pytest und zwei seiner wichtigsten Funktionen (Fixtures und Parametrisierung) verwendet
Du weißt jetzt genug, um deinen eigenen Test mit dem pytest Framework zu schreiben. Wir empfehlen dir dringend, das zu tun, damit du alles, was du in diesem Artikel gelernt hast, auch behältst. Du solltest dir auch unseren Kurs über Unit-Tests für Data Science in Python ansehen, um eine ausführlichere Erklärung mit Beispielen zu erhalten.
Kurse für Python
Course
Intermediate Python
Course
Introduction to Data Science in Python
Der Blog