[Tutor] TDD: How to test input()?
Steven D'Aprano
steve at pearwood.info
Sat Oct 8 02:18:54 EDT 2016
On Fri, Oct 07, 2016 at 08:26:28PM -0500, boB Stepp wrote:
> I think I have this figured out, but I want to be certain I am doing
> it both correctly and in the preferred way. I have a need for a
> get_input() function and have written my first test for this function
> as follows:
Testing code that depends on user input is always tricky. There are a
few ways to deal with it:
(1) Denial. Just don't test that part of your code at all. That's not
ideal, but it may be "good enough" if any error in that code would be
obvious enough.
(2) Perform ad hoc non-automated tests that require user intavention.
That's a bit better but still not great.
(3) You can monkey-patch the input() function in your test:
import mymodule # module being tested
class MyTests(unittest.TestCase):
def test_get_input(self):
def myinput(prompt):
return "5"
mymodule.input = myinput
try:
result = mymodule.get_input("What number do you want?")
self.assertEqual(result, 5)
finally:
del mymodule.input
That's often a good solution for simple testing.
(4) Python 3 unittest library now includes support for mocking:
https://docs.python.org/3/library/unittest.mock.html
which lets you replace parts of your code with fake code ("mocks") which
are more easily tested, similar to the monkey-patch example in (3)
above. For an example, look at the test suite for the "code" module:
https://docs.python.org/3/library/code.html
https://hg.python.org/cpython/file/3.5/Lib/test/test_code_module.py
(5) Or you could manually monkey-patch sys.stdin as you do.
I haven't studied your code in detail to comment on it yet. Time
permitting, I shall do so later.
--
Steve
More information about the Tutor
mailing list