Re: [Tutor] Using unittest module for Test Driven Development
On 2014-08-25 01:10, Marc Tompkins wrote: On Mon, Aug 25, 2014 at 12:04 AM, Alex Kleider wrote: I appreciate your further elucidation, like your 'sledge hammer' metaphor and thank you for the fragility warning. I expect within such a limited scope, the dangers are not great. As someone who has been burned by this sort of thinking, please allow me to urge you: get into good habits now! At various points in my career when I've been learning a new language/technology/paradigm, I've decided to take shortcuts when writing my early "toy" programs. Unfortunately, in several cases, my "toy" programs ended up evolving into production code - shortcuts and all. In particular, I used to assume that my code - since it was either a learning exercise or a utility for myself alone - would only ever run in a single-user/single-tasking environment, and that when I wrote the "real" program later (in my copious free time) I would take the necessary precautions. Please, take a fool's advice: always assume that any program you write (more complex than "Hello world") will eventually be running in a busy environment, or that your user will manage to invoke five copies of it instead of one, or... Thanks for the sage advice; so much to learn. Since this is in a unittest module, it's unlikely that it'll get out into the sort of situation you describe, n'est pas? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using unittest module for Test Driven Development
On Mon, Aug 25, 2014 at 12:04 AM, Alex Kleider wrote: > I appreciate your further elucidation, like your 'sledge hammer' metaphor and > thank you for the fragility warning. I expect within such a limited scope, > the dangers are not great. As someone who has been burned by this sort of thinking, please allow me to urge you: get into good habits now! At various points in my career when I've been learning a new language/technology/paradigm, I've decided to take shortcuts when writing my early "toy" programs. Unfortunately, in several cases, my "toy" programs ended up evolving into production code - shortcuts and all. In particular, I used to assume that my code - since it was either a learning exercise or a utility for myself alone - would only ever run in a single-user/single-tasking environment, and that when I wrote the "real" program later (in my copious free time) I would take the necessary precautions. Please, take a fool's advice: always assume that any program you write (more complex than "Hello world") will eventually be running in a busy environment, or that your user will manage to invoke five copies of it instead of one, or... ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using unittest module for Test Driven Development
On 2014-08-24 21:30, Danny Yoo wrote: Is there a way that I can provide the file name command line parameters to compare.py so that its get_args function can be tested? sys.argv is writeable, or better still, provide get_args() an optional argument to use instead of sys.argv.o I don't understand what you mean by "sys.argv is writeable". Hi Alex, I think Steven's suggestion to have get_args() take in an explicit args argument makes the most sense: it allows the function to be testable. If the behavior of the "function" depends on something outside of the function, making that thing an explicit parameter allows you to capture it. It makes the free variable something under your control. What "sys.argv is writeable" means is that you can take a sledgehammer approach: you can save the old value of sys.argv somewhere in another temporary variable, assign sys.argv to the test value, do your tests, and then assign the original value back to sys.argv. But this approach is very fragile: anything else that depends on sys.argv can suddenly stop working. Thanks, Danny; yes, as I spent more time looking over Steven's suggested approach I began to understand what he meant. I appreciate your further elucidation, like your 'sledge hammer' metaphor and thank you for the fragility warning. I expect with in such a limited scope, the dangers are not great. Cheers, AlexK ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using unittest module for Test Driven Development
>>> Is there a way that I can provide the file name command line parameters >>> to compare.py so that its get_args function can be tested? >> >> sys.argv is writeable, or better still, provide get_args() an optional >> argument to use instead of sys.argv.o > > > I don't understand what you mean by "sys.argv is writeable". Hi Alex, I think Steven's suggestion to have get_args() take in an explicit args argument makes the most sense: it allows the function to be testable. If the behavior of the "function" depends on something outside of the function, making that thing an explicit parameter allows you to capture it. It makes the free variable something under your control. What "sys.argv is writeable" means is that you can take a sledgehammer approach: you can save the old value of sys.argv somewhere in another temporary variable, assign sys.argv to the test value, do your tests, and then assign the original value back to sys.argv. But this approach is very fragile: anything else that depends on sys.argv can suddenly stop working. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using unittest module for Test Driven Development
Thank you very much, Steven. This is just the help I needed. Forgive me for causing confusion- I pared down my code for presentation but not enough and also left the names which now out of context, don't make sense. In line explanations provided below although it would probably be of little interest. You did ask so I feel I owe you an explanation. Gratefully, Alex On 2014-08-24 18:57, Steven D'Aprano wrote: On Sun, Aug 24, 2014 at 05:23:35PM -0700, Alex Kleider wrote: Given $ cat compare.py #!/usr/bin/env python3 import os import sys def get_args(): try: args = sys.argv[1:] except IndexError: return return [arg for arg in args if os.path.isfile(arg)] The try...except block is redundant, because you are taking a slice, not an index, it cannot fail. If the bounds are outside of the actual list, the empty list is returned: py> [1, 2][100:1000] [] This I did not know. Good to know. By the way, is there significance to the name "compare.py"? Because it's not really doing any comparisons... That's the ultimate goal of the script but I've a ways to go before that is evident! if __name__ == "__main__": print(get_args()) How can one unittest get_args()? It seems to me that 'unittest'ing only works to test functions and methods, not programs. Well, technically "unit testing" refers to testing individual "units" (that is, classes, functions, modules etc.) of a program, not the entire program all at once. But it's also flexible enough to test the entire program. That's good to hear. To test get_args() alone, I would do something like this: import sys import unittest import compare class Test_Get_Args(unittest.TestCase): def setUp(self): # Create some known files. open('/tmp/aaa', 'w').close() open('/tmp/bbb', 'w').close() # Make sure another file doesn't exist. if os.path.exists('/tmp/ccc'): os.unlink('/tmp/ccc') def tearDown(self): # Clean up once we're done. for file in ('/tmp/aaa', '/tmp/bbb'): if os.path.exists(file): os.unlink(file) def test_existing_files(self): sys.argv = ['testing', '/tmp/aaa', '/tmp/bbb'] result = compare.get_args() self.assertEqual(result, ['/tmp/aaa', '/tmp/bbb']) def test_nonexisting_files(self): sys.argv = ['testing', '/tmp/ccc'] result = compare.get_args() self.assertEqual(result, []) def test_not_files(self): sys.argv = ['testing', '/tmp', '/'] result = compare.get_args() self.assertEqual(result, []) The paths I used are suitable for Unix, Linux or Mac. You will need to adapt them for Windows. M$ Windows is of little interest to me:-) To avoid having to write to sys.argv, give your get_args function an optional argument: def get_args(args=None): if args is None: args = sys.argv[1:] return [arg for arg in args if os.path.isfile(arg)] then in your tests, just pass the list directly to the function. Here's my attempt at a testing module: $ cat testing.py #!/usr/bin/env python3 import unittest import compare_sizes What's compare_sizes ? OOPS! In editing for presentation to the list I forgot to change this instance of compare_sizes to compare. The ultimate goal is to compare file sizes and so I am trying to do TDD of compare_sizes.py which I forgot to rename to 'compare' in the import statement. class CompareTesting(unittest.TestCase): def setUp(self): pass If you're not doing anything in setUp, just don't override the method. The default method does nothing, so you don't need this. I stuck it in as a place holder expecting to soon need it. Should have removed it for presentation. def test_nothing(self): self.assertEqual(not False, True) What is the purpose of this test? How is it testing *your* code? That would be necessary as a test of Python's built-ins. Since I'm learning I wanted to start with a test that I 'knew' shouldn't fail. I should have deleted it for presentation- sorry. def test_get_file_param(self): self.assertTrue(compare_sizes.get_args() == ['file1', 'file2']) You should use assertEqual(a, b) rather than assertTrue(a == b). Thanks for this tip. I remember reading about that. if __name__ == '__main__': unittest.main() Is there a way that I can provide the file name command line parameters to compare.py so that its get_args function can be tested? sys.argv is writeable, or better still, provide get_args() an optional argument to use instead of sys.argv.o I don't understand what you mean by "sys.argv is writeable". Thks again ak ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using unittest module for Test Driven Development
On Sun, Aug 24, 2014 at 05:23:35PM -0700, Alex Kleider wrote: > Given > $ cat compare.py > #!/usr/bin/env python3 > import os > import sys > > def get_args(): > try: > args = sys.argv[1:] > except IndexError: > return > return [arg for arg in args if os.path.isfile(arg)] The try...except block is redundant, because you are taking a slice, not an index, it cannot fail. If the bounds are outside of the actual list, the empty list is returned: py> [1, 2][100:1000] [] By the way, is there significance to the name "compare.py"? Because it's not really doing any comparisons... > if __name__ == "__main__": > print(get_args()) > > How can one unittest get_args()? > It seems to me that 'unittest'ing only works to test functions and > methods, not programs. Well, technically "unit testing" refers to testing individual "units" (that is, classes, functions, modules etc.) of a program, not the entire program all at once. But it's also flexible enough to test the entire program. To test get_args() alone, I would do something like this: import sys import unittest import compare class Test_Get_Args(unittest.TestCase): def setUp(self): # Create some known files. open('/tmp/aaa', 'w').close() open('/tmp/bbb', 'w').close() # Make sure another file doesn't exist. if os.path.exists('/tmp/ccc'): os.unlink('/tmp/ccc') def tearDown(self): # Clean up once we're done. for file in ('/tmp/aaa', '/tmp/bbb'): if os.path.exists(file): os.unlink(file) def test_existing_files(self): sys.argv = ['testing', '/tmp/aaa', '/tmp/bbb'] result = compare.get_args() self.assertEqual(result, ['/tmp/aaa', '/tmp/bbb']) def test_nonexisting_files(self): sys.argv = ['testing', '/tmp/ccc'] result = compare.get_args() self.assertEqual(result, []) def test_not_files(self): sys.argv = ['testing', '/tmp', '/'] result = compare.get_args() self.assertEqual(result, []) The paths I used are suitable for Unix, Linux or Mac. You will need to adapt them for Windows. To avoid having to write to sys.argv, give your get_args function an optional argument: def get_args(args=None): if args is None: args = sys.argv[1:] return [arg for arg in args if os.path.isfile(arg)] then in your tests, just pass the list directly to the function. > Here's my attempt at a testing module: > $ cat testing.py > #!/usr/bin/env python3 > import unittest > import compare_sizes What's compare_sizes ? > class CompareTesting(unittest.TestCase): > > def setUp(self): > pass If you're not doing anything in setUp, just don't override the method. The default method does nothing, so you don't need this. > def test_nothing(self): > self.assertEqual(not False, True) What is the purpose of this test? How is it testing *your* code? That would be necessary as a test of Python's built-ins. > def test_get_file_param(self): > self.assertTrue(compare_sizes.get_args() == ['file1', 'file2']) You should use assertEqual(a, b) rather than assertTrue(a == b). > if __name__ == '__main__': > unittest.main() > > Is there a way that I can provide the file name command line parameters > to compare.py so that its get_args function can be tested? sys.argv is writeable, or better still, provide get_args() an optional argument to use instead of sys.argv. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Using unittest module for Test Driven Development
Given $ cat compare.py #!/usr/bin/env python3 import os import sys def get_args(): try: args = sys.argv[1:] except IndexError: return return [arg for arg in args if os.path.isfile(arg)] if __name__ == "__main__": print(get_args()) How can one unittest get_args()? It seems to me that 'unittest'ing only works to test functions and methods, not programs. Here's my attempt at a testing module: $ cat testing.py #!/usr/bin/env python3 import unittest import compare_sizes class CompareTesting(unittest.TestCase): def setUp(self): pass def test_nothing(self): self.assertEqual(not False, True) def test_get_file_param(self): self.assertTrue(compare_sizes.get_args() == ['file1', 'file2']) if __name__ == '__main__': unittest.main() Is there a way that I can provide the file name command line parameters to compare.py so that its get_args function can be tested? Thanks in advance for any advice. AlexK ps I'm on Ubuntu14.4, using Python3.4.0 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor