[Tutor] Do not understand code snippet from "26.8. test — Regression tests package for Python"

boB Stepp robertvstepp at gmail.com
Sun Apr 16 11:21:46 EDT 2017


On Sat, Apr 15, 2017 at 6:31 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 16/04/17 00:17, boB Stepp wrote:
>
>> --------------------------------------------------------------------------------------
>> #!/usr/bin/env python3
>>
>> def mySuperWhammyFunction(any_input):
>>     return any_input
>
> This is a simple function, its not bound to an object

I did not name this function.  I think that if the docs' example meant
it to be a method, they would have named it, "mySuperWhammyMethod".

>>
>> import unittest
>>
>> class TestFuncAcceptsSequencesMixin:
>>
>>     func = mySuperWhammyFunction
>>
>>     def test_func(self):
>>         self.func(self.arg)
>
> This is calling self.function which implies a method.
>
> Convert your function to a method and it should work.

I did this and it indeed works.  But how do I use this technique to
unittest the given function?  I am just not seeing how to do it with
this with this mixin approach, and I have yet to study mixins, though
apparently I have just now started!

In the modified program (per your suggestion) to test a method (I
still need to know how to make this test the original *function*!), I
now have:

--------------------------------------------------------------------------------------
class SuperWhammy:
    def mySuperWhammyFunction(self, any_input):
        return any_input

import unittest

class TestFuncAcceptsSequencesMixin:

    obj = SuperWhammy
    func = obj.mySuperWhammyFunction

    def test_func(self):
        f = self.func(self.arg)
        self.assertEqual(f, self.arg)
        print(f)

class AcceptLists(TestFuncAcceptsSequencesMixin, unittest.TestCase):
    arg = [1, 2, 3]

class AcceptStrings(TestFuncAcceptsSequencesMixin, unittest.TestCase):
    arg = 'abc'

class AcceptTuples(TestFuncAcceptsSequencesMixin, unittest.TestCase):
    arg = (1, 2, 3)

if __name__ == '__main__':
    unittest.main()
--------------------------------------------------------------------------------------

This gives me the results:

> python -m unittest -v test_super.py
test_func (test_super.AcceptLists) ... [1, 2, 3]
ok
test_func (test_super.AcceptStrings) ... abc
ok
test_func (test_super.AcceptTuples) ... (1, 2, 3)
ok

----------------------------------------------------------------------
Ran 3 tests in 0.000s

Questions:

1)  I did not notice it until this AM, but I used (as above) "obj =
SuperWhammy".  Normally I would write this as "obj = SuperWhammy()"
with parentheses.  But I see that both work.  Are the parentheses
unneeded when creating an object instance if there are no
initialization arguments needed?

2)  The big question:  What is the program flow for this program?  I
am not seeing the order of execution here.  How is the unittest module
handling the execution of this?  The ending comment in the docs'
example cited reads:

"When using this pattern, remember that all classes that inherit from
unittest.TestCase are run as tests. The Mixin class in the example
above does not have any data and so can’t be run by itself, thus it
does not inherit from unittest.TestCase."

This suggests to me that unittest "uses" the bottom three classes, but
even though each of the three inherits from the class
TestFuncAcceptsSequenceMixin, those classes don't have any methods
that they call on that class, so how does its code get run?  I suspect
that the mixin's concepts is where I am stumbling.  I have yet to find
a reference that is making things clear to me, though I will continue
searching and reading.

-- 
boB


More information about the Tutor mailing list