Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

How to find templates that are never executed? #4

Closed
nedbat opened this issue Jan 24, 2015 · 17 comments
Closed

How to find templates that are never executed? #4

nedbat opened this issue Jan 24, 2015 · 17 comments

Comments

@nedbat
Copy link
Owner

nedbat commented Jan 24, 2015

With .py files, --source will find files that were never even executed once. What's the equivalent for template files?

@jessamynsmith
Copy link
Contributor

I ran into this on one of my projects. I had unit tests on views, but they weren't actually calling views that rendered templates, so I wasn't getting any template coverage. Perhaps the plugin should inspect settings.TEMPLATE_DIRS and report on all files found therein? That will cover cases where the user has templates in unusual places. It might also be possible to leverage settings.TEMPLATE_LOADERS to find all templates in the project. By default, Django checks every app for a templates directory.

@nedbat
Copy link
Owner Author

nedbat commented Feb 20, 2015

One thing I'm not sure of, is how to know what are template files. With Python files, I can look for .py files. But template files could have any extension. Is it true that every file in the TEMPLATE_DIRS tree is a template? Do we need a configuration option for the plugin which is the extensions to consider as templates?

@PamelaM
Copy link
Collaborator

PamelaM commented Jan 14, 2016

I can't speak for every project, but for ours, every file in TEMPLATE_DIRS is a template.

One could add optional settings for:
(a) template_extensions (defaults to .*, but for most of us it will be .html)
(b) If you open a file, parse it, and there's no template language (e.g. '{%' or '{{'), it's not a template

But I think treating the TEMPLATE_DIRS as containing all templates will be good enough.

@sergei-maertens
Copy link

You could inspire yourself on how makemessages works, that one also loops through all the templates and it's an option to specify extensions other than the defaults.

I wrote a library that also loops through all template files in the same way, you could maybe use that as inspiration: https://github.com/sergei-maertens/django-systemjs/blob/develop/systemjs/management/commands/systemjs_bundle.py#L64

Other than that, some .coveragerc options to manually specify directories/files might also be an option?

@edwardotis
Copy link

+1 to fix this issue
and +1 for every file in TEMPLATES['DIRS'] can be considered a template file. (people can use omit if they put non-templates in there.)

fyi, I still cannot get this plugin configured to pick up a single template.

@saulshanabrook
Copy link

But template files could have any extension. Is it true that every file in the TEMPLATE_DIRS tree is a template?

For all my projects, this is true. I can't think of a reason why you would put a file in there that isn't a template.

@clokep
Copy link

clokep commented Sep 8, 2017

Just chiming in that for us every file in TEMPLATE_DIRS is a template...and not all of them have a .html extension (.txt and .subject are common other ones).

@schinckel
Copy link

I think the mechanism that is there only looks in settings.TEMPLATES[i][DIRS] - we have apps that have their own templates - those should be included too.

@schinckel
Copy link

Oh wait, that's not in the released code - the HEAD in git will find all HTML files in the tested directories.

My comment about APP_DIRS stands though - but then how do we know which apps to include, I suppose? Generally only internal apps are tested in my project.

@charettes
Copy link
Contributor

One way this could be solved is to file a Django feature request to add a method to engines that returns all of their templates.

@schinckel
Copy link

Hmm. I think that might work, because I think that coverage will only include files that are inside the coverage source directories. I'm not familiar enough with it to state definitively, but I think that's what I saw yesterday.

@schinckel
Copy link

@charettes Will this return all templates that are in the tree, or only those that are actually loaded? I feel like it's the latter...

@charettes
Copy link
Contributor

@schinckel the idea would be for engines to return all valid identifiers they allow. The thing is not all template custom engines are file based; some third-party ones are backed by models for example.

@jambonrose
Copy link
Collaborator

Given that #39 was merged and implements the feature, I am closing this issue.

@schinckel : When I run tests with django_coverage_plugin, I am seeing missing template files from app directories, and have not been able to replicate conditions where they are missing. If you're not seeing missing templates when they're in app_name/templates please open a new issue (with code, if possible!). Thank you.

Several people expressed the desire to be able to match files that don't end with .html or .htm. This sounds like a reasonable feature to be, so I will be opening a new issue for that.

@charettes
Copy link
Contributor

@jambonrose does it work for TEMPLATES.DIR as well?

e.g.

TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_PATH, 'templates'),
    }
]

@jambonrose
Copy link
Collaborator

I thought so, but you have me second-guessing myself. Let me double-check.

@jambonrose
Copy link
Collaborator

@charettes : I am able to see missing templates from my test run even when they are in a templates directory at the root of the project. However, the results were not exactly what I expected.

On top of changing the TEMPLATES setting, I informed .coveragerc of the new templates directory.

[run]
branch = true
omit =
    *migrations*,
    *tests*,
parallel = true
source =
    user_integration
    templates
plugins =
    django_coverage_plugin

[report]
show_missing = true
precision = 2

Output for templates dir:

Name                                                  Stmts   Miss Branch BrPart     Cover   Missing
----------------------------------------------------------------------------------------------------
templates/base.html                                      15      0      0      0   100.00%
templates/home.html                                       7      0      0      0   100.00%
templates/registration/activation_complete.html           2      0      0      0   100.00%
templates/registration/activation_email.txt               6      0      0      0   100.00%
templates/registration/activation_email_subject.txt       1      0      0      0   100.00%
templates/registration/#.html                        15      0      0      0   100.00%
templates/registration/logout.html                        2      2      0      0     0.00%   1-7
templates/registration/password_reset_done.html           2      0      0      0   100.00%
templates/registration/registration_complete.html         2      0      0      0   100.00%
templates/registration/registration_form.html             7      0      0      0   100.00%
user_integration/__init__.py                              0      0      0      0   100.00%
user_integration/apps.py                                  3      0      0      0   100.00%
user_integration/urls.py                                  6      0      0      0   100.00%
----------------------------------------------------------------------------------------------------
TOTAL                                                    68      2      0      0    97.06%

The logout.html template is definitely not being used, so it's correctly listed as being missing.

However, running the same tests with templates in the app directory yields different results: password_reset_done.html is not covered.

Name                                                                   Stmts   Miss Branch BrPart     Cover   Missing
---------------------------------------------------------------------------------------------------------------------
user_integration/__init__.py                                               0      0      0      0   100.00%
user_integration/apps.py                                                   3      0      0      0   100.00%
user_integration/templates/base.html                                      15      0      0      0   100.00%
user_integration/templates/home.html                                       7      0      0      0   100.00%
user_integration/templates/registration/activation_complete.html           2      0      0      0   100.00%
user_integration/templates/registration/activation_email.txt               6      0      0      0   100.00%
user_integration/templates/registration/activation_email_subject.txt       1      0      0      0   100.00%
user_integration/templates/registration/#.html                        15      0      0      0   100.00%
user_integration/templates/registration/logout.html                        2      2      0      0     0.00%   1-7
user_integration/templates/registration/password_reset_done.html           2      2      0      0     0.00%   1-5
user_integration/templates/registration/registration_complete.html         2      0      0      0   100.00%
user_integration/templates/registration/registration_form.html             7      0      0      0   100.00%
user_integration/urls.py                                                   6      0      0      0   100.00%
---------------------------------------------------------------------------------------------------------------------
TOTAL                                                                     68      4      0      0    94.12%

The project is setup such that Django's Admin template is used for password_reset_done.html instead of the local one, so my local templates should also be at 0% coverage. I suspect that when the template is in the templates directory in the root of the project, the plugin cannot differentiate between the local and admin versions (which is a bug?). Some further examination is required.

The bottom line, however, is that as long as you don't have namespace clashes between apps, you should be able to see missing templates regardless of their location. That said, please correct me if I'm not understanding the problem.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants