﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
33348	Change API of assertFormError to take an actual form object	Baptiste Mispelon	Baptiste Mispelon	"The current signature of `assertFormError` is `(response, form, field, errors, msg_prefix='')` where:

- `response` is a response object (specifically one generated by the test client because it needs `response.context`)
- `form` is the name of a form (string) to be found in the response's context
- `field` is a name of a field in the form (string)
- `errors` is either a list of error strings, a single error string (equivalent to `[error]`) or `None` (equivalent to `[]`) 
- `msg_prefix` is a string added to the test failure message


Personally I've always found this `response`/`form` API to be clunky since I often want to test a form directly without having to go through the test client.
It would be a lot easier to use if we could pass a form object directly. I don't really understand why the API was implemented like this to begin with.

On top of that, now that Django uses template-based rendering for forms, formsets and widgets there are a lot of contexts to search in `response.context` and a lot of possibilities for clashing names (see #33346).

I would therefore propose the following new signature: `assertFormError(form, field, errors, msg_prefix='')` with `form` being an actual `Form` object and all other parameters staying the same.
The deprecation should be straightforward to implement by checking if `form` is a response object (`isinstance` check) or if `response` kwarg has been passed.


With that change `assertFormsetError` becomes mostly useless since one can simply do `assertFormError(formset.forms[i], field_name, errors)`. The one usecase that wouldn't be covered is `i = None + field_name=None` which checks the `errors` list against the formset's `non_form_errors()`.
We could either leave `assertFormsetError` in place as a convenience method (with a similar change to its API to accept a formset object directly) or deprecate more agressively by suggesting the user tests the output of `formset.non_field_errors()` directly."	Cleanup/optimization	closed	Testing framework	dev	Normal	fixed		Baptiste Mispelon	Ready for checkin	1	0	0	0	0	0
