Data Test as CI

python
Unit Test with Pytest. I want to display a full information rich string into my CI Log, but it is trimmed by Python. Here is a simple fix to make it display full string in the log file.
Author

noklam

Published

March 17, 2021

I am running test with great_expectations that validate data in UAT and production server with CI, so it would be nice if the log can capture this.

I created a custom error class that would do the job, however, pytest truncated my AssertionError since it is quite long.

I am using pytest magic from https://github.com/akaihola/ipython_pytest which allow me to run pytest in a Jupyter notebook cell.

It is quite simple with a few tens of lines.

import os
import shlex
import sys
from pathlib import Path

import tempfile
from IPython.core import magic
from pytest import main as pytest_main


TEST_MODULE_NAME = '_ipytesttmp'

def pytest(line, cell):
    with tempfile.TemporaryDirectory() as root:
        oldcwd = os.getcwd()
        os.chdir(root)
        tests_module_path = '{}.py'.format(TEST_MODULE_NAME)
        try:
            Path(tests_module_path).write_text(cell)
            args = shlex.split(line)
            os.environ['COLUMNS'] = '80'
            pytest_main(args + [tests_module_path])
            if TEST_MODULE_NAME in sys.modules:
                del sys.modules[TEST_MODULE_NAME]
        finally:
            os.chdir(oldcwd)

def load_ipython_extension(ipython):
    magic.register_cell_magic(pytest)
Writing ipython_pytest.py
# !pip install pytest
The ipython_pytest extension is already loaded. To reload it, use:
  %reload_ext ipython_pytest
def test_long_assertion_error():
    x = "placeholder"
    expect = "abcdefg\n"*20 # Long string
    assert x == expect
============================= test session starts =============================
platform win32 -- Python 3.8.3, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: C:\Users\channo\AppData\Local\Temp\tmpohw9e_9w
collected 1 item

_ipytesttmp.py F                                                         [100%]

================================== FAILURES ===================================
__________________________ test_long_assertion_error __________________________

    def test_long_assertion_error():
        x = "placeholder"
        expect = "abcdefg\n"*20 # Long string
>       assert x == expect
E       AssertionError: assert 'placeholder' == 'abcdefg\nabc...fg\nabcdefg\n'
E         + placeholder
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg...
E         
E         ...Full output truncated (15 lines hidden), use '-vv' to show

_ipytesttmp.py:5: AssertionError
=========================== short test summary info ===========================
FAILED _ipytesttmp.py::test_long_assertion_error - AssertionError: assert 'pl...
============================== 1 failed in 0.06s ==============================

You can see that pytest truncated my error with ... Here is how I solve ths issue

def test_long_assertion_error():
    x = "placeholder"
    expect = "abcdefg\n"*20 # Long string
    assert x == expect
============================= test session starts =============================
platform win32 -- Python 3.8.3, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- c:\programdata\miniconda3\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\channo\AppData\Local\Temp\tmpyic4vcra
collecting ... collected 1 item

_ipytesttmp.py::test_long_assertion_error FAILED                         [100%]

================================== FAILURES ===================================
__________________________ test_long_assertion_error __________________________

    def test_long_assertion_error():
        x = "placeholder"
        expect = "abcdefg\n"*20 # Long string
>       assert x == expect
E       AssertionError: assert 'placeholder' == ('abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n'\n 'abcdefg\n')
E         + placeholder
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg
E         - abcdefg

_ipytesttmp.py:5: AssertionError
=========================== short test summary info ===========================
FAILED _ipytesttmp.py::test_long_assertion_error - AssertionError: assert 'pl...
============================== 1 failed in 0.06s ==============================