Django 3T
Django 3T is a Django Template Testing Tool which aims to help developers to write better tests where the Django template engine is involved.
Some of the things you can do with Django 3T include:
- Ensure a specific
template
,node
orblock
is rendered - Ensure a specific
template
,node
orblock
is rendered a specific amount of times - Ensure a specific
template
is rendered with a specific context subset - Ensure a specific
node
is rendered with specific arguments - Ensure a specific
template
,node
orblock
results in a specific content or includes it
Installation
pip install django-3t
Usage
Django 3T uses the watch_templates
context manager to intercept template and node renderings.
Suppose your project implements the following template called homepage.html
:
{% load say_hello from project_tags %}
<h1>The most useful website ever</h1>
{% say_hello request.user %}
A test that makes sure your template and template tag are rendered correctly would roughly look like this:
from django.contrib.auth import get_user_model
from django.test import Client
# 1. Import the context manager
from d3t.watcher import watch_templates
User = get_user_model()
def test_homepage():
user = User.objects.get(username='Billy')
client = Client()
client.force_login(user)
# 2. Wrap the code where the rendering happens
with watch_templates as rendered:
client.get('/')
# 3. Assert!
assert rendered.template('homepage.html')
assert rendered.node('say_hello').with_arguments(user)
The first assertion makes sure the template homepage.html
was rendered, the second assertion makes sure the template tag say_hello
was rendered and it was done using user
as argument.
For a comprehensive list of available methods, check the API section.
API
You can check that a template, node or block has been rendered and that it did under specific conditions
Template API
Check that it has been rendered
rendered.template('template-name.html')
Check that it has been rendered with a specific context subset
rendered.template('template-name.html').with_context({'answer': 42})
Check that it has been rendered and the output contains a specific string
rendered.template('template-name.html').contains('content')
Check that it has been rendered and the output equals a specific string
rendered.template('template-name.html').equals('full content')
Node API
Check that it has been rendered
rendered.node('node_name')
Check that it has been rendered with specific arguments
rendered.node('node_name').with_arguments(42, type='answer')
Check that it has been rendered and the output contains a specific string
rendered.node('node_name').contains('content')
Check that it has been rendered and the output equals a specific string
rendered.node('node_name').equals('full content')
Block API
Check that it has been rendered
rendered.block('block-name')
Check that it has been rendered and the output contains a specific string
rendered.block('block-name').contains('content')
Check that it has been rendered and the output equals a specific string
rendered.block('block-name').equals('full content')
Handling multilpe renderings
A template, node or block could be rendered any number of times, Django 3T allows you to take control of this giving support for the not
operator and for the len
, all
and any
built-in functions:
Check that a template/node/block has not been rendered
not rendered.template('template-name.html')
Check that a template/node/block has been rendered a specific amount of times
len(rendered.node('node_name')) == 3
Check that all the template/node/block renderings happened under a specific condition
all(rendered.block('block-name').contains('content'))
Check that any of the template/node/block renderings happened under a specific condition
any(rendered.template('template-name.html').equals('specific content'))
Signals
template_rendered
d3t.signals.template_rendered
This is sent immediately after a template is rendered.
Arguments sent with this signal:
-
senderThe
Template
class. -
instanceThe actual template instance being rendered.
-
contextThe context used to render the template.
-
resultThe resulting rendered output.
node_rendered
d3t.signals.node_rendered
This is sent immediately after a node is rendered.
Arguments sent with this signal:
-
senderThe
Node
class. -
instanceThe actual node instance being rendered.
-
resultThe resulting rendered output.