Pytest'te konsola nasıl yazdırılır?


175

TDD (test odaklı geliştirme) ile kullanmaya çalışıyorum pytest. kullandığımda konsola pytestgitmeyecek .printprint

pytest my_tests.pyÇalıştırmak için kullanıyorum .

documentation: Varsayılan olarak çalışması gerektiğini söylemek gibi görünüyor http://pytest.org/latest/capture.html

Fakat:

import myapplication as tum

class TestBlogger:

    @classmethod
    def setup_class(self):
        self.user = "alice"
        self.b = tum.Blogger(self.user)
        print "This should be printed, but it won't be!"

    def test_inherit(self):
        assert issubclass(tum.Blogger, tum.Site)
        links = self.b.get_links(posts)
        print len(links)   # This won't print either.

Standart çıktı konsoluma hiçbir şey yazdırılmıyor (sadece normal ilerleme ve kaç testin başarılı / başarısız olduğu).

Ve test ettiğim script baskı içeriyor:

class Blogger(Site):
    get_links(self, posts):
        print len(posts)   # It won't get printed in the test.

In unittestmodülü, her şey tam olarak neye ihtiyacım olan varsayılan olarak basılmış olur. Ancak pytestbaşka nedenlerle kullanmak istiyorum .

Baskı bildirimlerinin nasıl gösterileceğini bilen var mı?


1
Belki stdout'un üzerine yazılıyor. Kullanırsan ne olur sys.stdout.write("Test")? Nasıl sys.__stdout__.write("Test")? İkincisi her zaman konsol olması gereken sistem tanımlı stdout'a yazmalıdır. İki komut farklı şeyler yaparsa, stdout değiştirilir; aynı şeyi yaparlarsa, sorun başka bir şeydir.
TheSoundDefense

Yanıtlar:


205

Varsayılan py.testolarak, standart çıkış sonucunu yakalar, böylece nasıl yazdırılacağını kontrol edebilir. Bunu yapmadıysa, testin o metni yazdırdığı bağlam olmadan çok fazla metin yayınlardı.

Ancak, bir test başarısız olursa, sonuç raporunda söz konusu testte neyin standart olarak yazdırıldığını gösteren bir bölüm bulunur.

Örneğin,

def test_good():
    for i in range(1000):
        print(i)

def test_bad():
    print('this should fail!')
    assert False

Aşağıdaki çıktıdaki sonuçlar:

>>> py.test tmp.py
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py .F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
------------------------------- Captured stdout --------------------------------
this should fail!
====================== 1 failed, 1 passed in 0.04 seconds ======================

Captured stdoutBölümü not edin .

printİfadeleri yürütüldüklerinde görmek istiyorsanız, -sbayrağa iletebilirsiniz py.test. Ancak, bunun ayrıştırılması bazen zor olabilir.

>>> py.test tmp.py -s
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py 0
1
2
3
... and so on ...
997
998
999
.this should fail!
F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
====================== 1 failed, 1 passed in 0.02 seconds ======================

2
Son derece pratik. İyi iş!
cmc

1
hmm ... hala yazılı beyanlarımı kaydetmiyor
Tim Boland

68

-sSeçeneği kullanmak , çok fazla olabilecek tüm işlevlerin çıktısını yazdırır.

Belirli bir çıktıya ihtiyacınız varsa, bahsettiğiniz doküman sayfası birkaç öneri sunar:

  1. assert False, "dumb assert to make PyTest print my stuff"İşlevinizin sonuna yerleştirin ve başarısız test nedeniyle çıkışınızı göreceksiniz.

  2. PyTest tarafından size iletilen özel bir nesneniz var ve çıktıyı daha sonra incelemek için bir dosyaya yazabilirsiniz, örneğin

    def test_good1(capsys):
        for i in range(5):
            print i
        out, err = capsys.readouterr()
        open("err.txt", "w").write(err)
        open("out.txt", "w").write(out)

    outVe errdosyalarını ayrı bir sekmede açabilir ve düzenleyicinin sizin için otomatik olarak yenilemesine izin verebilir veya py.test; cat out.txttestinizi çalıştırmak için basit bir kabuk komutu yapabilirsiniz .

Bu bir şeyler yapmak için oldukça hackish bir yol, ama ihtiyacınız olan şeyler olabilir: sonuçta, TDD şeylerle uğraşmak ve hazır olduğunda temiz ve sessiz bırakmak anlamına gelir :-).


sürüm 1. deneme pytest 3.8.1 ile ne yazık ki sadece test fonksiyon bloğunu yazdırır, ancak baskı ifadeleri çıktı :( bunun için başka hileler?
UV

@UV - İşlevi kullanmak yerine , assert deyiminde virgülden sonraprint() yazdırmak istediğiniz değişkeni veya iletiyi koymalısınız . Örn , pitorya raporundaki değerini 'yazdıracak' . assert False, what_are_youwhat_are_you
Mart Van de Ven

43

Kısa cevap

-sSeçeneği kullanın :

pytest -s

Ayrıntılı cevap

Gönderen docs :

Testin yürütülmesi sırasında stdout ve stderr'a gönderilen herhangi bir çıktı yakalanır. Bir test veya kurulum yöntemi başarısız olursa, yakalanan çıktısı genellikle hata izleme ile birlikte gösterilir.

pytestseçeneği vardır --capture=methodki burada method: her test yöntemi yakalama ve aşağıdakilerden biri olabilir fd, sysya da no. pytestayrıca -sbir kısayol olan seçeneğe de sahiptir --capture=nove bu, yazdırma ifadelerinizi konsolda görmenizi sağlayan seçenektir.

pytest --capture=no     # show print statements in console
pytest -s               # equivalent to previous command

Yakalama yöntemlerini ayarlama veya yakalamayı devre dışı bırakma

pytestYakalamayı gerçekleştirmenin iki yolu vardır :

  1. dosya tanımlayıcı (FD) düzeyi yakalama (varsayılan): İşletim sistemi dosya tanımlayıcıları 1 ve 2'ye giden tüm yazma işlemleri yakalanır.

  2. sys seviyesi yakalama : Yalnızca Python dosyalarına yazar sys.stdout ve sys.stderr yakalanır. Dosya yazımcılarına yazma işlemi yapılmaz.

pytest -s            # disable all capturing
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
pytest --capture=fd  # also point filedescriptors 1 and 2 to temp file

17

Ben tam olarak ne zaman Atlanan testler hakkında önemli uyarı yazdırmak için gerekli PyTestanlamıyla kapatılabilir her şeyi .

Bir sinyal göndermek için bir testte başarısız olmak istemedim, bu yüzden aşağıdaki gibi bir hack yaptım:

def test_2_YellAboutBrokenAndMutedTests():
    import atexit
    def report():
        print C_patch.tidy_text("""
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.""")
    if sys.stdout != sys.__stdout__:
        atexit.register(report)

atexitModül beni şeyler yazdırmak için izin verir sonra PyTest çıkış akışları yayınladı. Çıktı aşağıdaki gibi görünüyor:

============================= test session starts ==============================
platform linux2 -- Python 2.7.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /media/Storage/henaro/smyth/Alchemist2-git/sources/C_patch, inifile: 
collected 15 items 

test_C_patch.py .....ssss....s.

===================== 10 passed, 5 skipped in 0.15 seconds =====================
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.
~/.../sources/C_patch$

İleti bile yazdırılır PyTestsessiz modda edilir ve değil sizinle şeyler çalıştırırsanız basılmış py.test -sher şey zaten güzel test edilir, böylece.


1
Özel test metriklerini çıktılamak için mükemmeldir.
z0r


2

Başlangıçta buraya PyTestbirim testini çalıştırırken / hata ayıklarken VSCode konsolunda nasıl baskı yapacağımı bulmak için buraya geldim . Bu, aşağıdaki launch.jsonyapılandırma ile yapılabilir . Verilen .venvsanal ortam klasörünü.

    "version": "0.2.0",
    "configurations": [
        {
            "name": "PyTest",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "pythonPath": "${config:python.pythonPath}",
            "module": "pytest",
            "args": [
                "-sv"
            ],
            "cwd": "${workspaceRoot}",
            "env": {},
            "envFile": "${workspaceRoot}/.venv",
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit",
                "RedirectOutput"
            ]
        }
    ]
}
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.