Re: [Tutor] TDD: How to test input()?
On 08/10/16 07:18, Steven D'Aprano wrote: > Testing code that depends on user input is always tricky. There are a > few ways to deal with it: > > (5) Or you could manually monkey-patch sys.stdin as you do. A variation on this that I have used is to read the input from stdin as usual but redirect stdin when you run the code: python test_input.py < testdata.txt That way I can use multiple sets of test data and run the tests using the different data sets. The test suite is then exercised by a simple shell script that runs against each test file in turn. I find that easier and more flexible than using a StringIO buffer. You can catch EOF errors in your test rig or write the tests to read a finite set of data and create the data to match. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] TDD: How to test input()?
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 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] TDD: How to test input()?
Oops! On Fri, Oct 7, 2016 at 8:26 PM, boB Steppwrote: > 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: > > class TestGetInput(unittest.TestCase): > '''Tests for the function get_input().''' > > def setUp(self): > '''Establish conditions for running these tests.''' > > # Redirect sys.stdin in order to test input functions. > self.old_stdin = sys.stdin > sys.stdin = StringIO('5') > > def test_get_input(self): > '''Test that get_input() returns the expected result.''' > > expected = 5 > draw2x2grid.get_input() > self.assertEqual(sys.stdin.getvalue(), expected) My brain was scrambled. The test_get_input(self) should instead be: def test_get_input(self): '''Test that get_input() returns the expected result.''' expected = 5 self.assertEqual(draw2x2grid.get_input(), expected) boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor