I like TDD, so I try to write my Black Box Test at first.
This is a python programme that deal with stdin and output to stdout like this (I try to write my own language that just deal with stdin and stdout):
$ python3 ./minor.py
>>> print, "hello\nthis is a good morning"
... hello
. this is a good morning
>>> $quit
But I can not mock the stdin and stdout. I try to use subprocess in Python but the Popen.stdout.read() is hanging for a EOF, which need the programme killed. Or the communicate() but it will kill my programme and it cannot deal with two or more input.
It upset me for 2+ days, I cannot find anything useful about mock or black-box test with stdin/stdout (It looks strange that I can test with browser but not stdin/stdout easily).
Thanks.
*** First Editing ***
I create a new unittest class to handle my class. It have a function to create a new Popen object.
I try to write to stdin and assert the stdout... But it is hanging just because it cannot find the EOF.
How should I deal with it to make it? Thanks for your help!
class TestFunc(unittest.TestCase):
def run_minor(self):
return Popen(['python3', './minor.py'],
stdin = PIPE,
stdout = PIPE,
stderr = PIPE,
text = True,
)
def test_print(self):
prop = self.run_minor()
self.assertEqual(prop.stdout.read(), '>>> ')
prop.stdin.write("print, 'this'")
self.assertEqual(prop.stdout.read(), '... this\n>>> ')
prop.stdin.write("$quit")
self.assertEqual(prop.stdout.read(), '')
prop.kill()
sys.stdinandsys.stdoutare just file-like objects, you can replace them with other file-like objects that behave however your tests require. There are cases in which you need to actually have overridden FD 0 and FD 1, butos.dup2()makes short work of those cases.input/output. By the way, I am thinking if use a function to handle input/output like a string is OK for me... input, then turn it to string and return a string, then output... Or build a class with state.