PyTest-Tutorial: Was ist PyTest? (mit Beispielen)

⚡ Intelligente Zusammenfassung

Pytest ist ein Python Ein Testframework, das Ihnen hilft, einfache und skalierbare Tests für Datenbanken, APIs und Benutzeroberflächen zu schreiben. Es unterstützt Fixtures, Parametrisierung, Marker, parallele Ausführungen und detaillierte Assertionsberichte – von einfachen Unit-Tests bis hin zu komplexen Funktionstests.

  • 🔘 Installation: Der Befehl `pip install pytest` fügt das Framework hinzu, und `py.test -h` bestätigt die Einrichtung durch Ausgabe der Hilfefunktion.
  • ☑️ Testfindung: Pytest sammelt automatisch Dateien mit dem Namen test_*.py oder *_test.py sowie Methoden, deren Namen mit test beginnen.
  • Behauptungen: Einfache Assert-Anweisungen geben bei einem Fehler eine eindeutige AssertionError-Meldung mit den verglichenen Werten aus.
  • 🧪 Spielpaarungen: Der @pytest.fixture-Dekorator stellt wiederverwendbare Setup-Daten bereit, die über eine conftest.py-Datei dateiübergreifend geteilt werden.
  • Selektive Läufe: Marker, der -k-Teilstringfilter und parametrisierte Ausführung gezielter Teilmengen oder des gleichen Tests über viele Eingaben hinweg.
  • 🤖 KI-Workflows: Machine-Learning-Teams verwenden pytest zur Validierung von Datenpipelines und Modellausgaben, und Copilot kann Testfälle entwerfen.

Pytest-Tutorial

Pytest ist eines der am weitesten verbreiteten Testframeworks in der Python Das Ökosystem sorgt für kurzen und lesbaren Testcode, erkennt Tests automatisch und entwickelt sich von einer ersten Assertion zu einer vollständigen Testsuite für Datenbanken, APIs und Benutzeroberflächen. Die folgenden Abschnitte erläutern Installation, Assertions, Fixtures, Marker, Parametrisierung und parallele Testläufe anhand praktischer Beispiele.

Was ist Pytest?

Pytest ist ein Testframework, mit dem Sie Testcode schreiben können. Python Pytest ist eine Programmiersprache, mit der sich einfache und skalierbare Testfälle für Datenbanken, APIs und sogar Benutzeroberflächen erstellen lassen. Pytest wird hauptsächlich für API-Tests verwendet und eignet sich sowohl für einfache Unit-Tests als auch für komplexe Funktionstests.

Warum Pytest verwenden?

Zu den Vorteilen von pytest gehören:

  • Der Einstieg ist dank der einfachen und übersichtlichen Syntax sehr leicht.
  • Kann Tests parallel ausführen.
  • Kann einen bestimmten Test oder eine Teilmenge der Tests ausführen.
  • Automatische Testerkennung.
  • Tests können übersprungen werden.
  • Open Source.

Wie installiert man Pytest?

Im Folgenden wird der Installationsprozess für pytest beschrieben:

Schritt 1) Sie können pytest mit dem folgenden Befehl installieren.

pip install pytest==2.9.1

Sobald die Installation abgeschlossen ist, können Sie dies mit dem folgenden Befehl bestätigen.

py.test -h

Dadurch wird die Hilfe angezeigt.

Installieren Sie pytest und sehen Sie sich die Hilfeausgabe an.

Erstes einfaches Pytest-Beispiel

Nun lernen Sie anhand eines einfachen pytest-Beispiels, wie man pytest verwendet.

Erstellen Sie einen Ordner namens „study_pytest“. In diesem Ordner werden die Testdateien erstellt. Navigieren Sie in der Kommandozeile zu diesem Ordner. Erstellen Sie dort eine Datei namens „test_sample1.py“.

Erstelle die erste einfache pytest-Testdatei

Füge den unten stehenden Code ein und speichere die Datei.

import pytest
def test_file1_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed"
def test_file1_method2():
	x=5
	y=6
	assert x+1 == y,"test failed" 

Führen Sie den Test mit dem unten stehenden Befehl aus.

py.test

Sie erhalten folgende Ausgabe.

test_sample1.py F.
============================================== FAILURES ========================================
____________________________________________ test_sample1 ______________________________________
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed"
E       AssertionError: test failed
E       assert 5 == 6
test_sample1.py:6: AssertionError

Ausgabe des fehlgeschlagenen Pytest-Tests

In der Datei test_sample1.py steht „F“ für einen Fehler und der Punkt (.) für einen Erfolg. Im Abschnitt „Fehler“ werden die fehlgeschlagenen Methoden und die entsprechende Fehlerzeile angezeigt. Hier bedeutet x==y, dass 5==6 fehlschlägt, was falsch ist.

Als Nächstes lernen Sie etwas über Assertions in pytest.

Assertions in Pytest

Pytest-Assertions sind Prüfungen, die entweder „True“ oder „False“ zurückgeben. Schlägt eine Assertion in einer Testmethode fehl, wird die Ausführung dieser Methode an dieser Stelle abgebrochen. Der restliche Code in dieser Testmethode wird nicht ausgeführt, und Pytest fährt mit der nächsten Testmethode fort.

Pytest-Assert-Beispiele:

assert "hello" == "Hai" is an assertion failure.
assert 4==4 is a successful assertion
assert True is a successful assertion
assert False is an assertion failure.

Folgendes berücksichtigen.

assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

Platzieren Sie diesen Code in test_file1_method1() anstelle der unten stehenden Assertion.

assert x == y,"test failed"

Wenn Sie den Test ausführen, wird der Fehler als angezeigt AssertionError: Test fehlgeschlagen x=5 y=6.

Wie Pytest die Testdateien und Testmethoden identifiziert

Standardmäßig erkennt pytest nur die Dateinamen, die mit einem bestimmten Präfix beginnen. Prüfung_ oder endend mit _Prüfung als die Testdateien. Wir können jedoch auch andere Dateinamen explizit angeben (wird später erläutert). Pytest erfordert, dass die Namen der Testmethoden mit einem Präfix beginnen. TestAlle anderen Methodennamen werden ignoriert, selbst wenn wir explizit die Ausführung dieser Methoden anfordern.

Hier einige Beispiele für gültige und ungültige pytest-Dateinamen.

test_login.py - valid
login_test.py - valid
testlogin.py -invalid
logintest.py -invalid

Hinweis: Ja, wir können pytest explizit anweisen, testlogin.py und logintest.py auszuwählen.

Hier finden Sie einige Beispiele für gültige und ungültige pytest-Testmethoden.

def test_file1_method1(): - valid
def testfile1_method1(): - valid
def file1_method1(): - invalid	

Hinweis: Auch wenn wir file1_method1() explizit erwähnen, wird pytest diese Methode nicht ausführen.

Führen Sie mehrere Tests aus einer bestimmten Datei und mehreren Dateien aus

Im Ordner study_pytest befindet sich aktuell die Datei test_sample1.py. Angenommen, es gibt mehrere Dateien, beispielsweise test_sample2.py und test_sample3.py. Um alle Tests aus allen Dateien im Ordner und seinen Unterordnern auszuführen, genügt der Befehl pytest.

py.test

Dadurch werden alle Dateinamen, die mit test_ beginnen, und alle Dateinamen, die mit _test enden, in diesem Ordner und den Unterordnern dieses Ordners ausgeführt.

Um Tests nur für eine bestimmte Datei auszuführen, können wir py.test verwenden. Die

py.test test_sample1.py

Führe eine Teilmenge des gesamten Tests mit Pytest aus

Manchmal möchten wir nicht die gesamte Testsuite ausführen. Pytest ermöglicht es uns, bestimmte Tests auszuführen. Dies ist auf zwei Arten möglich:

  • Grouping von Testnamen durch Teilzeichenkettenvergleich.
  • Grouping von Tests nach Prüfern.

Wir haben bereits die Datei test_sample1.py. Erstellen Sie eine Datei test_sample2.py und fügen Sie den unten stehenden Code ein.

def test_file2_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
def test_file2_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

Aktuell haben wir also Folgendes:

• test_sample1.py
• test_file1_method1()
• test_file1_method2()
• test_sample2.py
• test_file2_method1()
• test_file2_method2()

Option 1) Tests durch Teilstringvergleich ausführen

Um hier alle Tests auszuführen, die „method1“ im Namen enthalten, müssen wir den folgenden Befehl ausführen.

py.test -k method1 -v
-k <expression> is used to represent the substring to match
-v increases the verbosity

Die Ausführung von py.test -k method1 -v liefert folgendes Ergebnis.

test_sample2.py::test_file2_method1 FAILED
test_sample1.py::test_file1_method1 FAILED

============================================== FAILURES ==============================================
_________________________________________ test_file2_method1 _________________________________________
    def test_file2_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
test_sample2.py:5: AssertionError

_________________________________________ test_file1_method1 _________________________________________
    @pytest.mark.only
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
test_sample1.py:8: AssertionError

================================= 2 tests deselected by '-kmethod1' ==================================
=============================== 2 failed, 2 deselected in 0.02 seconds ===============================

Hier können Sie gegen Ende sehen, 2 Tests von '-kmethod1' abgewählt, welche test_file1_method2 und test_file2_method2 sind.

Probieren Sie verschiedene Kombinationen wie die folgenden aus.

py.test -k method -v - will run all the four methods
py.test -k methods -v – will not run any test as there is no test name matches the substring 'methods'

Option 2) Führen Sie Tests nach Markern durch

Pytest ermöglicht es uns, mithilfe von Pytest-Markern (@pytest.mark) verschiedene Attribute für Testmethoden festzulegen. Um Marker in Testdateien zu verwenden, müssen wir Pytest in die Testdateien importieren. Hier weisen wir den Testmethoden unterschiedliche Markernamen zu und führen basierend auf diesen Namen spezifische Tests aus. Die Marker können wir wie folgt für jeden Testnamen definieren.

@pytest.mark.<name>.			

Wir definieren die Marker set1 und set2 in den Testmethoden und führen den Test anhand dieser Markernamen aus. Aktualisieren Sie die Testdateien mit dem folgenden Code.

test_sample1.py

import pytest
@pytest.mark.set1
def test_file1_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

@pytest.mark.set2
def test_file1_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

test_sample2.py

import pytest
@pytest.mark.set1
def test_file2_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

@pytest.mark.set1
def test_file2_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

Wir können den markierten Test mit dem folgenden Befehl ausführen.

py.test -m <name>
-m <name> mentions the marker name

Führen Sie `py.test -m set1` aus. Dadurch werden die Methoden `test_file1_method1`, `test_file2_method1` und `test_file2_method2` ausgeführt. Mit `py.test -m set2` wird `test_file1_method2` ausgeführt.

Tests parallel mit Pytest ausführen

Eine Testsuite besteht üblicherweise aus mehreren Testdateien und Hunderten von Testmethoden, deren Ausführung viel Zeit in Anspruch nimmt. Pytest ermöglicht die parallele Ausführung von Tests. Dazu muss zunächst pytest-xdist mit dem folgenden Befehl installiert werden.

pip install pytest-xdist

Führe Tests parallel mit pytest-xdist aus

Sie können die Tests jetzt mit folgendem Befehl ausführen.

py.test -n 4

Hier, -n Die Tests werden mithilfe mehrerer Worker ausgeführt. Im obigen Befehl werden vier Worker die Tests ausführen.

Pytest-Geräte

Fixtures werden verwendet, wenn wir vor jeder Testmethode Code ausführen möchten. Anstatt also denselben Code in jedem Test zu wiederholen, definieren wir Fixtures. Normalerweise werden Fixtures verwendet, um Datenbankverbindungen zu initialisieren und die Basisadresse zu übergeben. URLund so weiter. Eine Methode wird als pytest-Fixture gekennzeichnet, indem sie mit Folgendem markiert wird.

@pytest.fixture

Eine Testmethode kann eine pytest-Fixture verwenden, indem sie die Fixture als Eingabeparameter angibt. Erstellen Sie eine neue Datei test_basic_fixture.py mit folgendem Code.

import pytest
@pytest.fixture
def supply_AA_BB_CC():
	aa=25
	bb =35
	cc=45
	return [aa,bb,cc]

def test_comparewithAA(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

Hier:

  • Wir haben eine Fixture namens supply_AA_BB_CC. Diese Methode gibt eine Liste mit drei Werten zurück.
  • Wir haben drei Testmethoden, mit denen wir die Werte vergleichen.

Jede Testfunktion hat ein Eingabeargument, dessen Name mit einer verfügbaren Testumgebung übereinstimmt. Pytest ruft dann die entsprechende Methode der Testumgebung auf, und die zurückgegebenen Werte werden im Eingabeargument gespeichert, hier die Liste [25, 35, 45]. Die Listenelemente werden anschließend in den Testmethoden für den Vergleich verwendet. Führen Sie nun den Test aus und sehen Sie sich das Ergebnis an.

 py.test test_basic_fixture
test_basic_fixture.py::test_comparewithAA FAILED                                                                                                                                                                                       
test_basic_fixture.py::test_comparewithBB PASSED                                                                                                                                                                                       
test_basic_fixture.py::test_comparewithCC FAILED
                                                                                                                                                                                       
============================================== FAILURES ==============================================
_________________________________________ test_comparewithAA _________________________________________
supply_AA_BB_CC = [25, 35, 45]
    def test_comparewithAA(supply_AA_BB_CC):
    	zz=35
>   	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"
E    AssertionError: aa and zz comparison failed
E    assert 25 == 35
test_basic_fixture.py:10: AssertionError

_________________________________________ test_comparewithCC _________________________________________
supply_AA_BB_CC = [25, 35, 45]
    def test_comparewithCC(supply_AA_BB_CC):
    	zz=35
>   	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"
E    AssertionError: cc and zz comparison failed
E    assert 45 == 35
test_basic_fixture.py:16: AssertionError
================================= 2 failed, 1 passed in 0.05 seconds =================================

Der Test test_comparewithBB ist erfolgreich, da zz=BB=35, die beiden verbleibenden Tests schlagen jedoch fehl.

Die Fixture-Methode ist nur innerhalb der Testdatei gültig, in der sie definiert ist. Beim Zugriff auf die Fixture in einer anderen Testdatei wird eine Fehlermeldung angezeigt. „supply_AA_BB_CC“ nicht gefunden für die Testmethoden in den anderen Dateien.

Um dieselbe Testumgebung für mehrere Testdateien zu verwenden, erstellen wir Testumgebungsmethoden in einer Datei namens `conftest.py`. Betrachten wir dazu das folgende pytest-Beispiel. Erstellen Sie drei Dateien: `conftest.py`, `test_basic_fixture.py` und `test_basic_fixture2.py` mit dem folgenden Code.

conftest.py

import pytest
@pytest.fixture
def supply_AA_BB_CC():
	aa=25
	bb =35
	cc=45
	return [aa,bb,cc]

test_basic_fixture.py

import pytest
def test_comparewithAA(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

test_basic_fixture2.py

import pytest
def test_comparewithAA_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

Pytest sucht zuerst in der Testdatei nach der Testumgebung. Wird sie dort nicht gefunden, sucht es in der Datei `conftest.py`. Führen Sie den Test mit `py.test -k test_comparewith -v` aus, um das unten stehende Ergebnis zu erhalten.

test_basic_fixture.py::test_comparewithAA FAILED  
test_basic_fixture.py::test_comparewithBB PASSED 
test_basic_fixture.py::test_comparewithCC FAILED 
test_basic_fixture2.py::test_comparewithAA_file2 PASSED 
test_basic_fixture2.py::test_comparewithBB_file2 FAILED 
test_basic_fixture2.py::test_comparewithCC_file2 FAILED

Pytest parametrisierter Test

Der Zweck der Parametrisierung eines Tests besteht darin, einen Test mit mehreren Argumentsätzen auszuführen. Dies erreichen wir mit `@pytest.mark.parametrize`. Das folgende pytest-Beispiel veranschaulicht dies. Hier übergeben wir drei Argumente an eine Testmethode. Diese Testmethode addiert die ersten beiden Argumente und vergleicht das Ergebnis mit dem dritten Argument. Erstellen Sie die Testdatei `test_addition.py` mit dem unten stehenden Code.

import pytest
@pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
def test_add(input1, input2, output):
	assert input1+input2 == output,"failed"

Die Testmethode akzeptiert drei Argumente: input1, input2 und output. Sie addiert input1 und input2 und vergleicht die Summe mit dem Ergebnis. Führen wir den Test mit `py.test -k test_add -v` aus und betrachten wir das Ergebnis.

test_addition.py::test_add[5-5-10] PASSED                                                                                                                                                                                              
test_addition.py::test_add[3-5-12] FAILED                                                                                                                                                                                              
============================================== FAILURES ==============================================
__________________________________________ test_add[3-5-12] __________________________________________
input1 = 3, input2 = 5, output = 12
    @pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
    def test_add(input1, input2, output):
>   	assert input1+input2 == output,"failed"
E    AssertionError: failed
E    assert (3 + 5) == 12
test_addition.py:5: AssertionError

Sie können sehen, dass die Tests zweimal durchgeführt wurden, einmal wurde geprüft, ob 5+5 ==10 ist, und einmal wurde geprüft, ob 3+5 ==12 ist.

test_addition.py::test_add[5-5-10] BESTANDEN

test_addition.py::test_add[3-5-12] FEHLGESCHLAGEN

Pytest Xfail und Skip Tests

Es wird Situationen geben, in denen wir einen Test nicht durchführen wollen, oder einen Testfall ist zu einem bestimmten Zeitpunkt nicht relevant. In solchen Situationen haben wir die Möglichkeit, den Test mit xfail abzubrechen oder die Tests zu überspringen. Der mit xfail abgebrochene Test wird zwar ausgeführt, zählt aber nicht zu den fehlgeschlagenen oder bestandenen Tests. Es wird keine tracEine Fehlermeldung wird angezeigt, wenn der Test fehlschlägt. Tests können mit `@pytest.mark.xfail` als fehlgeschlagen markiert werden. Überspringenping Ein „Test“ bedeutet, dass der Test nicht ausgeführt wird. Tests können mit `@pytest.mark.skip` übersprungen werden. Bearbeiten Sie die Datei `test_addition.py` mit dem folgenden Code.

import pytest
@pytest.mark.skip
def test_add_1():
	assert 100+200 == 400,"failed"

@pytest.mark.skip
def test_add_2():
	assert 100+200 == 300,"failed"

@pytest.mark.xfail
def test_add_3():
	assert 15+13 == 28,"failed"

@pytest.mark.xfail
def test_add_4():
	assert 15+13 == 100,"failed"

def test_add_5():
	assert 3+2 == 5,"failed"

def test_add_6():
	assert 3+2 == 6,"failed"

Hier:

  • test_add_1 und test_add_2 werden übersprungen und nicht ausgeführt.
  • Die Tests test_add_3 und test_add_4 sind fehlgeschlagen. Diese Tests werden ausgeführt und gehören zu den fehlgeschlagenen (xfailed) bzw. bestandenen (xpassed) Tests. Es wird keine tracRückerstattung bei Fehlern.
  • Die Tests test_add_5 und test_add_6 werden ausgeführt, wobei test_add_6 einen Fehler meldet. traceback while test_add_5 passes.

Führe den Test mit py.test test_addition.py -v aus und sieh dir das Ergebnis an.

test_addition.py::test_add_1 SKIPPED
test_addition.py::test_add_2 SKIPPED
test_addition.py::test_add_3 XPASS
test_addition.py::test_add_4 xfail
test_addition.py::test_add_5 PASSED
test_addition.py::test_add_6 FAILED

============================================== FAILURES ==============================================
_____________________________________________ test_add_6 _____________________________________________
    def test_add_6():
>   	assert 3+2 == 6,"failed"
E    AssertionError: failed
E    assert (3 + 2) == 6
test_addition.py:24: AssertionError

================ 1 failed, 1 passed, 2 skipped, 1 xfailed, 1 xpassed in 0.07 seconds =================

Ergebnisse im XML-Format

Wir können Testergebnisse im XML-Format erstellen und diese zur Weiterverarbeitung an Continuous-Integration-Server übermitteln. Dies geschieht mit dem Befehl `py.test test_sample1.py -v --junitxml="result.xml"`. Die Datei `result.xml` speichert das Ergebnis der Testausführung. Ein Beispiel für eine `result.xml` finden Sie unten.

<?xml version="1.0" encoding="UTF-8"?>
<testsuite errors="0" failures="1" name="pytest" skips="0" tests="2" time="0.046">
   <testcase classname="test_sample1" file="test_sample1.py" line="3" name="test_file1_method1" time="0.001384973526">
     <failure message="AssertionError:test failed because x=5 y=6 assert 5 ==6">
    @pytest.mark.set1
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
         test_sample1.py:9: AssertionError
    </failure>
   </testcase>
   <testcase classname="test_sample1" file="test_sample1.py" line="10" name="test_file1_method2" time="0.000830173492432" />
</testsuite>

Aus Wir sehen insgesamt zwei Tests, von denen einer fehlgeschlagen ist. Darunter finden Sie die Details zu jedem ausgeführten Test. Etikett.

Pytest-Framework zum Testen einer API

Nun erstellen wir ein kleines pytest-Framework zum Testen einer API. Die hier verwendete API ist kostenlos und stammt von [Name der Plattform/des Anbieters]. requires.inDiese Website stellt lediglich eine testbare API bereit und speichert keine unserer Daten. Hier werden wir einige Tests für Folgendes schreiben:

  • Auflistung einiger Benutzer.
  • Mit Benutzern anmelden.

Erstellen Sie die folgenden Dateien mit dem angegebenen Code. Zunächst enthält conftest.py eine Fixture, die die Basis bereitstellt. URL für alle Testmethoden.

import pytest
@pytest.fixture
def supply_url():
	return "https://reqres.in/api"

Anschließend enthält test_list_user.py die Testmethoden zum Auflisten gültiger und ungültiger Benutzer.

  • test_list_valid_user prüft, ob ein gültiger Benutzer abgerufen wurde und verifiziert die Antwort.
  • test_list_invaliduser prüft auf ungültige Benutzerabfragen und verifiziert die Antwort.
import pytest
import requests
import json
@pytest.mark.parametrize("userid, firstname",[(1,"George"),(2,"Janet")])
def test_list_valid_user(supply_url,userid,firstname):
	url = supply_url + "/users/" + str(userid)
	resp = requests.get(url)
	j = json.loads(resp.text)
	assert resp.status_code == 200, resp.text
	assert j['data']['id'] == userid, resp.text
	assert j['data']['first_name'] == firstname, resp.text

def test_list_invaliduser(supply_url):
	url = supply_url + "/users/50"
	resp = requests.get(url)
	assert resp.status_code == 404, resp.text

Die Datei test_login_user.py enthält dann die Testmethoden zum Testen der Anmeldefunktionalität.

  • test_login_valid prüft den gültigen Anmeldeversuch mit E-Mail-Adresse und Passwort.
  • test_login_no_password testet den ungültigen Anmeldeversuch ohne Angabe eines Passworts.
  • test_login_no_email testet den ungültigen Anmeldeversuch ohne Angabe einer E-Mail-Adresse.
import pytest
import requests
import json
def test_login_valid(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'test@test.com','password':'something'}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 200, resp.text
	assert j['token'] == "QpwL5tke4Pnpja7X", resp.text

def test_login_no_password(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'test@test.com'}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 400, resp.text
	assert j['error'] == "Missing password", resp.text

def test_login_no_email(supply_url):
	url = supply_url + "/login/" 
	data = {}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 400, resp.text
	assert j['error'] == "Missing email or username", resp.text

Führen Sie den Test mit py.test -v aus und sehen Sie sich das Ergebnis wie folgt an.

test_list_user.py::test_list_valid_user[1-George] PASSED                                                                                                                                                                               
test_list_user.py::test_list_valid_user[2-Janet] PASSED                                                                                                                                                                                
test_list_user.py::test_list_invaliduser PASSED                                                                                                                                                                                        
test_login_user.py::test_login_valid PASSED                                                                                                                                                                                            
test_login_user.py::test_login_no_password PASSED                                                                                                                                                                                      
test_login_user.py::test_login_no_email PASSED

Aktualisieren Sie die Tests und probieren Sie verschiedene Ausgaben aus.

Häufig gestellte Fragen

Beide laufen Python Pytest verwendet zwar auch Unittest-Tests, aber es nutzt einfache Assert-Anweisungen, benötigt weniger Boilerplate-Code und bietet Fixtures, Marker und Parametrisierung. Unittest ist in der Standardbibliothek enthalten und folgt dem klassenbasierten xUnit-Stil. Pytest kann weiterhin bestehende Unittest-Testfälle ausführen.

Verwenden Sie die Knoten-ID-Syntax mit einem Doppelpunkt: pytest test_sample1.py::test_file1_method1. Dadurch wird nur diese eine Methode ausgeführt. Sie können auch eine ganze Datei auswählen (pytest test_sample1.py) oder mit der Option -k nach Namen filtern.

Installieren Sie das pytest-cov-Plugin und führen Sie anschließend `pytest --cov=Ihr_Paket` aus. Es wird der Prozentsatz der von Ihren Tests ausgeführten Zeilen angezeigt, und `--cov-report=html` erzeugt einen durchsuchbaren Bericht, der nicht getestete Zeilen hervorhebt.

Der Gültigkeitsbereich einer Fixture steuert, wie oft sie ausgeführt wird: Funktion (Standard), Klasse, Modul, Paket oder Session. Er wird mit `@pytest.fixture(scope="module")` festgelegt. Größere Gültigkeitsbereiche ermöglichen die Wiederverwendung aufwändiger Setups, wie z. B. Datenbankverbindungen, in mehreren Tests.

Führen Sie `pytest -x` aus, um den Test nach dem ersten fehlgeschlagenen Test sofort zu beenden, oder `pytest --maxfail=2`, um ihn nach einer festgelegten Anzahl von Fehlern zu stoppen. Dies verkürzt die Feedbackschleife beim Debuggen einer fehlerhaften Testsuite.

Pytest erfasst standardmäßig die Standardausgabe. Mit dem Parameter `-s` (pytest -s) lässt sich die Erfassung deaktivieren und die Ausgaben live anzeigen. Der Parameter `-v` fügt eine ausführliche, testbezogene Ausgabe hinzu, die den Namen jedes Tests und sein Ergebnis auflistet.

Teams im Bereich maschinelles Lernen nutzen pytest, um Datenladeprozesse, Merkmalsumwandlungen und Modellausgaben zu validieren. Fixtures stellen Beispieldatensätze bereit, und parametrisierte Tests überprüfen zahlreiche Eingaben, sodass die intelligenten Systemkomponenten auch bei Codeänderungen zuverlässig funktionieren.

Ja. GitHub Copilot und agentenbasierte KI-Assistenten können pytest-Funktionen, Fixtures und parametrisierte Fälle aus einer kurzen Eingabeaufforderung oder einer bestehenden Funktion generieren. RevPrüfen Sie die generierten Aussagen, da KI Grenzfälle übersehen und erwartete Werte falsch einschätzen kann.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: