Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

py.test printing out full data in stack trace

Tags:

python

pytest

Currently when one of my tests fails, it prints out the arguments of the unit test followed by the stack trace. However, if the arguments are large JSON objects, the full object is not displayed. Is there a way to easily force py.test to not cut off the data? Example stack trace:

TestSpecialOfferDefaultContentUser.test_check_default_content_for_user[test_data0] 

self = <scripts.spof.test_01_special_offer_default_content_user.TestSpecialOfferDefaultContentUser instance at 0x00000000022CF8C8>
config = <merlin.lib.configuration_test.TestConfiguration object at 0x00000000022DD1D0>
test_data = {'amount_of_number_of_days_options': 6, 'available_for_guest': 'True', 'fl_password': 'password', 'fl_user': '[email protected]', ...}

@pytest.mark.parametrize("test_data", _test_cases_special_offer)
def test_check_default_content_for_user(self, config, test_data):
[...]
like image 739
Huniku Avatar asked Jul 18 '14 18:07

Huniku


People also ask

Can you print in pytest?

Allows to print extra content onto the PyTest reporting. This can be used for example to report sub-steps for long running tests, or to print debug information in your tests when you cannot debug the code.

What is verbose in pytest?

Verbosity. The -v flag controls the verbosity of pytest output in various aspects: test session progress, assertion details when tests fail, fixtures details with --fixtures , etc.

Where does pytest print to?

By default, pytest captures the output to sys. stdout/stderr and redirects it to a temporary file.


2 Answers

Good question.

Did not find command line switch to force complete printouts.

Searching and testing various command line options of py.test, I did not find any way to get full dictionary printout.

It is probably for good reason, having endless printout is not very useful.

Use assert message to get your own printout

While py.test does excellent job with useful messages explaining what went wrong, sometimes you have to take things to your own hands.

assert has optional argument with a message. If you use that, py.test printout is replaced by what you put into that message.

Having the file test_it.py:

def test_it():
    dct = {str(i): i for i in xrange(100)}
    assert dct == "Hi"


def test_it2():
    dct = {str(i): i for i in xrange(100)}
    assert dct == "Hi", str(dct) + " shall sound friendly"

you can try:

$ py.test

And you would see:

$ py.test
========================================== test session starts ===========================================
platform linux2 -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
collected 2 items

test_it.py FF

================================================ FAILURES ================================================
________________________________________________ test_it _________________________________________________

    def test_it():
        dct = {str(i): i for i in xrange(100)}
>       assert dct == "Hi"
E       assert {'0': 0, '1': 1, '10': 10, '11': 11, ...} == 'Hi'

test_it.py:3: AssertionError
________________________________________________ test_it2 ________________________________________________

    def test_it2():
        dct = {str(i): i for i in xrange(100)}
>       assert dct == "Hi", str(dct) + " shall sound friendly"
E       AssertionError: {'24': 24, '25': 25, '26': 26, '27': 27, '20': 20, '21': 21, '22': 22, '23': 23, '28': 28, '29': 29, '0': 0, '4': 4, '8': 8, '59': 59, '58': 58, '55': 55, '54': 54, '57': 57, '56': 56, '51'
: 51, '50': 50, '53': 53, '52': 52, '88': 88, '89': 89, '82': 82, '83': 83, '80': 80, '81': 81, '86': 86, '87': 87, '84': 84, '85': 85, '3': 3, '7': 7, '39': 39, '38': 38, '33': 33, '32': 32, '31': 31, '30': 30, '
37': 37, '36': 36, '35': 35, '34': 34, '60': 60, '61': 61, '62': 62, '63': 63, '64': 64, '65': 65, '66': 66, '67': 67, '68': 68, '69': 69, '2': 2, '6': 6, '99': 99, '98': 98, '91': 91, '90': 90, '93': 93, '92': 92
, '95': 95, '94': 94, '97': 97, '96': 96, '11': 11, '10': 10, '13': 13, '12': 12, '15': 15, '14': 14, '17': 17, '16': 16, '19': 19, '18': 18, '48': 48, '49': 49, '46': 46, '47': 47, '44': 44, '45': 45, '42': 42, '
43': 43, '40': 40, '41': 41, '1': 1, '5': 5, '9': 9, '77': 77, '76': 76, '75': 75, '74': 74, '73': 73, '72': 72, '71': 71, '70': 70, '79': 79, '78': 78} shall sound friendly

test_it.py:8: AssertionError
======================================== 2 failed in 0.02 seconds ========================================
like image 58
Jan Vlcinsky Avatar answered Oct 20 '22 00:10

Jan Vlcinsky


You're right, currently this can not be displayed, this is probably a feature request so please file a bug.

However the "standard" way to work around this is to simply rely on py.test's excellent output capture and simply print the argument explicitly during the test:

def test_foo(large_dict):
    pprint.pprint(large_dict)
    assert 0, 'Something went wrong'

This will result in the information being available in the rest report on failure.

like image 35
flub Avatar answered Oct 20 '22 01:10

flub