How to check standard input and standard output in Python Script using Unittest test?

I am trying to test a Python script (2.7), where I work with standard input (read using raw_input () and click with simple print), but I do not find how to do this, and I find this problem very simple.

This is the very very good code of my script:

def example():
    number = raw_input()
    print number

if __name__ == '__main__':
    example()

I want to write a unittest test to test this, but I do not find how to do it. I am trying with StringIO and other things, but I have not found a solution to make this very simple.

Does anyone have an idea?

PD: Of course, in a real script, I use data blocks with multiple rows and other data types.

Thank you very much.

EDIT:

, , StringIO, StringIO, from StringIO import StringIO ( , , ), , , .

, , ( ), : , script, , , , ...

- :

class Test(unittest.TestCase):
    ...
    #open file and process saving data like datablocks and results
    ...
    allTest = True
    for test in tests:
        stub_stdin(self, test.dataBlock)
        stub_stdouts(self)
        runScrip()
        if sys.stdout.getvalue() != test.expectResult:
            allTest = False

    self.assertEqual(allTest, True)

, , , unittest , , . , , , .

+4
1

sys.stdin sys.stdout . Python 3, StringIO, , Python 2.7 3.3+, Python 2 3 io ( , ).

, unittest.TestCase, ( ), sys.stdin/sys.stdout . :

import sys
import io
import unittest

stdin, , ( ) stdin, str:

def stub_stdin(testcase_inst, inputs):
    stdin = sys.stdin

    def cleanup():
        sys.stdin = stdin

    testcase_inst.addCleanup(cleanup)
    sys.stdin = StringIO(inputs)

stdout stderr:

def stub_stdouts(testcase_inst):
    stderr = sys.stderr
    stdout = sys.stdout

    def cleanup():
        sys.stderr = stderr
        sys.stdout = stdout

    testcase_inst.addCleanup(cleanup)
    sys.stderr = StringIO()
    sys.stdout = StringIO()

, testcase addCleanup, cleanup reset , , . , , , sys.stdout io.StringIO, , , .

. , :

class ExampleTestCase(unittest.TestCase): 

    def test_example(self):
        stub_stdin(self, '42')
        stub_stdouts(self)
        example()
        self.assertEqual(sys.stdout.getvalue(), '42\n')

, Python 2, , StringIO StringIO, Python 3 . , , io , , , / Unicode , (, print Python 2 , ). Python 2 3:

class StringIO(io.StringIO):
    """
    A "safely" wrapped version
    """

    def __init__(self, value=''):
        value = value.encode('utf8', 'backslashreplace').decode('utf8')
        io.StringIO.__init__(self, value)

    def write(self, msg):
        io.StringIO.write(self, msg.encode(
            'utf8', 'backslashreplace').decode('utf8'))

, unittest, Python 2, 3 ( print Python 3) stdio.

: stub_ setUp TestCase, .

, , mocks, stdin/stdout, , , .


, , , . - :

class Test(unittest.TestCase):

    def helper(self, data, answer, runner):
        stub_stdin(self, data)
        stub_stdouts(self)
        runner()
        self.assertEqual(sys.stdout.getvalue(), answer)
        self.doCleanups()  # optional, see comments below

    def test_various_inputs(self):
        data_and_answers = [
            ('hello', 'HELLOhello'),
            ('goodbye', 'GOODBYEgoodbye'),
        ]

        runScript = upperlower  # the function I want to test 

        for data, answer in data_and_answers:
            self.helper(data, answer, runScript)

, doCleanups, , , data_and_answers , , , , - , , stdio, , . , :

def upperlower():
    raw = raw_input()
    print (raw.upper() + raw),

, , , , : , TestCase assertEqual , . , , , , , /, , , , for ( , - , , , ). helper - , test, , . , - /, , .

:

StringIO, StringIO, , StringIO import StringIO ( , ), , .

, , , import io, io.StringIO, class StringIO(io.StringIO). , Python 2, Python 3, , , Python 2 (, ) 5 . , , , . , , from StringIO import StringIO , StringIO StringIO. from cStringIO import StringIO , C StringIO. , , (, , Python 3).

, script. , , ( , , "" , , Python , , , ( , ), ). , , , , , - , , , , ?:) , , .


, , , /, , SO, , , , . :

, , , unittest.mock, Python 3.3+, / backport pypi, , , , , ( ) . , unittest.mock.patch StringIO patching sys.stdout.

+4

Source: https://habr.com/ru/post/1650727/


All Articles