Re: How best to test functions which use date.today
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
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
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
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
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
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
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
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