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

Alan Gauld alan.gauld at yahoo.co.uk
Sun Apr 16 13:06:41 EDT 2017


On 16/04/17 16:21, boB Stepp wrote:

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

I'm not familiar with the mixin approach so don;t know what
they intend but...

> --------------------------------------------------------------------------------------
> class SuperWhammy:
>     def mySuperWhammyFunction(self, any_input):
>         return any_input
> 
> import unittest
> 
> class TestFuncAcceptsSequencesMixin:
> 
>     obj = SuperWhammy
>     func = obj.mySuperWhammyFunction

Note this is a class attribute not an instance one
so you could attach a "normal" function and call it
via the class.

>     def test_func(self):
>         f = self.func(self.arg)

    f = TestFuncAcceptsSequencesMixin.func(self.args)

>         self.assertEqual(f, self.arg)
>         print(f)

But I've no idea if that's what the author intended...

I tried it on your original code and it seemed to work OK.

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

No, you are not creating an instance but a reference to the class.
So when you assigned the function you were in effect doing

func = SuperWhammy.mySuperWhammyFunction

Which of course works fine.

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

I'll let a unittest expert comment on that fully.

So far as I understand it, the unittest framework
just calls all the test_xxx methods of all classes
that inherit from TestCase. And because all three
test classes inherit the mixin and its test_func()
method they all execute that method but each providing
their own version of args.

Exactly how that magic is accomplished I leave to
the framework authors! ;-)


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

They inherit the test_fujnc() method from the mixin.
And the TestCase looks for  methods called test_xxx
and runs them. (It could be as simple as doing a dir(self),
I really don't know.)

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

Mixins are conceptually very simple, just small classes
expressing a capability that you inherit along with your
other super classes. There is nothing intrinsically special
about them, its more about the concept than the implementation.
(Some languages use mixins a lot and have dedicated support
for them such as not having them inherit from object to avoid
the dreaded MI diamond patterns or other similar tricks.) The
introduction of interfaces into languages like Java and C#
have made mixins less common.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list