Re: Testing framework inflexibilities

2009-02-09 Thread Russell Keith-Magee

On Tue, Feb 10, 2009 at 10:34 AM, Ludvig Ericson
 wrote:
>
> Feb 8, Russell Keith-Magee:
>> First off - it isn't impossible to do what you are describing with the
>> existing setup. There is no reason you couldn't override _pre_setup()
>> in your subclass and either re-instantiate self.client, or modify the
>> self.client instance that has already been created. This isn't
>> necessarily clean, but it would work.
>
> Though I solved my own problem through some means, no - your
> suggestion would not work. The reason is that the TestCase.__call__
> code does: _pre_setup, set client, super...(), _post_setup.

Erm... no it doesn't. Lines 236-245 of testcases.py:

self.client = Client()
try:
self._pre_setup()
except (KeyboardInterrupt, SystemExit):
raise
except Exception:
import sys
result.addError(self, sys.exc_info())
return
super(TransactionTestCase, self).__call__(result)

That's set client, _pre_setup, super(), not _pre_setup, set client, super().

>> This area could certainly be cleaned up, though. Moving the
>> instantiation of Client into _pre_setup() would be one approach.
>> Another would be to parameterize the class that is instantiated when
>> the client is created - i.e., rather than always instantiating
>> django.test.client.Client, we provide a customization hook that lets
>> subclasses provide their own Client class.
>
> A rather common idiom I've seen is:
>
> class TestCase(...):
> client_class = DjangoTestClientThing
>
> def __call__(self, ...):
> # ...
> if self.client_class:
> self.client = self.client_class(...)
> # ...
>
> Essentially achieving the same as you, only because of Python's name
> resolution machinery, you could also do `my_inst.client_class = Blah`
> to specialize per instance.

That's the technique I was referring to. It can be implemented in at
least three ways -
 1) Providing a class level variable that defines the Client class to
be instantiated,
 2) Providing a method that returns the Client class to be instantiated, or
 3) Providing a method that instantiates the client class.

Option (3) is essentially a replacement for setup(), so it's probably
overkill. Personally, I'd be leaning towards (1) - it's easy to
describe, almost impossible to get wrong, and matches the other
configuration options for the TestCase class.

Yours,
Russ Magee %-)

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Testing framework inflexibilities

2009-02-09 Thread Ludvig Ericson

Feb 8, Russell Keith-Magee:
> First off - it isn't impossible to do what you are describing with the
> existing setup. There is no reason you couldn't override _pre_setup()
> in your subclass and either re-instantiate self.client, or modify the
> self.client instance that has already been created. This isn't
> necessarily clean, but it would work.

Though I solved my own problem through some means, no - your  
suggestion would not work. The reason is that the TestCase.__call__  
code does: _pre_setup, set client, super...(), _post_setup.

The only way to hook into that code would be to mash up the MRO for  
TestCase and inject oneself into the super call. And then re-instatiate.

> This area could certainly be cleaned up, though. Moving the
> instantiation of Client into _pre_setup() would be one approach.
> Another would be to parameterize the class that is instantiated when
> the client is created - i.e., rather than always instantiating
> django.test.client.Client, we provide a customization hook that lets
> subclasses provide their own Client class.

A rather common idiom I've seen is:

 class TestCase(...):
 client_class = DjangoTestClientThing

 def __call__(self, ...):
 # ...
 if self.client_class:
 self.client = self.client_class(...)
 # ...

Essentially achieving the same as you, only because of Python's name  
resolution machinery, you could also do `my_inst.client_class = Blah`  
to specialize per instance.

> Patches welcome. :-)


Once I know what to write!

- Ludvig

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Testing framework inflexibilities

2009-02-07 Thread Russell Keith-Magee

On Sat, Feb 7, 2009 at 8:17 PM, Ludvig Ericson  wrote:
>
> Hi,
> I realize this topic is in a gray zone between django-users and
> django-developers, but I thought it'd be more fitting to post it here.
>
> I needed to inject things into the session, and I'm not using regular
> sessions.
> I have my own session framework*, but the testing framework is rather
> tightly
> coupled with the built-in Django sessions.
>
> All I want to do with it - for now - is to have a simple dict as the
> session of
> the testing client.
>
> Normally, I'd just subclass django.test.TestCase, and change the part
> I need to
> change - simple programming! But this is more or less impossible with
> TestCase,
> because the part that sets up the client object is TestCase.__call__,
> which also
> contains other logics.
>
> So for me to be able to override the class used for the client object,
> I would
> have to *copy* the __call__ method from the actual .py file, paste and
> rewrite.
> IMHO that's a pretty strong indication that modularization isn't at
> its best.
> :-)
>
> I'm not sure how to modularize this either. A first step would be
> moving the
> line `self.client = Client()` from __call__ to _pre_setup. That way,
> one could
> subclass and upcall, then replace. That's virtually impossible
> currently.

First off - it isn't impossible to do what you are describing with the
existing setup. There is no reason you couldn't override _pre_setup()
in your subclass and either re-instantiate self.client, or modify the
self.client instance that has already been created. This isn't
necessarily clean, but it would work.

This area could certainly be cleaned up, though. Moving the
instantiation of Client into _pre_setup() would be one approach.
Another would be to parameterize the class that is instantiated when
the client is created - i.e., rather than always instantiating
django.test.client.Client, we provide a customization hook that lets
subclasses provide their own Client class.

Patches welcome. :-)

Yours,
Russ Magee %-)

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---