Pytest çalışması sırasında oluşturulan normal baskı çıktısını nasıl görebilirim?


400

Bazen sadece koduma bazı baskı ifadeleri eklemek ve bunu yaparken ne yazdırılır görmek istiyorum. Her zamanki gibi "egzersiz" için mevcut pytest testleri ile. Ama bunları çalıştırdığımda, herhangi bir standart çıktı göremiyorum (en azından PyCharm, IDE içinden).

Bir pytest çalışması sırasında standart çıktıyı görmenin basit bir yolu var mı?


Sadece başarısız mı yoksa her zaman mı?

17
-s test başına yakalamayı devre dışı bırakır
hpk42

3
@delnan - Her zaman görmek istiyorum
Des

Yanıtlar:



51

Bir In upvoted yorumun için kabul cevap , Joe sorar:

Konsolda yazdırmanın VE çıktıyı junit raporunda görünecek şekilde yakalamanın herhangi bir yolu var mı ?

UNIX'te buna yaygın olarak titting denir . İdeal olarak, yakalama yerine titting, py.test varsayılanı olacaktır. İdeal olmayan bir şekilde, ne py.test ne de mevcut herhangi bir üçüncü taraf py.test eklentisi (... zaten bildiğim ), Python'un kutudan çıkma işlemini önemsiz bir şekilde desteklemesine rağmen, boyun eğmeyi desteklemez .

Maymun yamalı py.test desteklenmeyen bir şey yapmak için önemsiz değildir. Neden? Çünkü:

  • Çoğu py.test işlevselliği özel arkasında kilitli _pytestpaketin değil dışarıdan ithal edilmek istenen. Ne yaptığınızı bilmeden bunu yapmaya çalışmak, genel pytestpaketin çalışma zamanında belirsiz istisnalar ortaya çıkarmasına neden olur. Çok teşekkürler, py.test. Gerçekten sağlam bir mimari.
  • Eğer bile yapmak için özel maymun-yama nasıl saptamayla _pytestgüvenli bir şekilde API, bunu yapmak zorunda önce kamu çalışan pytestharici tarafından paket çalıştırmak py.testkomutu. Sen olamaz bir eklenti bunu (örneğin üst düzey bir conftesttest paketi modülü). Zaman py.test lazily dinamik eklentinizi ithal civarında olur ederek, herhangi py.test sınıfı maymun yama istedim çoktan örneği olmuştur - ve do not o örneğe erişebilirler. Bu, maymun yamanızın anlamlı bir şekilde uygulanmasını istiyorsanız, harici py.testkomutu artık güvenli bir şekilde çalıştıramayacağınız anlamına gelir . Bunun yerine, bu komutun çalışmasını özel bir kurulum araçlarıyla sarmanız gerekirtest (sırayla) komutu:
    1. Monkey, özel _pytestAPI'yi yamalar .
    2. Komutu pytest.main()çalıştırmak için genel işlevi py.testçağırır.

Bu cevap maymun yamaları py.test's -sve --capture=nostderr yakalama seçenekleri ama stdout değil . Varsayılan olarak, bu seçenekler ne stderr ne de stdout'u yakalamaz. Tabii ki bu pek de yorucu değil. Ancak her büyük yolculuk, beş yıl içinde herkesin unutduğu can sıkıcı bir başlangıçla başlar.

Bunu neden yaptın? Şimdi söyleyeyim. Teste dayalı test takımım yavaş fonksiyonel testler içeriyor. Bu testlerin stdout'unun görüntülenmesi yararlı ve güven verici, leycec'inkillall -9 py.test henüz uzun süren başka bir fonksiyonel testin haftalarca bir şey yapamaması için ulaşmasını önler . Bununla birlikte, bu testlerin stderr'inin görüntülenmesi, py.test'in test hatalarıyla ilgili istisna geri bildirimlerini bildirmesini önler. Bu tamamen yararsızdır. Bu nedenle, stderr'i yakalamak için py.test'i zorlarız ama stdout'u değil .

Bu cevaba ulaşmadan önce, py.test'i testçağıran özel bir setuptools komutuna sahip olduğunuzu varsayar . Bunu yapmazsanız , py.test'in iyi yazılmış İyi Uygulamalar sayfasının Manuel Entegrasyon alt bölümüne bakın.

Do not install pytest-koşucu , bir üçüncü taraf Setuptools özel Setuptools sağlayan eklentisi testde py.test yürütmesini komutu. Pytest-runner zaten yüklenmişse, muhtemelen bu pip3 paketini kaldırmanız ve daha sonra yukarıdakine bağlı manuel yaklaşımı benimsemeniz gerekir.

Yukarıda vurgulanan Manuel Entegrasyon'daki talimatları izlediğinizi varsayarsak , kod tabanınızın şimdi bir PyTest.run_tests()yöntem içermesi gerekir . Bu yöntemi aşağıdakine benzer şekilde değiştirin:

class PyTest(TestCommand):
             .
             .
             .
    def run_tests(self):
        # Import the public "pytest" package *BEFORE* the private "_pytest"
        # package. While importation order is typically ignorable, imports can
        # technically have side effects. Tragicomically, that is the case here.
        # Importing the public "pytest" package establishes runtime
        # configuration required by submodules of the private "_pytest" package.
        # The former *MUST* always be imported before the latter. Failing to do
        # so raises obtuse exceptions at runtime... which is bad.
        import pytest
        from _pytest.capture import CaptureManager, FDCapture, MultiCapture

        # If the private method to be monkey-patched no longer exists, py.test
        # is either broken or unsupported. In either case, raise an exception.
        if not hasattr(CaptureManager, '_getcapture'):
            from distutils.errors import DistutilsClassError
            raise DistutilsClassError(
                'Class "pytest.capture.CaptureManager" method _getcapture() '
                'not found. The current version of py.test is either '
                'broken (unlikely) or unsupported (likely).'
            )

        # Old method to be monkey-patched.
        _getcapture_old = CaptureManager._getcapture

        # New method applying this monkey-patch. Note the use of:
        #
        # * "out=False", *NOT* capturing stdout.
        # * "err=True", capturing stderr.
        def _getcapture_new(self, method):
            if method == "no":
                return MultiCapture(
                    out=False, err=True, in_=False, Capture=FDCapture)
            else:
                return _getcapture_old(self, method)

        # Replace the old with the new method.
        CaptureManager._getcapture = _getcapture_new

        # Run py.test with all passed arguments.
        errno = pytest.main(self.pytest_args)
        sys.exit(errno)

Bu maymun yamasını etkinleştirmek için py.test'i aşağıdaki gibi çalıştırın:

python setup.py test -a "-s"

Stderr ancak stdout değil şimdi yakalanacak. Şık!

Yukarıdaki maymun yamasını tee stdout ve stderr'e genişletmek, boş zaman dolu bir varil ile okuyucuya bir egzersiz olarak bırakılır.


33

Testi çalıştırırken -sseçeneği kullanın. exampletest.pyTest çalıştırıldığında içindeki tüm yazdırma ifadeleri konsolda yazdırılır.

py.test exampletest.py -s

31

Pytest belgelerine göre, pytest 3 sürümü bir testte yakalamayı geçici olarak devre dışı bırakabilir:

def test_disabling_capturing(capsys):
    print('this output is captured')
    with capsys.disabled():
        print('output not captured, going directly to sys.stdout')
    print('this output is also captured')

20

pytest stdout'u bireysel testlerden yakalar ve bunları varsayılan olarak yazdırdığı testlerin özeti ile birlikte yalnızca belirli koşullarda görüntüler.

Ekstra özet bilgi '-r' seçeneği kullanılarak gösterilebilir:

pytest -rP

geçen testlerin yakalanan çıktısını gösterir.

pytest -rx

başarısız testlerin yakalanan çıktısını gösterir (varsayılan davranış).

Çıktının biçimlendirmesi, -s ile -s'den daha güzel.


2
Aradığım gerçek cevap bu! Teşekkür ederim. ( Test sonucundan SONRA
stdoutun gelmesi istenir

18

pytest -s -v test_login.pyKonsolda daha fazla bilgi deneyin .

-v kısa --verbose

-s 'tüm yakalamayı devre dışı bırak' anlamına gelir




1
pytest.ini dosyasını kullanıyorsanız şunları kullanabilirsiniz: addopts = -s -v python_files = test_login.py
timj98

4

PyCharm IDE kullanıyorsanız, Çalıştır araç çubuğunu kullanarak bu tek tek testi veya tüm testleri çalıştırabilirsiniz. Çalıştırma aracı penceresi uygulamanız tarafından oluşturulan çıktıyı görüntüler ve test çıktısının bir parçası olarak oradaki tüm yazdırma ifadelerini görebilirsiniz.


Test çalışırken PyCharm'ın nasıl yazdırılacağını biliyor musunuz? (test geçtikten sonra)
Alexandre Huat

3

pytest --capture=tee-sysyakın zamanda eklendi. Stdout / err üzerindeki görüntüyü yakalayabilir ve görebilirsiniz.


-4

Diğer cevaplar işe yaramıyor. Sadece yakalanan çıkışı görmek için bir yol izleyen bayrağını kullanıyor:

pytest - hepsini göster


6
--show-capture=allvarsayılan değerdir. Eklemek hiçbir şeyi etkilemez.
Hoefling
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.