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

Reply via email to