Samouczek PyTest: Czym jest PyTest? (z przykładami)

⚡ Inteligentne podsumowanie

Pytest to jest Python Framework testowy, który pomaga pisać proste, skalowalne testy dla baz danych, interfejsów API i interfejsów użytkownika. Obsługuje on funkcje testowania, parametryzację, znaczniki, przebiegi równoległe i szczegółowe raportowanie asercji, od podstawowych testów jednostkowych po złożone testy funkcjonalne.

  • 🔘 Instalacja: Polecenie pip install pytest dodaje środowisko, a py.test -h potwierdza konfigurację, wyświetlając dane wyjściowe pomocy.
  • ️ Odkrycie testowe: Pytest automatycznie zbiera pliki o nazwie test_*.py lub *_test.py oraz metody, których nazwy zaczynają się od test.
  • ✅ Asercje: Proste instrukcje assert generują wyraźny błąd AssertionError z porównywanymi wartościami za każdym razem, gdy sprawdzenie się nie powiedzie.
  • 🧪 Lampy: Dekorator @pytest.fixture dostarcza wielokrotnego użytku dane konfiguracyjne, które są współdzielone między plikami za pośrednictwem pliku conftest.py.
  • 🛠️. Biegi selektywne: Markery, filtr podciągów -k i parametryzacja uruchamiają docelowe podzbiory lub ten sam test na wielu wejściach.
  • 🤖 Przepływy pracy AI: Zespoły zajmujące się uczeniem maszynowym używają narzędzia pytest do sprawdzania poprawności danych i modelowania wyników, a Copilot może tworzyć przypadki testowe.

Samouczek Pytest

Pytest jest jednym z najczęściej używanych frameworków testowych Python Ekosystem. Utrzymuje kod testowy zwięzły i czytelny, automatycznie wykrywa testy i rozwija się od pierwszej asercji do pełnego zestawu testów dla baz danych, API i interfejsów użytkownika. Poniższe sekcje opisują instalację, asercje, wyposażenie, znaczniki, parametryzację i przebiegi równoległe z praktycznymi przykładami.

Czym jest Pytest?

Pytest jest środowiskiem testowym, które umożliwia pisanie kodu testowego przy użyciu Python Język programowania. Pomaga pisać proste i skalowalne przypadki testowe dla baz danych, interfejsów API, a nawet interfejsów użytkownika. Pytest jest używany głównie do pisania testów dla interfejsów API i skaluje się od prostych testów jednostkowych do złożonych testów funkcjonalnych.

Dlaczego warto używać Pytest?

Oto niektóre z zalet pytest:

  • Bardzo łatwy na początek, ze względu na prostą i przejrzystą składnię.
  • Można uruchamiać testy równolegle.
  • Można uruchomić konkretny test lub podzbiór testów.
  • Automatycznie wykrywa testy.
  • Można pominąć testy.
  • Otwarte źródło.

Jak zainstalować Pytest

Poniżej przedstawiono proces instalacji pytest:

Krok 1) Możesz zainstalować pytest za pomocą poniższego polecenia.

pip install pytest==2.9.1

Po zakończeniu instalacji możesz ją potwierdzić za pomocą następującego polecenia.

py.test -h

Spowoduje to wyświetlenie pomocy.

Zainstaluj pytest i zobacz wynik pomocy

Pierwszy podstawowy przykład Pytest

Teraz nauczysz się używać pytesta na przykładzie podstawowego pytesta.

Utwórz folder study_pytest. W tym folderze utworzysz pliki testowe. Przejdź do tego folderu w wierszu poleceń. Utwórz w nim plik o nazwie test_sample1.py.

Utwórz pierwszy podstawowy plik testowy pytest

Dodaj poniższy kod i zapisz.

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" 

Uruchom test za pomocą poniższego polecenia.

py.test

Wynik będzie wyglądał następująco.

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

Wynik testu Pytest z błędem

Tutaj, w pliku test_sample1.py F., litera F oznacza niepowodzenie, a kropka (.) oznacza powodzenie. W sekcji błędów widoczne są nieudane metody i wiersz błędu. Tutaj x==y oznacza 5==6, co oznacza fałsz.

Następnie dowiesz się o asercjach w pytest.

Asercje w Pytest

Asercje w pytest to testy, które zwracają status True (prawda) lub False (fałsz). W pytest, jeśli asercja w metodzie testowej zakończy się niepowodzeniem, wykonywanie tej metody zostaje przerwane. Pozostały kod w tej metodzie testowej nie jest wykonywany, a pytest kontynuuje wykonywanie następnej metody testowej.

Przykłady asercji Pytest:

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.

Rozważ następujące kwestie.

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

Umieść ten kod w test_file1_method1() zamiast poniższego potwierdzenia.

assert x == y,"test failed"

Uruchomienie testu spowoduje niepowodzenie jako AssertionError: test nie powiódł się x=5 y=6.

Jak Pytest identyfikuje pliki testowe i metody testowe

Domyślnie pytest identyfikuje tylko nazwy plików zaczynające się od test_ lub kończąc na _test jak pliki testowe. Możemy jednak jawnie podać inne nazwy plików (wyjaśnimy to później). Pytest wymaga, aby nazwy metod testowych zaczynały się od testWszystkie inne nazwy metod są ignorowane, nawet jeśli wyraźnie poprosimy o uruchomienie tych metod.

Zobacz przykłady prawidłowych i nieprawidłowych nazw plików pytest.

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

Uwaga: Tak, możemy jawnie poprosić pytest o wybranie plików testlogin.py i logintest.py.

Zobacz przykłady prawidłowych i nieprawidłowych metod testowych pytest.

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

Uwaga: Nawet jeśli wyraźnie wspomnimy o file1_method1(), pytest nie uruchomi tej metody.

Uruchom wiele testów z określonego pliku i wielu plików

Obecnie w folderze study_pytest znajduje się plik test_sample1.py. Załóżmy, że mamy wiele plików, na przykład test_sample2.py i test_sample3.py. Aby uruchomić wszystkie testy ze wszystkich plików w folderze i podfolderach, wystarczy uruchomić polecenie pytest.

py.test

Spowoduje to uruchomienie wszystkich plików o nazwach zaczynających się od test_ i kończących się na _test w danym folderze i jego podfolderach.

Aby uruchomić testy tylko z określonego pliku, możemy użyć py.test .

py.test test_sample1.py

Uruchom podzbiór całego testu za pomocą Pytest

Czasami nie chcemy uruchamiać całego zestawu testów. Pytest pozwala nam uruchamiać konkretne testy. Możemy to zrobić na dwa sposoby:

  • Grouping nazw testów poprzez dopasowywanie podciągów.
  • Grouping testów według markerów.

Mamy już plik test_sample1.py. Utwórz plik test_sample2.py i dodaj do niego poniższy kod.

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"

Więc obecnie mamy następująco.

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

Opcja 1) Uruchom testy poprzez dopasowanie podciągów

Tutaj, aby uruchomić wszystkie testy zawierające w nazwie method1, musimy uruchomić poniższe polecenie.

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

Tak więc uruchomienie polecenia py.test -k method1 -v da następujący wynik.

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 ===============================

Tutaj możesz zobaczyć pod koniec, 2 testy odznaczono za pomocą „-kmethod1”, które są test_file1_method2 i test_file2_method2.

Wypróbuj różne kombinacje, takie jak poniżej.

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'

Opcja 2) Uruchom testy według markerów

Pytest pozwala nam ustawiać różne atrybuty dla metod testowych za pomocą znaczników pytest, @pytest.mark. Aby użyć znaczników w pliku testowym, musimy zaimportować pytest do plików testowych. W tym miejscu zastosujemy różne nazwy znaczników do metod testowych i uruchomimy konkretne testy na podstawie tych nazw. Możemy zdefiniować znaczniki dla każdej nazwy testu, używając poniższego kodu.

@pytest.mark.<name>.			

Definiujemy znaczniki set1 i set2 w metodach testowych i uruchomimy test, używając nazw znaczników. Zaktualizuj pliki testu, używając poniższego kodu.

test_przykład1.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_przykład2.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"

Oznaczony test możemy uruchomić za pomocą poniższego polecenia.

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

Uruchom py.test -m set1. Spowoduje to uruchomienie metod test_file1_method1, test_file2_method1 i test_file2_method2. Uruchomienie py.test -m set2 spowoduje uruchomienie test_file1_method2.

Uruchamianie testów równolegle z Pytest

Zazwyczaj zestaw testów zawiera wiele plików testowych i setki metod testowych, których wykonanie zajmuje dużo czasu. Pytest pozwala na równoległe uruchamianie testów. W tym celu musimy najpierw zainstalować pytest-xdist, uruchamiając poniższe polecenie.

pip install pytest-xdist

Uruchom testy równolegle za pomocą pytest-xdist

Możesz teraz uruchomić testy za pomocą następującego polecenia.

py.test -n 4

Tutaj, -n uruchamia testy przy użyciu wielu procesów roboczych. W powyższym poleceniu testy będą uruchamiane przez cztery procesy robocze.

Urządzenia Pytesta

Fixtury są używane, gdy chcemy uruchomić jakiś kod przed każdą metodą testową. Zamiast więc powtarzać ten sam kod w każdym teście, definiujemy Fixtury. Zazwyczaj Fixtury służą do inicjowania połączeń z bazą danych, przekazywania danych bazowych. URLitd. Metodę oznacza się jako element pytest, poprzez oznaczenie jej w następujący sposób.

@pytest.fixture

Metoda testowa może używać fixtury pytest, podając ją jako parametr wejściowy. Utwórz nowy plik test_basic_fixture.py z poniższym kodem.

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"

Tutaj:

  • Mamy obiekt o nazwie supply_AA_BB_CC. Ta metoda zwraca listę trzech wartości.
  • Stosujemy trzy metody testowe porównujące każdą z wartości.

Każda z funkcji testowych ma argument wejściowy, którego nazwa odpowiada dostępnemu fixture. Następnie Pytest wywołuje odpowiednią metodę fixture, a zwrócone wartości są zapisywane w argumencie wejściowym, w tym przypadku na liście [25,35,45]. Elementy listy są następnie używane w metodach testowych do porównania. Teraz uruchom test i sprawdź wynik.

 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 =================================

Test test_comparewithBB kończy się pomyślnie, ponieważ zz=BB=35, a pozostałe dwa testy kończą się niepowodzeniem.

Metoda Fixture ma zasięg tylko w pliku testowym, w którym jest zdefiniowana. Jeśli spróbujemy uzyskać dostęp do Fixture w innym pliku testowym, pojawi się błąd o treści „fixture”. Nie znaleziono „supply_AA_BB_CC”. dla metod testowych w innych plikach.

Aby użyć tej samej konfiguracji dla wielu plików testowych, tworzymy metody konfiguracji w pliku conftest.py. Przeanalizujmy to na poniższym przykładzie pytest. Utwórz trzy pliki: conftest.py, test_basic_fixture.py i test_basic_fixture2.py, z następującym kodem.

konkurs.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 najpierw poszuka elementu w pliku testowym, a jeśli go nie znajdzie, przeszuka plik conftest.py. Uruchom test poleceniem py.test -k test_comparewith -v, aby uzyskać poniższy wynik.

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

Test parametryczny Pytest

Celem parametryzacji testu jest uruchomienie go dla wielu zestawów argumentów. Możemy to zrobić za pomocą @pytest.mark.parametrize. Zobaczymy to na poniższym przykładzie pytest. Przekażemy tu trzy argumenty do metody testowej. Ta metoda doda pierwsze dwa argumenty i porówna wynik z trzecim argumentem. Utwórz plik testowy test_addition.py z poniższym kodem.

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"

W tym przypadku metoda testowa przyjmuje trzy argumenty: input1, input2 i output. Dodaje input1 i input2 i porównuje sumę z outputem. Uruchommy test poleceniem py.test -k test_add -v i sprawdźmy wynik.

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

Można zobaczyć, że testy przeprowadzono dwukrotnie: pierwszy raz sprawdzano wynik 5+5 ==10, a drugi raz 3+5 ==12.

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

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

Testy Pytest Xfail i Skip

Będą sytuacje, w których nie będziemy chcieli przeprowadzać testu lub walizka testowa nie jest istotne w danym momencie. W takich sytuacjach mamy możliwość zaliczenia testu z wynikiem pozytywnym lub pominięcia testów. Test z wynikiem pozytywnym zostanie wykonany, ale nie będzie zaliczany do testów z wynikiem pozytywnym lub negatywnym. Nie będzie tracW przypadku niepowodzenia testu wyświetlany jest kod eback. Możemy oznaczyć testy jako xfail za pomocą @pytest.mark.xfail. Pomińping Test oznacza, że ​​test nie zostanie wykonany. Możemy pominąć testy, używając @pytest.mark.skip. Edytuj plik test_addition.py za pomocą poniższego kodu.

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"

Tutaj:

  • test_add_1 i test_add_2 są pomijane i nie zostaną wykonane.
  • Test_add_3 i test_add_4 są oznaczone jako xfailed. Te testy zostaną wykonane i będą częścią testów xfailed (w przypadku niepowodzenia testu) lub xpassed (w przypadku zaliczenia testu). Nie będzie żadnych traceback za porażki.
  • zostaną wykonane testy test_add_5 i test_add_6, a test_add_6 zgłosi błąd z traceback, dopóki test_add_5 nie przejdzie.

Wykonaj test poleceniem py.test test_addition.py -v i zobacz wynik.

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 =================

Wyniki w formacie XML

Możemy tworzyć wyniki testów w formacie XML, które następnie możemy przesłać do serwerów ciągłej integracji w celu dalszego przetwarzania. Można to zrobić za pomocą polecenia py.test test_sample1.py -v –junitxml=”result.xml”. Plik result.xml zapisze wynik wykonania testu. Przykładowy plik result.xml znajduje się poniżej.

<?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>

Z Widzimy łącznie dwa testy, z których jeden zakończył się niepowodzeniem. Poniżej znajdują się szczegóły dotyczące każdego wykonanego testu pod etykietka.

Framework Pytest do testowania API

Teraz utworzymy mały framework pytest do testowania API. Użyte tutaj API jest darmowe i pochodzi od reqres.inTa strona internetowa udostępnia jedynie testowalny interfejs API i nie przechowuje naszych danych. Poniżej napiszemy kilka testów dla następujących elementów:

  • Wyświetlanie listy niektórych użytkowników.
  • Zaloguj się jako użytkownicy.

Utwórz poniższe pliki za pomocą podanego kodu. Najpierw conftest.py zawiera element, który dostarczy bazę URL dla wszystkich metod testowych.

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

Następnie plik test_list_user.py zawiera metody testowe służące do wyświetlania listy prawidłowych i nieprawidłowych użytkowników.

  • test_list_valid_user sprawdza poprawność pobrania danych przez użytkownika i weryfikuje odpowiedź.
  • test_list_invaliduser sprawdza, czy użytkownik pobrał nieprawidłowe dane i weryfikuje odpowiedź.
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

Następnie plik test_login_user.py zawiera metody testowe służące do testowania funkcjonalności logowania.

  • test_login_valid sprawdza poprawność próby logowania przy użyciu adresu e-mail i hasła.
  • test_login_no_password sprawdza, czy próba logowania bez podania hasła jest nieudana.
  • test_login_no_email sprawdza, czy próba logowania jest nieudana, bez podawania adresu e-mail.
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

Uruchom test za pomocą py.test -v i zobacz wynik, jak poniżej.

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

Zaktualizuj testy i wypróbuj różne wyniki.

FAQ

Obydwa działają Python testy, ale pytest używa prostych instrukcji assert, wymaga mniej szablonów i oferuje funkcje Fixture, Marker i Parameterize. Unittest jest dostarczany ze standardową biblioteką i jest zgodny ze stylem xUnit opartym na klasach. Pytest nadal może uruchamiać istniejące przypadki testowe unittest.

Użyj składni identyfikatora węzła z podwójnym dwukropkiem: pytest test_sample1.py::test_file1_method1. To uruchamia tylko tę jedną metodę. Możesz również wskazać cały plik (pytest test_sample1.py) lub filtrować według nazwy za pomocą opcji -k.

Zainstaluj wtyczkę pytest-cov, a następnie uruchom polecenie pytest –cov=your_package. Raportuje ono procent wierszy wykonanych przez testy, a polecenie –cov-report=html generuje raport z możliwością przeglądania, który podświetla nieprzetestowane wiersze.

Zakres fixturowy kontroluje częstotliwość uruchamiania: funkcji (domyślnie), klasy, modułu, pakietu lub sesji. Ustaw go za pomocą @pytest.fixture(scope=”module”). Szersze zakresy wykorzystują kosztowne konfiguracje, takie jak połączenie z bazą danych, w wielu testach.

Uruchom pytest -x, aby zatrzymać się natychmiast po pierwszym nieudanym teście, lub pytest –maxfail=2, aby zatrzymać się po wybranej liczbie niepowodzeń. Skraca to pętlę sprzężenia zwrotnego podczas debugowania uszkodzonego pakietu.

Pytest domyślnie przechwytuje stdout. Dodaj flagę -s (pytest -s), aby wyłączyć przechwytywanie i wyświetlać polecenia print na żywo. Flaga -v dodaje szczegółowe dane wyjściowe dla każdego testu, które zawierają nazwę każdego testu i jego wynik.

Zespoły zajmujące się uczeniem maszynowym używają pytest do walidacji potoków ładowania danych, transformacji cech i wyników modeli. Fixtures dostarczają przykładowe zestawy danych, a parametrize weryfikuje wiele danych wejściowych, dzięki czemu inteligentne elementy systemu pozostają niezawodne pomimo zmian w kodzie.

Tak. GitHub Copilot i asystenci AI z wykorzystaniem agentów mogą generować funkcje pytest, fixtures i sparametryzowane przypadki z krótkiego monitu lub istniejącej funkcji. Revprzeglądaj wygenerowane stwierdzenia, ponieważ AI może przegapić przypadki skrajne i błędnie ocenić oczekiwane wartości.

Podsumuj ten post następująco: