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

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu May 15 22:19:08 EDT 2008


En Thu, 15 May 2008 22:44:17 -0300, Marcelo de Moraes Serpa  
<celoserpa at gmail.com> escribió:

> @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".

That depends on what you consider "valid". Just duplicating the function  
code in the test is absurd and pointless. Of course it will pass now -  
you're executing the same code! On the other hand, what if you later want  
to replace the algorithm and use SHA1 instead of md5? The test will fail  
then - but do you *actually* care whether it actually returns the md5  
digest or something else?
If you *do* care, then you should compute the output by hand (or assume it  
is correct *now*) and hard code THAT string in the test, not recompute it  
again.
If you *don't* care, then follow the steps I outlined in the previous  
message: just ensure that different inputs give different outputs.

> 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)

Mmm, no, your posted example was more like this:

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

You *computed* the expected result using (presumably) the same code as the  
tested function.

> 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?

I'd say they are still unit tests. I'm testing a single function,  
comparing the expected output with the actual output. But I only check the  
*public* interfase of the function, what their users expect from it (its  
contract, if you want); I don't check the internal implementation.
The real value of unit tests comes when you want to modify something, or  
reimplement it. You must ensure that you don't break other things. With a  
too strict test very tied to the current implementation, you can't change  
anything.

-- 
Gabriel Genellina




More information about the Python-list mailing list