question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Tests for template tags with pytest-xdist and pytest-cov break view tests using the template tags

See original GitHub issue

This was a weird one for me to figure out, but it should be simple to reproduce:

1.) You have a template tag library “foo” 2.) You have a view using a template using that library via load foo 3.) Being a thorough tester, you decide you need a test for the template tag library, which means you have to from app.templatetags import foo in your test. 4.) And of course you need to test the view using the templatetag. 5.) And maybe you have to test the templatetag before the view (not sure if this is relevant) e.g. pytest discovery puts it before the view test. 6.) And since you have many tests, you run pytest --cov -n 2

Which results in an error like the following:

django.template.exceptions.TemplateSyntaxError: 'foo' is not a registered tag library.

(maybe related to #110, but I don’t see any of the problems described in that issue)

Workaround:

  • You put the business code you want to test in a different module (one that is not imported from a template) and register the tags manually via
from django import template
from ._foo import (tag1, tag2)

register = template.Library()

register.filter(is_safe=True)(tag1)
register.tag()(tag2)

And of course you import _foo in your test, instead of the template library.

I’m not sure if I should file this with pytest-xdist or pytest-cov, since it definitely only occurs if both are used. I’m filing this here first and we can figure out if it really is xdist’s fault.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
ionelmccommented, May 5, 2019

Ok so I’ve tried the code. As explained before the problem are some missing imports. Apply this to fix your project:

diff --git a/.envrc b/.envrc
index 2188da1..990bc1d 100644
--- a/.envrc
+++ b/.envrc
@@ -1 +1,2 @@
 export DJANGO_SETTINGS_MODULE=proj.settings
+export PYTHONPATH=proj
diff --git a/proj/app/__init__.py b/proj/app/__init__.py
index e69de29..7ec32ee 100644
--- a/proj/app/__init__.py
+++ b/proj/app/__init__.py
@@ -0,0 +1 @@
+from . import templatetags
diff --git a/proj/app/templatetags/__init__.py b/proj/app/templatetags/__init__.py
index e69de29..2e046b5 100644
--- a/proj/app/templatetags/__init__.py
+++ b/proj/app/templatetags/__init__.py
@@ -0,0 +1 @@
+from . import tags
diff --git a/proj/pytest.ini b/proj/pytest.ini
deleted file mode 100644
index b0a6fc8..0000000
--- a/proj/pytest.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[pytest]
-# needs pytest-django:
-DJANGO_SETTINGS_MODULE = airshield.settings_test
0reactions
TauPancommented, May 5, 2019

Ok, it appears to be as you explained in https://github.com/pytest-dev/pytest-cov/issues/285#issuecomment-488733091

in fact against current master the following patch is sufficient to not cause an error:

diff --git a/proj/app/__init__.py b/proj/app/__init__.py
index e69de29..7ec32ee 100644
--- a/proj/app/__init__.py
+++ b/proj/app/__init__.py
@@ -0,0 +1 @@
+from . import templatetags
diff --git a/proj/app/templatetags/__init__.py b/proj/app/templatetags/__init__.py
index e69de29..2e046b5 100644
--- a/proj/app/templatetags/__init__.py
+++ b/proj/app/templatetags/__init__.py
@@ -0,0 +1 @@
+from . import tags

pytest --cov -n2 completes green with the following result:

============================================================================ test session starts =============================================================================
platform linux -- Python 3.6.8, pytest-4.4.1, py-1.8.0, pluggy-0.9.0
Django settings: proj.settings (from environment variable)
rootdir: /home/friedel/git/pytest-django-xdist-cov-bug
plugins: xdist-1.28.0, forked-1.0.2, django-3.4.8, cov-2.7.1
gw0 [2] / gw1 [2]
..                                                                                                                                                                     [100%]

----------- coverage: platform linux, python 3.6.8-final-0 -----------
Name                                Stmts   Miss  Cover
-------------------------------------------------------
proj/app/__init__.py                    1      0   100%
proj/app/admin.py                       1      0   100%
proj/app/models.py                      1      0   100%
proj/app/templatetags/__init__.py       1      0   100%
proj/app/templatetags/tags.py           4      0   100%
proj/app/views.py                       3      0   100%
proj/proj/__init__.py                   0      0   100%
proj/proj/urls.py                       4      0   100%
-------------------------------------------------------
TOTAL                                  15      0   100%

========================================================================== 2 passed in 2.16 seconds ==========================================================================

But the result raises more questions (which is probably a good thing):

1.) home.html is not only reported with coverage of 0% (probably because of https://github.com/nedbat/django_coverage_plugin/issues/36 ) but omitted completely.

2.) https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/ (or 1.11 or any version) does not mention that templatetags libraries need to be imported anywhere. I’m not sure if any of the relevant modules mentions that (pytest-cov, pytest-xdist, pytest-django or django_coverage_plugin). Since production code runs without those imports (and --cov and -n2 on their own as well) I suspect there’s still a bug somewhere and importing those modules explicitly is just a workaround, with the advantage that it’s simpler than my initial workaround of moving the busines code of the template tags and filters out of the tag library module and testing it separately.

You seem sure that there’s no bug in pytest-cov, so I suspect there might be one in pytest-django or pytest_coverage_plugin.

In any case, thanks for your assistance!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Tests for template tags with pytest-xdist and pytest-cov break ...
3.) Being a thorough tester, you decide you need a test for the template tag library, which means you have to from app.templatetags...
Read more >
Tests for template tags with pytest-xdist and ... - Bountysource
Tests for template tags with pytest-xdist and pytest-cov break view tests using the template tags.
Read more >
pytest-cov - Read the Docs
This plugin produces coverage reports. Compared to just using coverage run this plugin does some extras: • Subprocess support: you can fork ...
Read more >
pytest-cov - PyPI
This plugin produces coverage reports. Compared to just using coverage run this plugin does some extras: Subprocess support: you can fork or run...
Read more >
Test Custom template tags in Django#6 - YouTube
Django Testing Tutorials- How to test Inclusion Template Tags | Test Custom template tags in Django#6, https://youtu.be/Z7x3Wb2BDs8.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found