Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Python

PyTest-Tutorial:Was ist, Installation, Framework, Behauptungen

Was ist PyTest?

PyTest ist ein Testframework, mit dem Benutzer Testcodes mit der Programmiersprache Python schreiben können. Es hilft Ihnen, einfache und skalierbare Testfälle für Datenbanken, APIs oder UI zu schreiben. PyTest wird hauptsächlich zum Schreiben von Tests für APIs verwendet. Es hilft beim Schreiben von Tests von einfachen Unit-Tests bis hin zu komplexen Funktionstests.

Warum PyTest verwenden?

Einige der Vorteile von pytest sind

In diesem Python PyTest-Tutorial lernen Sie:

So installieren Sie PyTest

Im Folgenden wird beschrieben, wie PyTest installiert wird:

Schritt 1) Sie können pytest installieren, indem Sie

pip install pytest==2.9.1

Sobald die Installation abgeschlossen ist, können Sie diese mit durch

bestätigen
py.test -h

Dadurch wird die Hilfe angezeigt

Erster grundlegender PyTest

Jetzt lernen wir anhand eines einfachen PyTest-Beispiels, wie man Pytest verwendet.

Erstellen Sie einen Ordner study_pytest. Wir werden unsere Testdateien in diesem Ordner erstellen.

Bitte navigieren Sie zu diesem Ordner in Ihrer Befehlszeile.

Erstellen Sie eine Datei namens test_sample1.py in dem Ordner

Fügen Sie den folgenden Code hinzu und speichern Sie

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 Befehl

aus
py.test

Sie erhalten die Ausgabe als

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

Hier in test_sample1.py F.

F sagt Fehler

Punkt(.) sagt Erfolg.

Im Fehlerabschnitt können Sie die fehlgeschlagene(n) Methode(n) und die Fehlerlinie sehen. Hier bedeutet x==y 5==6, was falsch ist.

Als Nächstes lernen wir in diesem PyTest-Tutorial etwas über Behauptungen in PyTest.

Zusicherungen in PyTest

Pytest-Assertionen sind Prüfungen, die entweder den Status True oder False zurückgeben. Wenn in Python Pytest eine Assertion in einer Testmethode fehlschlägt, wird diese Methodenausführung dort gestoppt. Der verbleibende Code in dieser Testmethode wird nicht ausgeführt und Pytest-Assertionen werden mit der nächsten Testmethode fortgesetzt.

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.

Betrachten Sie

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

Platzieren Sie diesen Code in test_file1_method1() anstelle der Behauptung

assert x == y,"test failed"

Beim Ausführen des Tests wird der Fehler als AssertionError:test failed x=5 y=6 ausgegeben

Wie PyTest die Testdateien und Testmethoden identifiziert

Standardmäßig erkennt pytest nur die Dateinamen, die mit test_ beginnen oder mit _test enden als Testdateien. Wir können jedoch ausdrücklich andere Dateinamen erwähnen (wird später erklärt). Pytest erfordert, dass die Namen der Testmethoden mit „test“ beginnen .“ Alle anderen Methodennamen werden ignoriert, auch wenn wir ausdrücklich darum bitten, diese Methoden auszuführen.

Sehen Sie sich einige Beispiele für gültige und ungültige Pytest-Dateinamen an

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

Hinweis:Ja, wir können pytest ausdrücklich bitten, testlogin.py und logintest.py

auszuwählen

Sehen Sie sich einige Beispiele für gültige und ungültige Pytest-Testmethoden an

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

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

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

Derzeit haben wir im Ordner study_pytest eine Datei test_sample1.py. Angenommen, wir haben mehrere Dateien, sagen wir test_sample2.py, test_sample3.py. Um alle Tests von allen Dateien im Ordner und den Unterordnern auszuführen, müssen wir einfach den Befehl pytest ausführen.

py.test

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

Um Tests nur von einer bestimmten Datei auszuführen, können wir py.test

verwenden
py.test test_sample1.py

Führen Sie 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 durchzuführen. Wir können es auf 2 Arten tun

Wir haben bereits test_sample1.py. Erstellen Sie eine Datei test_sample2.py und fügen Sie den folgenden Code hinzu

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"

So haben wir derzeit

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

Option 1) Führen Sie Tests durch Übereinstimmung von Teilzeichenfolgen durch

Um alle Tests auszuführen, die method1 in ihrem Namen haben, müssen wir hier

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

Wenn Sie also py.test -k method1 -v ausführen, erhalten Sie das folgende 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 sehen Sie gegen Ende 2 Tests deselektiert durch ‚-kmethod1‘ Dies sind test_file1_method2 und test_file2_method2

Versuchen Sie, mit verschiedenen Kombinationen zu laufen, wie:-

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, verschiedene Attribute für die Testmethoden mithilfe von Pytest-Markern, @pytest.mark , festzulegen. Um Markierungen in der Testdatei zu verwenden, müssen wir pytest in die Testdateien importieren.

Hier wenden wir unterschiedliche Markernamen auf Testmethoden an und führen spezifische Tests basierend auf Markernamen durch. Wir können die Marker für jeden Testnamen definieren, indem wir

verwenden
@pytest.mark.<name>.			

Wir definieren die Marker set1 und set2 für die Testmethoden und führen den Test mit den 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 gekennzeichneten Test bis zum

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, test_file2_method2 ausgeführt.

Wenn Sie py.test -m set2 ausführen, wird test_file1_method2 ausgeführt.

Tests parallel mit Pytest ausführen

Normalerweise enthält eine Testsuite mehrere Testdateien und Hunderte von Testmethoden, deren Ausführung viel Zeit in Anspruch nimmt. Pytest ermöglicht es uns, Tests parallel auszuführen.

Dazu müssen wir zuerst pytest-xdist installieren, indem wir

ausführen
pip install pytest-xdist

Sie können jetzt Tests durchführen, indem Sie

py.test -n 4

-n führt die Tests mit mehreren Workern aus. Im obigen Befehl gibt es 4 Worker, um den Test auszuführen.

Pytest-Geräte

Fixtures werden verwendet, wenn wir vor jeder Testmethode Code ausführen möchten. Anstatt den gleichen Code in jedem Test zu wiederholen, definieren wir Fixtures. Normalerweise werden Fixtures verwendet, um Datenbankverbindungen zu initialisieren, die Basis zu übergeben usw.

Eine Methode wird durch Markierung mit

als Pytest Fixture gekennzeichnet
@pytest.fixture

Eine Testmethode kann eine Pytest-Vorrichtung verwenden, indem sie die Vorrichtung als Eingabeparameter erwähnt.

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

Jede der Testfunktionen hat ein Eingangsargument, dessen Name mit einer verfügbaren Vorrichtung übereinstimmt. Pytest ruft dann die entsprechende Fixture-Methode auf und die zurückgegebenen Werte werden im Eingabeargument gespeichert, hier die Liste [25,35,45]. Jetzt werden die Listenelemente in Testmethoden für den Vergleich verwendet.

Führen Sie nun den Test durch 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 wird seit zz=BB=35 bestanden und die verbleibenden 2 Tests sind fehlgeschlagen.

Die Fixture-Methode hat nur innerhalb der Testdatei einen Gültigkeitsbereich, in dem sie definiert ist. Wenn wir versuchen, auf das Fixture in einer anderen Testdatei zuzugreifen, erhalten wir die Fehlermeldung Fixture ‘supply_AA_BB_CC’ not found für die Testmethoden in anderen Dateien.

Um dasselbe Fixture für mehrere Testdateien zu verwenden, erstellen wir Fixture-Methoden in einer Datei namens conftest.py.

Lassen Sie uns dies anhand des folgenden PyTest-Beispiels sehen. Erstellen Sie 3 Dateien conftest.py, test_basic_fixture.py, 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 dem Fixture und wenn es nicht gefunden wird, sucht es in der conftest.py

Führen Sie den Test mit py.test -k test_comparewith -v aus, um das Ergebnis wie unten 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

Parametrisierter Pytest-Test

Der Zweck der Parametrisierung eines Tests besteht darin, einen Test mit mehreren Sätzen von Argumenten auszuführen. Wir können dies mit @pytest.mark.parametrize.

tun

Wir werden dies mit dem folgenden PyTest-Beispiel sehen. Hier übergeben wir 3 Argumente an eine Testmethode. Diese Testmethode fügt die ersten 2 Argumente hinzu und vergleicht sie mit dem 3. Argument.

Erstellen Sie die Testdatei test_addition.py mit dem folgenden 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"

Hier akzeptiert die Testmethode 3 Argumente - Eingabe1, Eingabe2, Ausgabe. Es addiert input1 und input2 und vergleicht es mit dem Output.

Lassen Sie uns den Test mit py.test -k test_add -v ausführen und das Ergebnis sehen

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 – einer prüft 5+5 ==10 und der andere prüft 3+5 ==12

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

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

Pytest Xfail / Tests überspringen

Es wird einige Situationen geben, in denen wir einen Test nicht ausführen möchten oder ein Testfall für eine bestimmte Zeit nicht relevant ist. In diesen Situationen haben wir die Möglichkeit, den Test nicht zu bestehen oder die Tests zu überspringen

Der xfailed-Test wird ausgeführt, aber nicht als teilweise nicht bestandener oder bestandener Test gezählt. Wenn dieser Test fehlschlägt, wird kein Traceback angezeigt. Wir können Tests xfailen mit

@pytest.mark.xfail.

Das Überspringen eines Tests bedeutet, dass der Test nicht ausgeführt wird. Wir können Tests mit

überspringen

@pytest.mark.skip.

Bearbeiten Sie 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

Führen Sie den Test mit py.test test_addition.py -v aus und sehen Sie sich 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 =================

Ergebnis-XML

Wir können Testergebnisse im XML-Format erstellen, die wir an Continuous-Integration-Server zur weiteren Verarbeitung usw. weiterleiten können. Dies kann durch

erfolgen

py.test test_sample1.py -v –junitxml=”result.xml”

Die result.xml zeichnet das Ergebnis der Testausführung auf. Unten finden Sie ein Beispiel für result.xml

<?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 “ sehen wir insgesamt zwei Tests, von denen einer fehlgeschlagen ist. Darunter sehen Sie die Details zu jedem ausgeführten Test unter dem -Tag.

Pytest Framework Testen einer API

Jetzt erstellen wir ein kleines Pytest-Framework, um eine API zu testen. Die hier verwendete API ist kostenlos von https://reqres.in/. Diese Website dient nur dazu, eine testbare API bereitzustellen. Diese Website speichert unsere Daten nicht.

Hier schreiben wir einige Tests für

Erstellen Sie die folgenden Dateien mit dem angegebenen Code

conftest.py – hat eine Vorrichtung, die die Basis-URL für alle Testmethoden bereitstellt

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

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

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

test_login_user.py – enthält Testmethoden zum Testen der Anmeldefunktionalität.

import pytest
import requests
import json
def test_login_valid(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'[email protected]','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':'[email protected]'}
	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

Sehen Sie sich das Ergebnis als

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

Zusammenfassung

In diesem PyTest-Tutorial haben wir behandelt


Python

  1. So installieren Sie WordPress in der Google Cloud
  2. Lernprogramm zum Testautomatisierungsframework für codierte UI
  3. Was ist ein Netzwerksicherheitsschlüssel? Wie finde ich es?
  4. Was sind WLAN-Anrufe? Wie funktioniert es?
  5. Was ist 6G und wie schnell wird es sein?
  6. So installieren Sie einen Dock Leveler
  7. Teilentladungstest:Was ist das und wie funktioniert er
  8. Was ist Pumpenkavitation und wie vermeide ich sie?
  9. Was ist Kupferlöten und wie wird es gemacht?
  10. Was ist Wartungsrückstand? Wie kann man es überwinden?