Re: How best to test functions which use date.today

2009-03-03 Thread Ed Singleton
On Feb 28, 5:54 pm, Lie Ryan  wrote:
> Yuan HOng wrote:
> > HI,
>
> > In my project I have several date related methods which I want tested for
> > correctness. The functions use date.today() in several places. Since this
> > could change every time I run the test, I hope to find someway to fake a
> > date.today.
>
> > For illustration lets say I have a function:
>
> > from datetime import date
> > def today_is_2009():
> >     return date.today().year == 2009
>
> > To test this I would like to write test function like:
>
> > def test_today_is_2009():
> >     set_today(date(2008, 12, 31))
> >     assert today_is_2009() == False
> >     set_today(date(2009,1,1))
> >     assert today_is_2009() == True

Although you can't override today, you should be able to do something
along the lines of:

class MyDate(object):
def __init__(self, today):
self.today = today

my_date = MyDate(date(2009, 11, 12))

date = my_date

This assumes you aren't using anything else from date.  If you are
you'll either have to add that to MyDate or use a proper Mock Object.

Ed

--
http://mail.python.org/mailman/listinfo/python-list


Re: How best to test functions which use date.today

2009-03-02 Thread Yuan HOng
Hello,

Thanks for all the great ideas. Based on your input, I was able to solve my
problem by way of a FakeDate in a fakedate module.

In the testing module, before importing the tested module, I would load my
fakedate module into sys.modules under the key 'datetime'. So when the
tested module is imported, it will get my fakedate module in stead of the
original C-extension datetime module.

That way, the tested module needs no modification.

-- 
Hong Yuan

大管家网上建材超市
装修装潢建材一站式购物
http://www.homemaster.cn
--
http://mail.python.org/mailman/listinfo/python-list


Re: How best to test functions which use date.today

2009-02-28 Thread Scott David Daniels

Lie Ryan wrote:

Yuan HOng wrote:

In my project I have several date related methods which I want tested for
correctness. The functions use date.today() in several places. Since this
could change every time I run the test, I hope to find someway to fake a
date.today.
For illustration lets say I have a function:

from datetime import date
def today_is_2009():
return date.today().year == 2009

To test this I would like to write test function like:

def test_today_is_2009():
set_today(date(2008, 12, 31))
assert today_is_2009() == False
set_today(date(2009,1,1))
assert today_is_2009() == True

Try something like this:
import module_to_test as sut # "sut" -> system under test
from datetime import date

class FakeDate(object):
def __init__(self, value):
self._result = value
def today(self):
return self._result

def test_today_is_2009_too_old():
temp, sut.date = sut.date, FakeDate(date(2008, 12, 31))
try:
assert not sut.today_is_2009()
finally:
sut.date = temp

def test_today_is_2009_too_young():
temp, sut.date = sut.date, FakeDate(date(2010, 1, 1))
try:
assert not sut.today_is_2009()
finally:
sut.date = temp

def test_today_is_2009_just_right():
temp, sut.date = sut.date, FakeDate(date(2009, 1, 1))
try:
assert not sut.today_is_2009()
finally:
sut.date = temp


Note: each test should test 1 thing.

--Scott David Daniels
scott.dani...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list


Re: How best to test functions which use date.today

2009-02-28 Thread Gabriel Genellina
En Sat, 28 Feb 2009 15:35:47 -0200, Yuan HOng   
escribió:



In my project I have several date related methods which I want tested for
correctness. The functions use date.today() in several places. Since this
could change every time I run the test, I hope to find someway to fake a
date.today.

For illustration lets say I have a function:


from datetime import date
def today_is_2009():
return date.today().year == 2009

To test this I would like to write test function like:

def test_today_is_2009():
set_today(date(2008, 12, 31))
assert today_is_2009() == False
set_today(date(2009,1,1))
assert today_is_2009() == True



Instead of trying to inject a fake date, you could rewrite the function to
take a date argument:

def today_is_2009(today=None):
   if today is None:
 today = date.today()
   return today.year == 2009

Then, tests should pass a known date. This approach has a drawback -- you
don't test the case when no argument is given.

Another way is to use a fake date class, or a fake datetime module. Google  
"python mock object"


--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list


Re: How best to test functions which use date.today

2009-02-28 Thread rdmurray
Christian Heimes  wrote:
> Lie Ryan wrote:
> >> But this fails with:
> >>
> >> TypeError: can't set attributes of built-in/extension type
> >> 'datetime.date'
> > 
> > This is because today is an attribute. In python, we can override
> > attribute access to become a function call. I don't have python right
> > now, but try this:
> > 
> > del date.today
> > date.today = mytoday
> 
> It won't work. The datetime module is written in C. You can't modify a C
>  extension.

Hmm.  Given that, Lie, maybe what you need to do is modify your code
so that you call your own special purpose function to get 'today',
and replace _that_ for testing, using datetime's today for production.

--RDM

--
http://mail.python.org/mailman/listinfo/python-list


Re: How best to test functions which use date.today

2009-02-28 Thread Christian Heimes
Lie Ryan wrote:
>> But this fails with:
>>
>> TypeError: can't set attributes of built-in/extension type
>> 'datetime.date'
> 
> This is because today is an attribute. In python, we can override
> attribute access to become a function call. I don't have python right
> now, but try this:
> 
> del date.today
> date.today = mytoday

It won't work. The datetime module is written in C. You can't modify a C
 extension.

Christian

--
http://mail.python.org/mailman/listinfo/python-list


Re: How best to test functions which use date.today

2009-02-28 Thread Lie Ryan

Yuan HOng wrote:

HI,

In my project I have several date related methods which I want tested for
correctness. The functions use date.today() in several places. Since this
could change every time I run the test, I hope to find someway to fake a
date.today.

For illustration lets say I have a function:


from datetime import date
def today_is_2009():
return date.today().year == 2009

To test this I would like to write test function like:

def test_today_is_2009():
set_today(date(2008, 12, 31))
assert today_is_2009() == False
set_today(date(2009,1,1))
assert today_is_2009() == True

The first approach of achieving this purpose is to monkey patch the
date.today like:

date.today = mytoday

But this fails with:

TypeError: can't set attributes of built-in/extension type 'datetime.date'


This is because today is an attribute. In python, we can override 
attribute access to become a function call. I don't have python right 
now, but try this:


del date.today
date.today = mytoday


A second possibility would be to change the system date (I am running
Linux). However the standard Python module doesn't provide a method for this
purpose. I could use os.system to issue a date command. But I am not very
comfortable with this since changing the system time could break something
undesirably. Also I will then have to have root privilege to run my test.
Besides, I will have to stop the ntp daemon so it will not inadvertently
correct the system clock during the test period.

Is there any suggestion from the community on how best to test such
functions?


It is a very bad idea to change the system date.

--
http://mail.python.org/mailman/listinfo/python-list


How best to test functions which use date.today

2009-02-28 Thread Yuan HOng
HI,

In my project I have several date related methods which I want tested for
correctness. The functions use date.today() in several places. Since this
could change every time I run the test, I hope to find someway to fake a
date.today.

For illustration lets say I have a function:


from datetime import date
def today_is_2009():
return date.today().year == 2009

To test this I would like to write test function like:

def test_today_is_2009():
set_today(date(2008, 12, 31))
assert today_is_2009() == False
set_today(date(2009,1,1))
assert today_is_2009() == True

The first approach of achieving this purpose is to monkey patch the
date.today like:

date.today = mytoday

But this fails with:

TypeError: can't set attributes of built-in/extension type 'datetime.date'

A second possibility would be to change the system date (I am running
Linux). However the standard Python module doesn't provide a method for this
purpose. I could use os.system to issue a date command. But I am not very
comfortable with this since changing the system time could break something
undesirably. Also I will then have to have root privilege to run my test.
Besides, I will have to stop the ntp daemon so it will not inadvertently
correct the system clock during the test period.

Is there any suggestion from the community on how best to test such
functions?

-- 
Hong Yuan

大管家网上建材超市
装修装潢建材一站式购物
http://www.homemaster.cn
--
http://mail.python.org/mailman/listinfo/python-list