Handling test data that depends on temporal data (that might change while the test runs)

Marcelo de Moraes Serpa celoserpa at gmail.com
Thu May 15 21:44:17 EDT 2008


Thank you for the replies.

@Gabriel: I understand what you are saying. It all depends on what you want
to test. In this case, I wanted to test the algorithm of the method.  The
test_generate_chat_dir_string is meant to do just that: Check if the
generate_chat_dir_string generated a "valid" (according to the specs) string
for a "chat dir name".

It is not a integration nor a functional "unit" test, but it is a "real"
unit test in the sense that I created a test for each method and I exercised
the methods the following way:

 1) Got some data to test and...
 2) ... Generated an output "manually" in the test method that I knew were
the expected return of the tested method;
 3) Fed this data to the tested method and compared the manually generated
result with the return value of the method.

It is like testing a method that does a simple division:

def test_divide
  divdend = 10
  divisor = 2
  expected_result = 5
  self.assertEquals(mathprogram.divide(dividend,divisor),5)

The techniques you explained in your message sound more like functional
testing or integration + functional testing where multiple aspects of a
single functional unit are being exercised. Or am I wrong?

@Erik:

I solved the problem by replacing the datetime.datetime with a custom
instance in the test method body:

def my_test_method
   now = datetime.datetime.now()
   class my_custom_datetime(object):
        def now(self): return now
   datetime.datetime = my_custom_datetime()

works great. Thanks to Zalamander @ #python on EFNET ;)



On Thu, May 15, 2008 at 10:12 PM, Erik Jones <mage2k at gmail.com> wrote:

>
>
> On Thu, May 15, 2008 at 12:21 PM, Marcelo de Moraes Serpa <
> celoserpa at gmail.com> wrote:
>
>> Hello,
>>
>> So, I have this particular method, generate_chat_dir_string, which should
>> generate a string in the following format:
>>  "md5hexstring-day-month-year-hour-minute"
>>
>> This string will be used to create a directory in the filesystem.
>>
>> I'm trying to adopt the TDD approach, so, I'm starting by testing all the
>> methods of the Chat class, including this one. However, an issue just popped
>> up, this is the test code:
>>
>>
>>    1.   def test_generate_chat_dir_string(self):
>>    2.         import md5
>>    3.         import random
>>    4.         import datetime
>>    5.         md5_handler = md5.new()
>>    6.         users = [{"user":"pedro","atendente":False},{
>>    "user":"joão","atendente":True}]
>>    7.         #salt = random.random().to_s()
>>    8.         #md5_handler.update(salt)
>>    9.         now = datetime.datetime.now()
>>    10.         ts = now.strftime("%d-%m-%Y-%H-%M")
>>    11.         for user in users:
>>    12.             md5_handler.update(user["user"])
>>    13.
>>    14.
>>    15.         seed = md5_handler.hexdigest()
>>    16.
>>    17.         final_string = seed + "-" + ts
>>    18.
>>    19.         method_generated_string =
>>    self.chat.generated_chat_dir_string(users,seed)
>>    20.
>>    21.         self.assertEquals(final_string,method_generated_string)
>>
>> As you can see, it generates a specific set of data and assembles a
>> final_string. It then feeds the same data to generate_chat_dir_string and
>> compare to see if the final_string is equal to the string generated by the
>> tested method.
>>
>> However, they might not be equal becouse of the temporal data. In this
>> case I'm not using seconds, but in a bizarre situation a minute could have
>> passed and the test would faile becouse the two strings would have a
>> different minute portion. Something like this:
>>
>> "b2ef9c7b10eb0985365f913420ccb84a-30-10-2008-10-31"
>> "b2ef9c7b10eb0985365f913420ccb84a-30-10-2008-10-32"
>>
>> How could I handle this issue?
>>
>> Thanks in advance,
>
>
> Add another parameter, with a default, to the method's interface:
>
> def test_generate_chat_dir_string(self, now=None):
>     if not now:
>         import datetime
>         now = datetime.datetime.now()
>     .....
>
>
> That way you can feed it values when testing to validate the calculations
> but leave it up to the datetime module to fill in the used value in
> production.
>
>
>
> --
> Erik Jones
> mage2k at gmail.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20080515/9a3d8f45/attachment.html>


More information about the Python-list mailing list