Re: [Tutor] Using unittest module for Test Driven Development

2014-08-25 Thread Alex Kleider

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

2014-08-25 Thread Marc Tompkins
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

2014-08-25 Thread Alex Kleider

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

2014-08-24 Thread Danny Yoo
>>> 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

2014-08-24 Thread Alex Kleider


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

2014-08-24 Thread Steven D'Aprano
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

2014-08-24 Thread Alex Kleider

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