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

Reply via email to