Jak mogę zobaczyć normalne wydruki utworzone podczas uruchamiania zapytania?

400

Czasami chcę po prostu wstawić kilka instrukcji drukowania do mojego kodu i zobaczyć, co zostanie wydrukowane, kiedy to wykonam. Mój zwykły sposób na „ćwiczenie” to z istniejącymi testami pytań. Ale kiedy je uruchamiam, nie widzę żadnego standardowego wyjścia (przynajmniej z PyCharm, mojego IDE).

Czy istnieje prosty sposób, aby zobaczyć standardowe wyjście podczas uruchamiania zapytania?

Des
źródło
Tylko w razie awarii czy zawsze?
17
-s wyłącza przechwytywanie na test
hpk42 19.01.13
3
@delnan - Chciałbym to zawsze widzieć
Des

Odpowiedzi:

51

W upvoted komentarzu do akceptowanej odpowiedzi , Joe pyta:

Czy jest jakiś sposób drukowania na konsoli ORAZ przechwytywania danych wyjściowych, aby były widoczne w raporcie programu Junit?

W UNIX jest to powszechnie określane jako teeing . Idealnie, teeing zamiast przechwytywania byłby domyślnym py.test. Idealnie, ani py.test, ani żadna istniejąca wtyczka py.test innej firmy (... o której wiem, w każdym razie ) obsługuje teeing - pomimo że Python trywialnie wspiera teeing out-of-the-box .

Łapanie małp py.test, aby zrobić coś nieobsługiwanego, nie jest trywialny. Dlaczego? Ponieważ:

  • Większość py.test funkcjonalność jest zamknięty za prywatny _pytestpakiet nie ma być importowany z zewnątrz. Próba zrobienia tego bez wiedzy o tym, co robisz, zwykle powoduje, że pytestpakiet publiczny podnosi niejasne wyjątki w czasie wykonywania. Bardzo dziękuję, test py. Naprawdę solidna architektura, którą tam masz.
  • Nawet jeśli zrobić dowiedzieć się, jak małpa-załatać prywatną _pytestAPI w sposób bezpieczny, trzeba to zrobić przed uruchomieniem publicznego pytesturuchomiony pakiet przez zewnętrznego py.testpolecenia. Nie możesz tego zrobić we wtyczce (np. W conftestmodule testowym najwyższego poziomu ). Zanim py.test leniwie zacznie dynamicznie importować wtyczkę, każda klasa py.test, którą chciałeś załatać, już dawno została utworzona - i nie masz dostępu do tej instancji. Oznacza to, że jeśli chcesz, aby łatka małpy została znacząco zastosowana, nie możesz już bezpiecznie uruchomić zewnętrznego py.testpolecenia. Zamiast tego musisz zawinąć uruchomienie tego polecenia za pomocą niestandardowych narzędzi konfiguracyjnychtest polecenie, które (w kolejności):
    1. Łata łata prywatny _pytestinterfejs API.
    2. Wywołuje funkcję publiczną w pytest.main()celu uruchomienia py.testpolecenia.

Ta odpowiedź zawiera łatki py.test -si --capture=noopcje przechwytywania stderr, ale nie stdout. Domyślnie te opcje nie wychwytują stderr ani stdout. Oczywiście nie jest to zbyt ekscytujące. Ale każda wielka podróż zaczyna się od żmudnego prequela, o którym wszyscy zapomną za pięć lat.

Czemu to robić? Teraz ci powiem. Mój pakiet testowy oparty na py.test zawiera powolne testy funkcjonalne. Wyświetlanie standardowego przebiegu tych testów jest pomocne i uspokajające, zapobiegając sięgnięciu po leycec,killall -9 py.test gdy kolejny długotrwały test funkcjonalny nic nie robi przez wiele tygodni. Wyświetlanie stderr tych testów uniemożliwia jednak py.test zgłaszanie śledzenia wyjątków w przypadku niepowodzeń testu. Co jest całkowicie nieprzydatne. Dlatego zmuszamy py. Test do przechwytywania stderr, ale nie stdout.

Zanim do tego przejdziemy, ta odpowiedź zakłada, że ​​masz już niestandardowe testpolecenie setuptools wywołujące py.test. Jeśli nie, zapoznaj się z podsekcją Ręczna integracja dobrze napisanej strony dobrych praktyk py.test .

Czy nie instalować pytest-runner , a setuptools osób trzecich plugin zapewnienie zwyczaj setuptools testkomendy również powołując py.test. Jeśli pytest-runner jest już zainstalowany, prawdopodobnie będziesz musiał odinstalować ten pakiet pip3, a następnie zastosować ręczne podejście opisane powyżej.

Zakładając, że postępowałeś zgodnie z instrukcjami podanymi powyżej w Integracji ręcznej , twoja baza kodu powinna teraz zawierać PyTest.run_tests()metodę. Zmodyfikuj tę metodę, aby przypominała:

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)

Aby włączyć tę łatkę dla małp, uruchom py.test w następujący sposób:

python setup.py test -a "-s"

Stderr, ale nie stdout, zostanie teraz przechwycony. Sprytne!

Rozciągnięcie powyższej łatki małpy na tee stdout i stderr pozostawia się jako ćwiczenie dla czytelnika z beczką pełną wolnego czasu.

Cecil Curry
źródło
33

Podczas uruchamiania testu skorzystaj z -sopcji. Wszystkie instrukcje drukowania exampletest.pyzostaną wydrukowane na konsoli po uruchomieniu testu.

py.test exampletest.py -s
Letnia zabawa
źródło
31

Zgodnie z dokumentacją pytest wersja 3 pytest może tymczasowo wyłączyć przechwytywanie w teście:

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')
Roman Susi
źródło
20

pytest przechwytuje stdout z poszczególnych testów i wyświetla je tylko pod pewnymi warunkami, wraz z podsumowaniem testów, które drukuje domyślnie.

Dodatkowe informacje podsumowujące można wyświetlić za pomocą opcji „-r”:

pytest -rP

pokazuje przechwycony wynik pozytywnych testów.

pytest -rx

pokazuje przechwycone wyjście nieudanych testów (zachowanie domyślne).

Formatowanie wyjścia jest ładniejsze przy pomocy -r niż przy -s.

Sunthar
źródło
2
To jest rzeczywista odpowiedź, której szukałem! Dziękuję Ci. (Po
pojawieniu się standardowego wyjścia
18

Spróbuj pytest -s -v test_login.pyuzyskać więcej informacji w konsoli.

-v to jest krótkie --verbose

-s oznacza „wyłącz wszystkie przechwytywanie”



Alex Makarenko
źródło
1
jeśli korzystasz z pliku pytest.ini, możesz użyć: addopts = -s -v pliki python = test_login.py
timj98
4

Jeśli używasz PyCharm IDE, możesz uruchomić ten test indywidualny lub wszystkie testy za pomocą paska narzędzi Uruchom. Okno narzędzia Uruchom wyświetla dane wyjściowe wygenerowane przez aplikację i można wyświetlić wszystkie instrukcje drukowania w ramach wyników testu.

Gemini Jain
źródło
Czy wiesz, jak zrobić drukowanie PyCharm podczas testu? (zamiast po zdaniu testu)
Alexandre Huat
3

pytest --capture=tee-syszostał niedawno dodany. Możesz przechwytywać, a także wyświetlać dane wyjściowe na stdout / err.

meonstackexchange
źródło
-4

Inne odpowiedzi nie działają. Jedyny sposób, aby zobaczyć przechwycony wyjście wykorzystuje następujące flagi:

pytest --show-capture all

aaa90210
źródło
6
--show-capture=alljest wartością domyślną. Dodanie go nic nie ma wpływu.
hoefling