Question

I haven't used Django's and Python's built in testing capabilities yet, but I want to finally start... And one of the most obvious things that I'd like to keep in check during the entire development process is that all my pages validate in all possible scenarios.

What's the best way to do this?

Was it helpful?

Solution

Good question. I haven’t done this myself, so hopefully there will be some better answers, but you might want to look into HTML validation middleware:

“in all possible scenarios” might be too much to ask for, depending on your app. For example if you make the next Facebook, and are thus accepting huge amounts of user data every day, something will come in at some point that breaks the validity of a page on your site.

As validation errors don’t tend to destroy functionality, it might be an acceptable approach to check with some limited test data, then react to errors as they come up. I believe this is known as stupidity-driven testing.

OTHER TIPS

Alternatively, a roll-your-own approach to validating pages on your site during your usual unit testing process would look something like this:

  1. Go through your urls.py and generate as many possible URLs for the site as you can
  2. Use the built-in Django test client to fetch each of those urls
  3. Validate them somehow (See perhaps Validate (X)HTML in Python)

Not sure if anyone’s done any of the work on this is a reusable way.

One solution is to make a script that renders all the templates based on an input dictionary of variables test values.

The main logic to retrieve the list of variables defined in the templates is the following:

from django.template.loader import get_template

def extract_required_vars(node):
    if not hasattr(node, 'nodelist'):
        return []
    var_names = []
    for child_node in node.nodelist:
        if isinstance(child_node, VariableNode):
            var_names.append(child_node.filter_expression.token)
        elif isinstance(child_node, ForNode):
            var_names.append(child_node.sequence.var.var)
        elif isinstance(child_node, ExtendsNode):
            template = get_template(child_node.parent_name.var)
            var_names.extend(extract_required_vars(template))
        elif isinstance(child_node, IncludeNode):
            template = get_template(child_node.template.var)
            var_names.extend(extract_required_vars(template))
        var_names.extend(extract_required_vars(child_node))
    return var_names

required_vars = extract_required_vars(get_template('index.html'))

The script then checks that the variables defined in the templates are either in the project settings or in the dict provided by user as test input.

/path/to/project/templates/templates/allusers.html
  -> ok: users, STATIC_URL
/path/to/project/templates/entrer-en-contact.html
  -> ok: contactform, STATIC_URL
/path/to/project/templates/dest-summary.html
  -> ok: STATIC_URL
  -> missing: dest_username

More details in this blog post.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top