Pytest'te, conftest.py dosyalarının kullanımı nedir?


218

Geçenlerde keşfettim pytest. Harika görünüyor. Ancak, belgelerin daha iyi olabileceğini hissediyorum.

Hangi conftest.pydosyaların kullanılması gerektiğini anlamaya çalışıyorum .

(Şu anda küçük) test takımımda conftest.pyproje kökünde bir dosya var . Testlerime enjekte ettiğim armatürleri tanımlamak için kullanıyorum.

İki sorum var:

  1. Bu doğru kullanım conftest.pymı? Başka kullanımları var mı?
  2. Birden fazla conftest.pydosyam olabilir mi? Bunu ne zaman yapmak isterdim? Örnekler takdir edilecektir.

Daha genel olarak, conftest.pybir py.test test takımında dosya (lar) ın amacını ve doğru kullanımını nasıl tanımlarsınız ?


9
Beni attıIt seems great. However, I feel the documentation could be better.
user9074332

7
Evet, dokümantasyon çok daha iyi olabilir. Tüm pytest belgelerini aradım ve conftest.pybu şeyi yapmak veya bir conftest dosyasıyla yapmak için birçok referans olmasına rağmen, belgelerin hiçbir yerinde pytest keşfi test ettiğinde, tüm conftest.py dosyaları bulundu ( üzerinde test keşfi yapılan dizin yapısı) test toplama aşamasında (herhangi bir test yapılmadan önce) çalıştırılacaktır. Deneme yoluyla kendimi anlamak zorunda kaldı.
Daniel Goldfarb

Yanıtlar:


290

Bu doğru conftest.py kullanımı mı?

Evet öyle. Armatürler potansiyel ve ortak bir kullanımdır conftest.py. Tanımlayacağınız fikstürler test takımınızdaki tüm testler arasında paylaşılacaktır. Bununla birlikte, kökteki demirbaşları tanımlamak conftest.pyişe yaramaz olabilir ve bu demirbaşlar tüm testler tarafından kullanılmazsa testi yavaşlatır.

Başka kullanımları var mı?

Evet öyle.

  • Armatürler : Testler tarafından kullanılan statik veriler için armatürleri tanımlayın. Bu verilere, aksi belirtilmedikçe paketteki tüm testlerden erişilebilir. Bu, tüm testlere aktarılacak olan modüllerin yanı sıra veriler olabilir.

  • Harici eklenti yükleme : conftest.pyharici eklentileri veya modülleri içe aktarmak için kullanılır. Aşağıdaki global değişkeni tanımlayarak, pytest modülü yükleyecek ve test için kullanılabilir hale getirecektir. Eklentiler genellikle projenizde tanımlanan veya testlerinizde ihtiyaç duyulabilecek diğer modüllerdir. Ayrıca burada açıklandığı gibi bir dizi önceden tanımlanmış eklenti yükleyebilirsiniz .

    pytest_plugins = "someapp.someplugin"

  • Kancalar : Testlerinizi geliştirmek için kurulum ve sökme yöntemleri ve çok daha fazlası gibi kancaları belirleyebilirsiniz. Mevcut kanca seti için burayı okuyun . Misal:

    def pytest_runtest_setup(item):
         """ called before ``pytest_runtest_call(item). """
         #do some stuff`
  • Test kökü yolu : Bu biraz gizli bir özelliktir. conftest.pyKök yolunuzda tanımlayarak pytest, uygulama modüllerinizi belirtmeden tanımanız gerekir PYTHONPATH. Arka planda, py.test sys.pathkök yolunda bulunan tüm alt modülleri ekleyerek değiştirir .

Birden fazla conftest.py dosyasına sahip olabilir miyim?

Evet yapabilirsiniz ve test yapınızın biraz karmaşık olması şiddetle önerilir. conftest.pydosyalarının dizin kapsamı vardır. Bu nedenle, hedeflenmiş demirbaşlar ve yardımcılar oluşturmak iyi bir uygulamadır.

Bunu ne zaman yapmak isterdim? Örnekler takdir edilecektir.

Birkaç vaka sığabilir:

Belirli bir test grubu için bir takım alet veya kancalar oluşturma.

Kök / mod / conftest.py

def pytest_runtest_setup(item):
    print("I am mod")
    #do some stuff


test root/mod2/test.py will NOT produce "I am mod"

Bazı testler için bir dizi fikstür yüklemek , ancak diğerleri için değil.

Kök / mod / conftest.py

@pytest.fixture()
def fixture():
    return "some stuff"

Kök / mod2 / conftest.py

@pytest.fixture()
def fixture():
    return "some other stuff"

Kök / mod2 / test.py

def test(fixture):
    print(fixture)

"Başka şeyler" yazdıracak.

Kökten miras alınan geçersiz kılma kancaları conftest.py.

Kök / mod / conftest.py

def pytest_runtest_setup(item):
    print("I am mod")
    #do some stuff

Kök / conftest.py

def pytest_runtest_setup(item):
    print("I am root")
    #do some stuff

İçeride herhangi bir test çalıştırıldığında root/mod, sadece "Ben modum" yazdırılır.

conftest.py Burada daha fazla bilgi edinebilirsiniz .

DÜZENLE:

Farklı modüllerdeki bir dizi testten düz eski yardımcı işlevlere çağrılacak olursam ne olur? Onları bir conftest.py'ye koyarsam bunlar kullanılabilir mi? Yoksa bunları bir helpers.py modülüne koymalı ve test modüllerime aktarmalı ve kullanmalı mıyım?

conftest.pyYardımcılarınızı tanımlamak için kullanabilirsiniz . Ancak, ortak uygulamayı takip etmelisiniz. Yardımcılar en az içinde fikstür olarak kullanılabilir pytest. Örneğin testlerimde, testlerime bu şekilde enjekte ettiğim sahte bir redis yardımcısı var.

Kök / yardımcı / Redis / redis.py

@pytest.fixture
def mock_redis():
    return MockRedis()

Kök / testler / malzeme / conftest.py

pytest_plugin="helper.redis.redis"

Kök / testler / malzeme / test.py

def test(mock_redis):
    print(mock_redis.get('stuff'))

Bu, testlerinize serbestçe aktarabileceğiniz bir test modülü olacaktır. NOT potansiyel isim verebilecek redis.pyşekilde conftest.pysizin modül eğer redisdaha fazla test içerir. Ancak, bu uygulama belirsizlik nedeniyle önerilmez.

Kullanmak istiyorsanız conftest.py, o yardımcıyı kökünüze koyabilir conftest.pyve gerektiğinde enjekte edebilirsiniz.

Kök / test / conftest.py

@pytest.fixture
def mock_redis():
    return MockRedis()

Kök / testler / malzeme / test.py

def test(mock_redis):
    print(mock_redis.get(stuff))

Yapabileceğiniz başka bir şey, yüklenebilir bir eklenti yazmaktır. Bu durumda yardımcınız herhangi bir yere yazılabilir ancak sizin ve diğer potansiyel test çerçevelerinize kurulacak bir giriş noktası tanımlaması gerekir. Bkz bu .

Fikstür kullanmak istemiyorsanız, elbette basit bir yardımcı tanımlayabilir ve sadece ihtiyaç duyduğunuz her yerde eski eski içe aktarmayı kullanabilirsiniz.

Kök / test / yardımcı / redis.py

class MockRedis():
    # stuff

Kök / testler / malzeme / test.py

from helper.redis import MockRedis

def test():
    print(MockRedis().get(stuff))

Ancak, modül testin alt klasöründe olmadığından burada yolla ilgili sorunlarınız olabilir. __init__.pyYardımcınıza bir ekleyerek bunun (test edilmemiş) üstesinden gelebilmelisiniz

Kök / test / yardımcı / __ init__.py

from .redis import MockRedis

Veya sadece yardımcı modülü bilgisayarınıza ekleyerek PYTHONPATH.


ilk birim test modülüm, test_aaaaa.pyaslında fikstür kurulumu tamamlanmadan önce çalıştırmaya çalıştığı bir durumla karşılaşıyorum conftest.py. Bunun neden olabileceğine dair düşünceleriniz var mı?
user9074332

Conftest.py olmadan, test kök yolunuz sys.path dosyasına eklenmez ve "ModuleNotFoundError: 'foobar' adında bir modül yok" gibi hatalar görürsünüz.
Cale Sweeney

11

Geniş anlamda conftest.py, dizin başına yerel bir eklentidir. Burada dizine özgü kancaları ve fikstürleri tanımlarsınız. Benim durumumda bir proje belirli test dizinleri içeren bir kök dizini var. Bazı yaygın sihirler 'root' conftest.py içinde yer alır. Projeye özgü - kendi başlarına. Yaygın olarak kullanılmadıkları sürece armatürleri conftest.py'de saklamakta kötü bir şey göremiyorum (Bu durumda bunları doğrudan test dosyalarında tanımlamayı tercih ederim)


10

conftest.pyTestlerime enjekte ettiğim fikstürleri tanımlamak için dosyayı kullanıyorum , bu doğru kullanım conftest.pymı?

Evet , bir fikstür genellikle verileri birden çok teste hazır hale getirmek için kullanılır.

Başka kullanımları var mı?

Evet , fikstür pytestgerçek test işlevlerinden önce ve sonra da çalıştırılan bir işlevdir. Fikstürdeki kod, istediğiniz her şeyi yapabilir. Örneğin, bir fikstür, testlerin çalışması için bir veri kümesi almak için kullanılabilir veya bir fikstür, bir testi çalıştırmadan önce bir sistemi bilinen bir duruma getirmek için de kullanılabilir.

Birden fazla conftest.pydosyam olabilir mi? Bunu ne zaman yapmak isterdim?

İlk olarak, fikstürleri bireysel test dosyalarına koymak mümkündür. Ancak, fikstürleri birden çok test dosyası arasında paylaşmak conftest.pyiçin, tüm testler için merkezi bir yerde bulunan bir dosyayı kullanmanız gerekir . Fikstürler herhangi bir testle paylaşılabilir. Armatürün sadece o dosyadaki testler tarafından kullanılmasını istiyorsanız, ayrı ayrı test dosyalarına yerleştirilebilirler.

İkincisi, evet , conftest.pyen iyi testler dizininin alt dizinlerinde başka dosyalarınız olabilir . Bunu yaparsanız, bu alt düzey conftest.pydosyalarda tanımlanan fikstürler bu dizin ve alt dizinlerdeki testler için kullanılabilir olacaktır.

Son olarak, armatürleri conftest.pytest köküne koymak , tüm test dosyalarında kullanılabilir hale getirecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.