2014-07-07 10 views
57

Sto provando a utilizzare Test-Driven Development con il modulo pytest. pytest non sarà print alla console quando scrivo print.Come stampare su console in Py Test?

Io uso py.test my_tests.py di farlo funzionare ...

La documentation sembra dire che dovrebbe funzionare in modo predefinito: http://pytest.org/latest/capture.html

Ma:

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. 

Nulla viene stampato al mio standard output console (solo i normali progressi e quanti test hanno superato/fallito).

e lo script che sto testando contiene stampa:

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

In unittest modulo, tutto viene stampato di default, che è esattamente quello che mi serve. Tuttavia, desidero utilizzare pytest per altri motivi. Sembra una funzionalità di base che forse mi manca !?

Qualcuno sa come visualizzare le istruzioni di stampa?

+0

Forse lo stdout viene sovrascritto. Cosa succede se usi 'sys.stdout.write (" Test ")'? Che ne dite di 'sys .__ stdout __. Write (" Test ")'? Quest'ultimo dovrebbe sempre scrivere sullo stdout definito dal sistema, che dovrebbe essere la console. Se i due comandi fanno cose diverse, allora stdout viene cambiato; se fanno la stessa cosa, allora il problema è un'altra cosa. – TheSoundDefense

risposta

77

Per impostazione predefinita, py.test acquisisce il risultato dello standard in modo che possa controllare come viene stampato. Se non lo facesse, emetterebbe un sacco di testo senza il contesto di quale test ha stampato quel testo.

Tuttavia, se un test non riesce, includerà una sezione nel rapporto risultante che mostra ciò che è stato stampato per standard in quel particolare test.

Per esempio,

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

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

risultati nel seguente output:

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

nota la sezione Captured stdout.

Se si desidera visualizzare le istruzioni print mentre vengono eseguite, è possibile passare il flag -s a py.test. Tuttavia, si noti che a volte può essere difficile da analizzare.

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

Utilizzando -s opzione stamperà in uscita di tutte le funzioni, che possono essere troppo.

Se avete bisogno di particolare uscita, la pagina doc lei ha citato offre alcuni suggerimenti:

  1. Inserire assert False, "dumb assert to make PyTest print my stuff" al termine della funzione, e vedrete la vostra uscita a causa di test fallito.

  2. Hai oggetto speciale passati a voi da PyTest, e si può scrivere l'output in un file di ispezionare in un secondo momento, come

    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) 
    

    È possibile aprire i file out e err in una scheda separata e lascia che l'editor lo aggiorni automaticamente per te, oppure fai un semplice comando di shell py.test; cat out.txt per eseguire il test.

Questo è piuttosto modo hacker per fare cose, ma può essere è la roba che serve: dopo tutto, TDD si vuol dire pasticciare con cose e lasciare pulito e silenzioso quando è pronto :-).

5

Avevo bisogno di stampare avvertenze importanti sui test saltati esattamente quando PyTest ha smorzato letteralmente tutto.

non volevo fallire un test per inviare un segnale, così ho fatto un hack come segue:

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) 

Il modulo atexit mi permette di stampare roba dopoPyTest rilasciato i flussi in uscita. L'output è la seguente:

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

messaggio viene stampato anche quando PyTest è in modalità silenziosa, ed è non stampato se si esegue cose con py.test -s, quindi tutto è testato bene già.

1

Secondo lo pytest docs, pytest --capture=sys dovrebbe funzionare. Se si desidera acquisire standard all'interno di un test, fare riferimento al dispositivo di capsys.