Re: Newb testing question

2008-11-04 Thread Rick Kitts

On Nov 4, 2008, at 1:00 PM, Karen Tracey wrote:

> [...snip...]
> The order of things during validation is specified clearly in the  
> docs:
>
> http://docs.djangoproject.com/en/dev/ref/forms/validation/

This was useful, thanks.
>
>
> This page has a subsection on cleaning fields that depend on each  
> other, where it is recommended that such validation be done in the  
> form clean() method as opposed to an individual field's clean  
> method.  An individual field's clean method should really focus on  
> validating that field's data, not that field's data plus some other  
> field's data.  It isn't clear to me if you are unaware of the  
> existence of the form's overall clean() method or if you just don't  
> agree with the recommendation that that is where cross-field  
> validation should be performed.  (Also cross-field validation didn't  
> seem to be an issue in your first message so I don't know if we've  
> gotten off on a tangent or if that was really an issue in your first  
> example.)

I may have been aware of it. I think I've seen e.g. password2  
validation in a couple of places though and just assumed...

Well, sort of a tangent. What I was getting at is that the "raw" data  
of the form (i.e. the data from all field.clean() calls) should, in my  
mind, be set up before creator validation is called. That's probably a  
little specious in the face of form.clean() though.

>
>
>
> Second this tends to make righting unit tests rather more error  
> prone. Or at least the sort of tests I'm used to writing. I realize  
> there are various idiomatic ways of dealing with the problems I'm  
> having (spelunk the error list, etc) but certainly I can imagine  
> better ways. Keep in mind I'm not at all a python person (yet) so  
> this may in fact be entirely infeasible. But presumably one can do  
> something like declare clean_xxx as follows:
>
> def clean_something(self, password1, password2):
>   # Stuff
>
> Provided one can get to the names of the arguments it seems then  
> that it would be useful to do something in full_clean() like
>
> for each argument in the args list of each clean_xxx method:
>   name = arg name
>   if there_is_a_field_named(name):
>   set the value of that argument to field.clean()
>   else:
>   raise somethingorother
>
> I like this in several dimensions, much as I'd like faster-than- 
> light travel, which is to say it would be really cool but I don't  
> see how to get there from here.
>
> Regardless of whether this is implementable in Python I feel it  
> would be rather more complicated to explain and use than the current  
> approach.  clean for a field not only validates that the data is OK  
> but normalizes it to a consistent form -- if you start trying to do  
> cross-field validation before all of the individual data bits have  
> been normalized then your cross-field validation has to worry about  
> handling non-normalized data.  As it is if you put your cross-field  
> validation in the form's clean() method then it only has to deal  
> with validating normalized data.

This is a win, I agree.

>
>
>
> Anyway, I can see several ways around this and I'll pick one or the  
> other. OTOH, if testing at this level of granularity is inconsistent  
> with the python/djano world view, I would love to hear what's  
> better. Understanding code is easy(ish), philosophy is hard.
>
> Testing that an individual field's validation works as expected is  
> not inconsistent with Django or Python philosophy.  However testing  
> that by calling the field's clean method directly is not the right  
> approach -- this method is intended to be called by Django as part  
> of the overall form cleaning.  Therefore to ensure that the  
> environment/args/etc is set up for it as it will be when your code  
> actually runs in production, it is best to test it by calling the  
> form's is_valid() function, and examining the results in the effect  
> it has on the form.

That's what I got too as well.

Thanks for the time and patience,
---Rick

> >


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



Re: Newb testing question

2008-11-04 Thread Karen Tracey
On Tue, Nov 4, 2008 at 2:06 PM, Rick Kitts <[EMAIL PROTECTED]> wrote:

> Well, I think it's clear what I see. I sort of disagree about the impl,
> design, call it what you will.
>

It wasn't clear to me what you had seen nor what you wanted to argue about
though you have clarified that some in this post.


>
> Specifically, the current impl makes testing harder than it needs to be, or
> at least the testing that I'd like to do. That is, I have a field, that
> field has validation rules and I'd like to test that the work. Strictly a
> field has 2 sets of validation rules, those on the field itself (or is it
> more correct to say on the widget), and a (possibly empty) set of rules
> defined by the form creator (call them creator validations).
>
> So a couple of issues about this.
>
> First, the cleaned_data attribute (member?) is not guaranteed to be
> populated fully at the time any creator validation is called. That is, if I
> have 2 dependent fields, say password1, password2, I cannot get
> cleaned_data['password2'] inside of the creator validator clean_password1()
> unless/until the full_clean() impl get's to the field password2. Thus the
> ordering of fields and the impls of clean_xxx() are coupled in what I'd call
> a non-obvious fashion. This seems unnecessary but that's just me.
>

The order of things during validation is specified clearly in the docs:

http://docs.djangoproject.com/en/dev/ref/forms/validation/

This page has a subsection on cleaning fields that depend on each other,
where it is recommended that such validation be done in the form clean()
method as opposed to an individual field's clean method.  An individual
field's clean method should really focus on validating that field's data,
not that field's data plus some other field's data.  It isn't clear to me if
you are unaware of the existence of the form's overall clean() method or if
you just don't agree with the recommendation that that is where cross-field
validation should be performed.  (Also cross-field validation didn't seem to
be an issue in your first message so I don't know if we've gotten off on a
tangent or if that was really an issue in your first example.)


>
> Second this tends to make righting unit tests rather more error prone. Or
> at least the sort of tests I'm used to writing. I realize there are various
> idiomatic ways of dealing with the problems I'm having (spelunk the error
> list, etc) but certainly I can imagine better ways. Keep in mind I'm not at
> all a python person (yet) so this may in fact be entirely infeasible. But
> presumably one can do something like declare clean_xxx as follows:
>
> def clean_something(self, password1, password2):
> # Stuff
>
> Provided one can get to the names of the arguments it seems then that it
> would be useful to do something in full_clean() like
>
> for each argument in the args list of each clean_xxx method:
> name = arg name
> if there_is_a_field_named(name):
> set the value of that argument to field.clean()
> else:
> raise somethingorother
>
> I like this in several dimensions, much as I'd like faster-than-light
> travel, which is to say it would be really cool but I don't see how to get
> there from here.
>

Regardless of whether this is implementable in Python I feel it would be
rather more complicated to explain and use than the current approach.  clean
for a field not only validates that the data is OK but normalizes it to a
consistent form -- if you start trying to do cross-field validation before
all of the individual data bits have been normalized then your cross-field
validation has to worry about handling non-normalized data.  As it is if you
put your cross-field validation in the form's clean() method then it only
has to deal with validating normalized data.


> Anyway, I can see several ways around this and I'll pick one or the other.
> OTOH, if testing at this level of granularity is inconsistent with the
> python/djano world view, I would love to hear what's better. Understanding
> code is easy(ish), philosophy is hard.
>

Testing that an individual field's validation works as expected is not
inconsistent with Django or Python philosophy.  However testing that by
calling the field's clean method directly is not the right approach -- this
method is intended to be called by Django as part of the overall form
cleaning.  Therefore to ensure that the environment/args/etc is set up for
it as it will be when your code actually runs in production, it is best to
test it by calling the form's is_valid() function, and examining the results
in the effect it has on the form.

Karen

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

Re: Newb testing question

2008-11-04 Thread Rick Kitts
Well, I think it's clear what I see. I sort of disagree about the  
impl, design, call it what you will.

Specifically, the current impl makes testing harder than it needs to  
be, or at least the testing that I'd like to do. That is, I have a  
field, that field has validation rules and I'd like to test that the  
work. Strictly a field has 2 sets of validation rules, those on the  
field itself (or is it more correct to say on the widget), and a  
(possibly empty) set of rules defined by the form creator (call them  
creator validations).

So a couple of issues about this.

First, the cleaned_data attribute (member?) is not guaranteed to be  
populated fully at the time any creator validation is called. That is,  
if I have 2 dependent fields, say password1, password2, I cannot get  
cleaned_data['password2'] inside of the creator validator  
clean_password1() unless/until the full_clean() impl get's to the  
field password2. Thus the ordering of fields and the impls of  
clean_xxx() are coupled in what I'd call a non-obvious fashion. This  
seems unnecessary but that's just me.

Second this tends to make righting unit tests rather more error prone.  
Or at least the sort of tests I'm used to writing. I realize there are  
various idiomatic ways of dealing with the problems I'm having  
(spelunk the error list, etc) but certainly I can imagine better ways.  
Keep in mind I'm not at all a python person (yet) so this may in fact  
be entirely infeasible. But presumably one can do something like  
declare clean_xxx as follows:

def clean_something(self, password1, password2):
# Stuff

Provided one can get to the names of the arguments it seems then that  
it would be useful to do something in full_clean() like

for each argument in the args list of each clean_xxx method:
name = arg name
if there_is_a_field_named(name):
set the value of that argument to field.clean()
else:
raise somethingorother

I like this in several dimensions, much as I'd like faster-than-light  
travel, which is to say it would be really cool but I don't see how to  
get there from here.

Anyway, I can see several ways around this and I'll pick one or the  
other. OTOH, if testing at this level of granularity is inconsistent  
with the python/djano world view, I would love to hear what's better.  
Understanding code is easy(ish), philosophy is hard.

Thanks for the pointer to the errorlist.

Apologies if this makes no sense at all. I am not, again, a python/ 
django person.

---Rick

On Nov 4, 2008, at 10:32 AM, Karen Tracey wrote:

> On Tue, Nov 4, 2008 at 12:07 PM, Rick <[EMAIL PROTECTED]> wrote:
>
> Give a man a fish...
>
> Right, so I see now what's going on. Is this the right place to argue
> about how this works?
>
> It isn't clear what you see or what you want to argue about?
>
> cleaned_data is established when the form is validated and is  
> deleted if the entire form does not pass validation (though I think  
> there is a ticket open that asks for cleaned_data to stick around  
> with the valid values that did pass validation, so that might change).
>
> There is no way to validate part of a form -- it is all-or-nothing.   
> If you want to check for an error on a specific field, then check  
> for the existence of that field's name in the errors dictionary  
> after calling is_valid().  (You can also verify that you get the  
> exact error message you are looking for, if you like.)
>
> Karen
>
>
> ---Rick
>
>
> On Nov 4, 8:46 am, Rick Kitts <[EMAIL PROTECTED]> wrote:
> > Thanks, it does but this is a bad test methodology. is_valid()
> > verifies the entire form and there is no way of knowing in the  
> test if
> > the validation is failing because of other reasons or the specific  
> one
> > I (think) I'm testing.
> >
> > I guess the broader question then is when is cleaned_data  
> established?
> > It appears transient since if I call the clean_xxx() method after
> > calling is_valid() then I still get the attriberr.
> >
> > ---Rick
> >
> > On Nov 4, 2008, at 5:10 AM, Dan Fairs wrote:
> >
> >
> >
> > >> Running the test causes a splash of barf that says:
> >
> > >> AttributeError: 'TheFormClass' object has no attribute  
> 'cleaned_data'
> >
> > > Try calling form.is_valid() (which should in addition return  
> whether
> > > the validation framework as a whole thought the form was valid).  
> This
> > > should invoke your clean_ method.
> >
> > > Cheers,
> > > Dan
> >
> > > --
> > > Dan Fairs <[EMAIL PROTECTED]> |http://www.fezconsulting.com/
> >
> >
>
>
>
> >


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

Re: Newb testing question

2008-11-04 Thread Karen Tracey
On Tue, Nov 4, 2008 at 12:07 PM, Rick <[EMAIL PROTECTED]> wrote:

>
> Give a man a fish...
>
> Right, so I see now what's going on. Is this the right place to argue
> about how this works?
>

It isn't clear what you see or what you want to argue about?

cleaned_data is established when the form is validated and is deleted if the
entire form does not pass validation (though I think there is a ticket open
that asks for cleaned_data to stick around with the valid values that did
pass validation, so that might change).

There is no way to validate part of a form -- it is all-or-nothing.  If you
want to check for an error on a specific field, then check for the existence
of that field's name in the errors dictionary after calling is_valid().
(You can also verify that you get the exact error message you are looking
for, if you like.)

Karen


>
> ---Rick
>
>
> On Nov 4, 8:46 am, Rick Kitts <[EMAIL PROTECTED]> wrote:
> > Thanks, it does but this is a bad test methodology. is_valid()
> > verifies the entire form and there is no way of knowing in the test if
> > the validation is failing because of other reasons or the specific one
> > I (think) I'm testing.
> >
> > I guess the broader question then is when is cleaned_data established?
> > It appears transient since if I call the clean_xxx() method after
> > calling is_valid() then I still get the attriberr.
> >
> > ---Rick
> >
> > On Nov 4, 2008, at 5:10 AM, Dan Fairs wrote:
> >
> >
> >
> > >> Running the test causes a splash of barf that says:
> >
> > >> AttributeError: 'TheFormClass' object has no attribute 'cleaned_data'
> >
> > > Try calling form.is_valid() (which should in addition return whether
> > > the validation framework as a whole thought the form was valid). This
> > > should invoke your clean_ method.
> >
> > > Cheers,
> > > Dan
> >
> > > --
> > > Dan Fairs <[EMAIL PROTECTED]> |http://www.fezconsulting.com/
> >
> >
> >
>

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



Re: Newb testing question

2008-11-04 Thread Rick

Give a man a fish...

Right, so I see now what's going on. Is this the right place to argue
about how this works?

---Rick


On Nov 4, 8:46 am, Rick Kitts <[EMAIL PROTECTED]> wrote:
> Thanks, it does but this is a bad test methodology. is_valid()  
> verifies the entire form and there is no way of knowing in the test if  
> the validation is failing because of other reasons or the specific one  
> I (think) I'm testing.
>
> I guess the broader question then is when is cleaned_data established?  
> It appears transient since if I call the clean_xxx() method after  
> calling is_valid() then I still get the attriberr.
>
> ---Rick
>
> On Nov 4, 2008, at 5:10 AM, Dan Fairs wrote:
>
>
>
> >> Running the test causes a splash of barf that says:
>
> >> AttributeError: 'TheFormClass' object has no attribute 'cleaned_data'
>
> > Try calling form.is_valid() (which should in addition return whether
> > the validation framework as a whole thought the form was valid). This
> > should invoke your clean_ method.
>
> > Cheers,
> > Dan
>
> > --
> > Dan Fairs <[EMAIL PROTECTED]> |http://www.fezconsulting.com/
>
>
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Newb testing question

2008-11-04 Thread Rick Kitts

Thanks, it does but this is a bad test methodology. is_valid()  
verifies the entire form and there is no way of knowing in the test if  
the validation is failing because of other reasons or the specific one  
I (think) I'm testing.

I guess the broader question then is when is cleaned_data established?  
It appears transient since if I call the clean_xxx() method after  
calling is_valid() then I still get the attriberr.

---Rick

On Nov 4, 2008, at 5:10 AM, Dan Fairs wrote:

>
>> Running the test causes a splash of barf that says:
>>
>> AttributeError: 'TheFormClass' object has no attribute 'cleaned_data'
>>
>
> Try calling form.is_valid() (which should in addition return whether
> the validation framework as a whole thought the form was valid). This
> should invoke your clean_ method.
>
> Cheers,
> Dan
>
> --
> Dan Fairs <[EMAIL PROTECTED]> | http://www.fezconsulting.com/
>
>
> >


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



Re: Newb testing question

2008-11-04 Thread Dan Fairs

> Running the test causes a splash of barf that says:
>
> AttributeError: 'TheFormClass' object has no attribute 'cleaned_data'
>

Try calling form.is_valid() (which should in addition return whether  
the validation framework as a whole thought the form was valid). This  
should invoke your clean_ method.

Cheers,
Dan

--
Dan Fairs <[EMAIL PROTECTED]> | http://www.fezconsulting.com/


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



Newb testing question

2008-11-03 Thread Rick Kitts

Greetings. I'm digging django pretty good. Many thanks.

I've run into a problem that I'm sure is my fault but I don't know why  
yet. I've got a ModelForm and I'm trying to write unit tests for the  
validation bits. My strategy here was to construct an instance of the  
form and populate it with data and then call the appropriate  
clean_() method and make sure it does the right thing. Roughly  
it looks like this:

TheFormClass

def clean_field(self):
field_val = self.cleaned_data['field']
# do sexy django validation tricks

and the test method looks like this:

def test_sexy_validation_is_dead_sexy(self):
model_object = ModelObject()
# Set some values on model_object
form = TheFormClass(instance=model_object)
form.clean_field()

Running the test causes a splash of barf that says:

AttributeError: 'TheFormClass' object has no attribute 'cleaned_data'

I've tried calling form.full_clean() with no better luck and  
form.clean() which gives the same AttributeError. So to the question.

What am I doing wrong here? I've been living in Java land for a long  
time so I'm suspecting I might be philosophically wrong about how to  
test this stuff, especially since I can't (easily) find any mention of  
this sort of thing on the web.

Any help much appreciated.

TIA,
---Rick 

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