diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt
index c38e8695aab..3ffb042ae97 100644
--- a/tests/requirements/base.txt
+++ b/tests/requirements/base.txt
@@ -1,5 +1,6 @@
bcrypt
docutils
+jinja2
# move to py2.txt when dropping Python 3.2
mock
numpy
diff --git a/tests/template_backends/__init__.py b/tests/template_backends/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/template_backends/forbidden/template_backends/hello.html b/tests/template_backends/forbidden/template_backends/hello.html
new file mode 100644
index 00000000000..14240a43ee9
--- /dev/null
+++ b/tests/template_backends/forbidden/template_backends/hello.html
@@ -0,0 +1 @@
+Hu ho.
diff --git a/tests/template_backends/jinja2/template_backends/csrf.html b/tests/template_backends/jinja2/template_backends/csrf.html
new file mode 100644
index 00000000000..081577fe3ae
--- /dev/null
+++ b/tests/template_backends/jinja2/template_backends/csrf.html
@@ -0,0 +1 @@
+{{ csrf_input }}
diff --git a/tests/template_backends/jinja2/template_backends/hello.html b/tests/template_backends/jinja2/template_backends/hello.html
new file mode 100644
index 00000000000..4ce626e9be1
--- /dev/null
+++ b/tests/template_backends/jinja2/template_backends/hello.html
@@ -0,0 +1 @@
+Hello {{ name }}!
diff --git a/tests/template_backends/template_strings/template_backends/csrf.html b/tests/template_backends/template_strings/template_backends/csrf.html
new file mode 100644
index 00000000000..b1c144dcb7d
--- /dev/null
+++ b/tests/template_backends/template_strings/template_backends/csrf.html
@@ -0,0 +1 @@
+$csrf_input
diff --git a/tests/template_backends/template_strings/template_backends/hello.html b/tests/template_backends/template_strings/template_backends/hello.html
new file mode 100644
index 00000000000..7a1b4446c73
--- /dev/null
+++ b/tests/template_backends/template_strings/template_backends/hello.html
@@ -0,0 +1 @@
+Hello $name!
diff --git a/tests/template_backends/templates/template_backends/csrf.html b/tests/template_backends/templates/template_backends/csrf.html
new file mode 100644
index 00000000000..a8367c4f081
--- /dev/null
+++ b/tests/template_backends/templates/template_backends/csrf.html
@@ -0,0 +1 @@
+{% csrf_token %}
diff --git a/tests/template_backends/templates/template_backends/hello.html b/tests/template_backends/templates/template_backends/hello.html
new file mode 100644
index 00000000000..4ce626e9be1
--- /dev/null
+++ b/tests/template_backends/templates/template_backends/hello.html
@@ -0,0 +1 @@
+Hello {{ name }}!
diff --git a/tests/template_backends/test_django.py b/tests/template_backends/test_django.py
new file mode 100644
index 00000000000..5c5070cb188
--- /dev/null
+++ b/tests/template_backends/test_django.py
@@ -0,0 +1,9 @@
+from django.template.backends.django import DjangoTemplates
+
+from .test_dummy import TemplateStringsTests
+
+
+class DjangoTemplatesTests(TemplateStringsTests):
+
+ engine_class = DjangoTemplates
+ backend_name = 'django'
diff --git a/tests/template_backends/test_dummy.py b/tests/template_backends/test_dummy.py
new file mode 100644
index 00000000000..e79dbbe02a7
--- /dev/null
+++ b/tests/template_backends/test_dummy.py
@@ -0,0 +1,70 @@
+# coding: utf-8
+
+from __future__ import unicode_literals
+
+from django.http import HttpRequest
+from django.middleware.csrf import CsrfViewMiddleware, get_token
+from django.template import TemplateDoesNotExist
+from django.template.backends.dummy import TemplateStrings
+from django.test import SimpleTestCase
+
+
+class TemplateStringsTests(SimpleTestCase):
+
+ engine_class = TemplateStrings
+ backend_name = 'dummy'
+ options = {}
+
+ @classmethod
+ def setUpClass(cls):
+ params = {
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'NAME': cls.backend_name,
+ 'OPTIONS': cls.options,
+ }
+ cls.engine = cls.engine_class(params)
+
+ def test_from_string(self):
+ template = self.engine.from_string("Hello!\n")
+ content = template.render()
+ self.assertEqual(content, "Hello!\n")
+
+ def test_get_template(self):
+ template = self.engine.get_template('template_backends/hello.html')
+ content = template.render({'name': 'world'})
+ self.assertEqual(content, "Hello world!\n")
+
+ def test_get_template_non_existing(self):
+ with self.assertRaises(TemplateDoesNotExist):
+ self.engine.get_template('template_backends/non_existing.html')
+
+ def test_html_escaping(self):
+ template = self.engine.get_template('template_backends/hello.html')
+ context = {'name': ''}
+ content = template.render(context)
+
+ self.assertIn('<script>', content)
+ self.assertNotIn('