PyTest Eğitimi: PyTest Nedir? (Örneklerle)

⚡ Akıllı Özet

Pytest bir Python Veritabanları, API'ler ve kullanıcı arayüzleri için basit, ölçeklenebilir testler yazmanıza yardımcı olan bir test çerçevesi. Temel birim testlerinden karmaşık fonksiyonel testlere kadar fikstürleri, parametreleştirmeyi, işaretleyicileri, paralel çalıştırmaları ve ayrıntılı doğrulama raporlamasını destekler.

  • 🔘 Kurulum: `pip install pytest` komutu framework'ü ekler ve `py.test -h` komutu ise yardım çıktısını yazdırarak kurulumu doğrular.
  • ☑️ Test keşfi: Pytest, otomatik olarak test_*.py veya *_test.py isimli dosyaları ve adları test ile başlayan metotları toplar.
  • iddialar: Basit doğrulama ifadeleri, bir kontrol başarısız olduğunda karşılaştırılan değerlerle birlikte açık bir AssertionError hatası bildirir.
  • 🧪 Fikstür: @pytest.fixture dekoratörü, conftest.py dosyası aracılığıyla dosyalar arasında paylaşılan yeniden kullanılabilir kurulum verileri sağlar.
  • Seçici çalıştırmalar: İşaretleyiciler, -k alt dize filtresi ve parametreleştirme, hedefli alt kümeleri veya aynı testi birçok girdi üzerinde çalıştırır.
  • 🤖 Yapay zeka iş akışları: Makine öğrenimi ekipleri, veri işlem hatlarını ve model çıktılarını doğrulamak için pytest'i kullanırken, Copilot test senaryoları oluşturabiliyor.

Pytest Eğitimi

Pytest Test etme alanında en yaygın kullanılan test çerçevelerinden biridir. Python Bu ekosistem, test kodunu kısa ve okunabilir tutar, testleri otomatik olarak keşfeder ve ilk doğrulama işleminden veritabanları, API'ler ve kullanıcı arayüzleri için tam bir test paketine kadar büyür. Aşağıdaki bölümler, kurulum, doğrulama işlemleri, fikstürler, işaretleyiciler, parametreleştirme ve paralel çalıştırmaları pratik örneklerle ele almaktadır.

Pytest nedir?

Pytest Test kodunu şu şekilde yazmanıza olanak sağlayan bir test çerçevesidir: Python Pytest, veritabanları, API'ler ve hatta kullanıcı arayüzleri için basit ve ölçeklenebilir test senaryoları yazmanıza yardımcı olan bir programlama dilidir. Pytest, esas olarak API'ler için test yazmak için kullanılır ve basit birim testlerinden karmaşık fonksiyonel testlere kadar ölçeklenebilir.

Pytest neden kullanılır?

Pytest'in bazı avantajları şunlardır:

  • Basit ve temiz sözdizimi sayesinde kullanımı çok kolay.
  • Testleri paralel olarak çalıştırabilir.
  • Belirli bir testi veya testlerin bir alt kümesini çalıştırabilir.
  • Testleri otomatik olarak algılar.
  • Testleri atlayabilirsiniz.
  • Açık kaynak.

Pytest nasıl kurulur?

Pytest'i yükleme süreci şu şekildedir:

) 1 Adım Pytest'i aşağıdaki komutla kurabilirsiniz.

pip install pytest==2.9.1

Kurulum tamamlandıktan sonra, aşağıdaki komutla doğrulayabilirsiniz.

py.test -h

Bu, yardım bölümünü gösterecektir.

pytest'i yükleyin ve yardım çıktısını inceleyin.

İlk Temel Pytest Örneği

Şimdi, temel bir pytest örneğiyle pytest'i nasıl kullanacağınızı öğreneceksiniz.

`study_pytest` adında bir klasör oluşturun. Test dosyalarını bu klasörün içine oluşturacaksınız. Lütfen komut satırında bu klasöre gidin. Klasörün içine `test_sample1.py` adında bir dosya oluşturun.

İlk temel pytest test dosyasını oluşturun.

Aşağıdaki kodu ekleyin ve kaydedin.

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" 

Aşağıdaki komutu kullanarak testi çalıştırın.

py.test

Aşağıdaki gibi bir çıktı alacaksınız.

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

Pytest testinin başarısızlık çıktısı

Burada, test_sample1.py dosyasındaki F. ifadesinde, F harfi başarısızlığı, nokta (.) ise başarıyı ifade eder. Başarısızlıklar bölümünde, başarısız olan metot(lar)ı ve başarısızlık satırını görebilirsiniz. Burada x==y ifadesi 5==6 anlamına gelir ki bu yanlıştır.

Sonraki adımda, pytest'te doğrulama (assertions) işlemleri hakkında bilgi edineceksiniz.

Pytest'te Doğrulama İşlemleri

Pytest'te doğrulama (assert) işlemleri, True veya False durumunu döndüren kontrollerdir. Pytest'te, bir test metodunda bir doğrulama başarısız olursa, o metodun yürütülmesi orada durdurulur. Test metodundaki kalan kod yürütülmez ve pytest bir sonraki test metoduna geçer.

Pytest assert örnekleri:

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.

Aşağıdakileri göz önünde bulundur.

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

Aşağıdaki doğrulama yerine bu kodu test_file1_method1() fonksiyonuna yerleştirin.

assert x == y,"test failed"

Testin çalıştırılması başarısızlığı şu şekilde verecektir: AssertionError: test başarısız oldu x=5 y=6.

Pytest Test Dosyalarını ve Test Metotlarını Nasıl Belirliyor?

Varsayılan olarak, pytest yalnızca "." ile başlayan dosya adlarını tanımlar. Ölçek_ veya ile biten _Ölçek Test dosyaları olarak. Ancak, diğer dosya adlarını da açıkça belirtebiliriz (daha sonra açıklanacak). Pytest, test metodu adlarının ile başlamasını gerektirir. testDiğer tüm yöntem adları, bu yöntemleri çalıştırmayı açıkça talep etsek bile, göz ardı edilir.

Geçerli ve geçersiz pytest dosya adlarına bazı örnekler aşağıda verilmiştir.

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

Not: Evet, pytest'ten testlogin.py ve logintest.py dosyalarını seçmesini açıkça isteyebiliriz.

Geçerli ve geçersiz pytest test yöntemlerine dair bazı örneklere göz atın.

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

Not: file1_method1() yöntemini açıkça belirtsek bile, pytest bu yöntemi çalıştırmayacaktır.

Belirli Bir Dosyadan ve Birden Çok Dosyadan Çoklu Test Çalıştırma

Şu anda study_pytest klasörünün içinde test_sample1.py adlı bir dosyamız var. Diyelim ki test_sample2.py ve test_sample3.py gibi birden fazla dosyamız var. Klasördeki ve alt klasörlerdeki tüm dosyalardaki tüm testleri çalıştırmak için sadece pytest komutunu çalıştırmamız yeterli.

py.test

Bu komut, belirtilen klasördeki ve bu klasörün altındaki alt klasörlerdeki "test_" ile başlayan ve "_test" ile biten tüm dosya adlarını çalıştıracaktır.

Yalnızca belirli bir dosyadaki testleri çalıştırmak için `py.test` kullanabiliriz. .

py.test test_sample1.py

Pytest kullanarak testin tamamının bir alt kümesini çalıştırın.

Bazen tüm test paketini çalıştırmak istemeyebiliriz. Pytest, belirli testleri çalıştırmamıza olanak tanır. Bunu iki şekilde yapabiliriz:

  • Grouping Alt dize eşleştirmesine göre test adlarının sıralanması.
  • Grouping belirteçler tarafından yapılan testler.

test_sample1.py dosyamız zaten mevcut. test_sample2.py adında bir dosya oluşturun ve içine aşağıdaki kodu ekleyin.

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"

Şu anda elimizde aşağıdaki bilgiler var.

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

Seçenek 1) Alt dize eşleştirmesi yaparak testleri çalıştırın

Burada, adında "method1" geçen tüm testleri çalıştırmak için aşağıdaki komutu çalıştırmamız gerekiyor.

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

Dolayısıyla `py.test -k method1 -v` komutunu çalıştırmak size aşağıdaki sonucu verecektir.

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

Burada, sona doğru, görebilirsiniz. '-kmethod2' tarafından 1 testin seçimi kaldırıldıBunlar test_file1_method2 ve test_file2_method2'dir.

Aşağıdaki gibi çeşitli kombinasyonlarla deneme yapın.

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'

Seçenek 2) Testleri işaretçilere göre çalıştırma

Pytest, `@pytest.mark` işaretçilerini kullanarak test yöntemleri için çeşitli öznitelikler belirlememize olanak tanır. Test dosyasında işaretçileri kullanmak için, `pytest`'i test dosyalarına içe aktarmamız gerekir. Burada, test yöntemlerine farklı işaretçi adları uygulayacağız ve işaretçi adlarına bağlı olarak belirli testleri çalıştıracağız. Her test adı için işaretçileri aşağıdaki şekilde tanımlayabiliriz.

@pytest.mark.<name>.			

Test yöntemlerinde set1 ve set2 işaretleyicilerini tanımlıyoruz ve testleri bu işaretleyici adlarını kullanarak çalıştıracağız. Test dosyalarını aşağıdaki kodla güncelleyin.

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"

İşaretli testi aşağıdaki komutla çalıştırabiliriz.

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

`py.test -m set1` komutunu çalıştırın. Bu komut, `test_file1_method1`, `test_file2_method1` ve `test_file2_method2` yöntemlerini çalıştıracaktır. `py.test -m set2` komutunu çalıştırmak ise `test_file1_method2` yöntemini çalıştıracaktır.

Pytest ile Testleri Paralel Olarak Çalıştırın

Genellikle bir test paketi, birden fazla test dosyası ve yüzlerce test yöntemi içerir ve bunların çalıştırılması önemli miktarda zaman alır. Pytest, testleri paralel olarak çalıştırmamıza olanak tanır. Bunun için öncelikle aşağıdaki komutu çalıştırarak pytest-xdist'i yüklememiz gerekir.

pip install pytest-xdist

pytest-xdist ile testleri paralel olarak çalıştırın.

Şimdi aşağıdaki komutla testleri çalıştırabilirsiniz.

py.test -n 4

Burada, -n Testler, birden fazla çalışan kullanarak çalıştırılır. Yukarıdaki komutta, testleri çalıştırmak için dört çalışan olacaktır.

Pytest Fikstürleri

Test yöntemlerinden önce belirli bir kodu çalıştırmak istediğimizde fixture'lar kullanılır. Yani, her testte aynı kodu tekrarlamak yerine fixture'lar tanımlarız. Genellikle fixture'lar veritabanı bağlantılarını başlatmak, temel parametreleri iletmek gibi işlemler için kullanılır. URLve benzeri. Bir yöntem, aşağıdaki şekilde işaretlenerek pytest fixture olarak işaretlenir.

@pytest.fixture

Bir test yöntemi, bir pytest fixture'ını giriş parametresi olarak belirterek kullanabilir. Aşağıdaki kodla yeni bir test_basic_fixture.py dosyası oluşturun.

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"

İşte:

  • supply_AA_BB_CC adında bir fikstürümüz var. Bu metot üç değerden oluşan bir liste döndürüyor.
  • Değerlerin her birini karşılaştırmak için üç test yöntemimiz var.

Test fonksiyonlarının her birinin, adı mevcut bir fixture ile eşleşen bir giriş argümanı vardır. Pytest daha sonra ilgili fixture yöntemini çağırır ve döndürülen değerler giriş argümanına, burada [25,35,45] listesine kaydedilir. Liste öğeleri daha sonra karşılaştırma için test yöntemlerinde kullanılır. Şimdi testi çalıştırın ve sonucu görün.

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

zz=BB=35 olduğu için test_comparewithBB testi başarılı olurken, kalan iki test başarısız oldu.

`fixture` metodu yalnızca tanımlandığı test dosyası içinde geçerlidir. Başka bir test dosyasında `fixture`'a erişmeye çalışırsak, `fixture` ile ilgili bir hata alırız. 'tedarik_AA_BB_CC' bulunamadı Diğer dosyalardaki test yöntemleri için.

Aynı fikstürü birden fazla test dosyasına karşı kullanmak için, conftest.py adlı bir dosyada fikstür yöntemleri oluşturuyoruz. Bunu aşağıdaki pytest örneğiyle görelim. Aşağıdaki kodla conftest.py, test_basic_fixture.py ve test_basic_fixture2.py olmak üzere üç dosya oluşturun.

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 öncelikle test dosyasında fixture'ı arayacak, bulamazsa conftest.py dosyasında arayacaktır. Aşağıdaki sonucu almak için testi py.test -k test_comparewith -v komutuyla çalıştırın.

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 Parametreli Test

Bir testi parametrelemenin amacı, testi birden fazla argüman kümesine karşı çalıştırmaktır. Bunu `@pytest.mark.parametrize` ile yapabiliriz. Aşağıdaki pytest örneğiyle bunu göreceğiz. Burada bir test yöntemine üç argüman geçireceğiz. Bu test yöntemi ilk iki argümanı toplayacak ve sonucu üçüncü argümanla karşılaştıracaktır. Aşağıdaki kodla `test_addition.py` test dosyasını oluşturun.

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"

Burada test metodu üç argüman kabul eder: input1, input2 ve output. input1 ve input2'yi toplar ve toplamı output ile karşılaştırır. py.test -k test_add -v komutuyla testi çalıştıralım ve sonucu görelim.

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

Gördüğünüz gibi testler iki kez çalıştırıldı; biri 5+5 ==10'u, diğeri ise 3+5 ==12'yi kontrol ediyor.

test_addition.py::test_add[5-5-10] BAŞARILI

test_addition.py::test_add[3-5-12] BAŞARISIZ

Pytest Xfail ve Testleri Atla

Bazı durumlarda bir testi çalıştırmak istemeyebiliriz veya test durumu Belirli bir zamanda ilgili olmayabilir. Bu durumlarda, testi başarısız olarak işaretleme veya testleri atlama seçeneğimiz vardır. Başarısız olarak işaretlenen test yürütülecektir, ancak başarısız veya başarılı testlerin bir parçası olarak sayılmayacaktır. Herhangi bir sonuç olmayacaktır. tracTest başarısız olursa eback görüntülenir. @pytest.mark.xfail kullanarak testleri başarısız olarak işaretleyebiliriz. Atlaping Bir testin çalıştırılmayacağı anlamına gelir. @pytest.mark.skip kullanarak testleri atlayabiliriz. test_addition.py dosyasını aşağıdaki kodla düzenleyin.

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"

İşte:

  • test_add_1 ve test_add_2 atlanır ve yürütülmez.
  • test_add_3 ve test_add_4 testleri xfailed olarak işaretlendi. Bu testler çalıştırılacak ve xfailed (test başarısız olursa) veya xpassed (test başarılı olursa) testlerinin bir parçası olacak. Herhangi bir hata olmayacak. tracBaşarısızlıklar için geri bildirim.
  • test_add_5 ve test_add_6 testleri çalıştırılacak ve test_add_6 bir hata raporu verecektir. tractest_add_5 başarılı olduğu sürece geri dönüş.

`py.test test_addition.py -v` komutuyla testi çalıştırın ve sonucu görün.

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

Sonuçlar XML Formatında

Sürekli Entegrasyon sunucularına daha fazla işlem için aktarabileceğimiz XML formatında test sonuçları oluşturabiliriz. Bu işlem, `py.test test_sample1.py -v –junitxml=”result.xml”` komutuyla yapılabilir. `result.xml` dosyası test yürütme sonucunu kaydedecektir. Aşağıda örnek bir `result.xml` dosyası bulabilirsiniz.

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

İtibaren Toplamda iki test görüyoruz, bunlardan biri başarısız oldu. Bunun altında, gerçekleştirilen her testle ilgili ayrıntıları görebilirsiniz. etiket.

API testleri için Pytest çerçevesi

Şimdi bir API'yi test etmek için küçük bir pytest çerçevesi oluşturacağız. Burada kullanılan API, ücretsiz bir API'dir. gereksinimler.Bu web sitesi yalnızca test edilebilir bir API sağlar ve verilerimizi saklamaz. Burada aşağıdaki konular için bazı testler yazacağız:

  • Bazı kullanıcıları listeliyoruz.
  • Kullanıcılarla giriş yapın.

Verilen kodla aşağıdaki dosyaları oluşturun. İlk olarak, conftest.py dosyasında temel verileri sağlayacak bir fixture bulunmaktadır. URL tüm test yöntemleri için.

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

Ardından, test_list_user.py dosyası geçerli ve geçersiz kullanıcıları listelemek için test yöntemlerini içerir.

  • `test_list_valid_user` geçerli bir kullanıcı sorgusu olup olmadığını kontrol eder ve yanıtı doğrular.
  • test_list_invaliduser, geçersiz kullanıcı sorgularını kontrol eder ve yanıtı doğrular.
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

Ardından, test_login_user.py dosyası, giriş işlevini test etmek için gereken test yöntemlerini içerir.

  • test_login_valid fonksiyonu, e-posta ve şifre ile yapılan geçerli giriş denemesini test eder.
  • test_login_no_password, parola girilmeden yapılan geçersiz giriş denemesini test eder.
  • test_login_no_email, e-posta adresi geçirilmeden geçersiz giriş denemesini test eder.
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

`py.test -v` komutunu kullanarak testi çalıştırın ve sonucu aşağıdaki gibi görün.

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

Testleri güncelleyin ve çeşitli çıktıları deneyin.

SSS

İkisi de koşuyor Python Unittest, standart kütüphaneyle birlikte gelir ve sınıf tabanlı xUnit stilini izler. Pytest, mevcut unittest test senaryolarını çalıştırabilir.

Düğüm kimliği sözdizimini çift nokta üst üste ile kullanın: `pytest test_sample1.py::test_file1_method1`. Bu, yalnızca o tek yöntemi çalıştırır. Ayrıca tüm bir dosyayı hedefleyebilir (`pytest test_sample1.py`) veya `-k` seçeneğiyle ada göre filtreleyebilirsiniz.

pytest-cov eklentisini kurun, ardından pytest –cov=your_package komutunu çalıştırın. Bu komut, testleriniz tarafından yürütülen satırların yüzdesini rapor eder ve –cov-report=html seçeneği, test edilmemiş satırları vurgulayan, göz atılabilir bir rapor oluşturur.

Bir testin kapsamı, ne sıklıkla çalıştırılacağını kontrol eder: fonksiyon (varsayılan), sınıf, modül, paket veya oturum. Bunu `@pytest.fixture(scope="module")` ile ayarlayabilirsiniz. Daha geniş kapsamlar, veritabanı bağlantısı gibi maliyetli kurulumları birçok testte yeniden kullanır.

Hata veren bir test paketini ayıklarken geri bildirim döngüsünü kısaltmak için `pytest -x` komutunu çalıştırarak ilk başarısız testten sonra hemen durdurabilir veya `pytest –maxfail=2` komutunu çalıştırarak seçtiğiniz sayıda başarısız testten sonra durdurabilirsiniz.

Pytest varsayılan olarak standart çıktıyı yakalar. Yakalamayı devre dışı bırakmak ve çıktıları canlı olarak göstermek için -s bayrağını (pytest -s) ekleyin. -v bayrağı, her testin adını ve sonucunu listeleyen ayrıntılı, test başına çıktı ekler.

Makine öğrenimi ekipleri, veri yükleme süreçlerini, özellik dönüşümlerini ve model çıktılarını doğrulamak için pytest kullanır. Fixture'lar örnek veri kümeleri sağlar ve parametrize birçok girdiyi kontrol eder, böylece kod değişse bile sistemin akıllı kısımları güvenilirliğini korur.

Evet. GitHub Copilot ve ajansal yapay zeka asistanları, kısa bir komut isteminden veya mevcut bir fonksiyondan pytest fonksiyonları, fikstürler ve parametrelendirilmiş test durumları oluşturabilir. RevYapay zekâ uç durumları gözden kaçırabileceği ve beklenen değerleri yanlış değerlendirebileceği için, oluşturulan iddiaları inceleyin.

Bu yazıyı şu şekilde özetleyin: