pythondjangopytestpytest-django

Third test in Django with Pytest is failed because "django.template.exceptions.TemplateDoesNotExist"


I got 3 tests in django using pytest, the first two tests are alright untill third one which cannot find Template. Last 2 of 3 are working with same template but second one cannot find the template.

FAILED app_wallet/accounts/tests/test_pytest.py::test_login_failed - django.template.exceptions.TemplateDoesNotExist: main_layout.html

#test_pytest.py

import pytest
from django.urls import reverse
from django.contrib.auth.models import User

pytestmark = pytest.mark.django_db

def test_create_account_success(client):
    client_url = reverse('accounts:create')
    data = {
        'username': 'test',
        'email': 'test@domain.pl',
        'password1': 'myPassword123',
        'password2': 'myPassword123',
    }
    response = client.post(path=client_url, data=data)
    user = User.objects.all().first()
    assert response.status_code == 302 # redirected to another page - valid data
    assert User.objects.all().count() == 1
    assert user.username == data.get('username')
    assert user.email == data.get('email')
    


def test_login_success(client):
    client_url = reverse('accounts:login')
    user = User.objects.create_user(username='test123', password='Password123', email='test@domain.pl')
    data = {
        'username': 'test123',
        'password': 'Password123'
    }
    response = client.post(path=client_url, data=data)

    assert response.status_code == 302 # redirected to another page - valid data
    assert User.objects.all().first().username == data.get('username')
    assert User.objects.all().first().email == 'test@domain.pl'


def test_login_failed(client):
    client_url = reverse('accounts:login')
    user = User.objects.create_user(username='test123', password='Password123', email='test@domain.pl')
    data = {
        'username': 'test123',
        'password': 'Password12'
    }
    response = client.post(path=client_url, data=data)

    assert response.status_code == 200
    assert User.objects.all().count() == 1
    assert User.objects.all().first().username != data.get('username')
#views.py

def login_view(request):
    if request.method == 'POST':

        form = LoginForm(request, data=request.POST)
        if form.is_valid():
            user_data = form.cleaned_data
            user = authenticate(request, username=user_data.get('username'), password=user_data.get('password'))
            login(request, user)
            return redirect(reverse('wallets:wallets'))
    
    else:
        form = LoginForm(request)

    context = {
        'form': form
    }
    return render(request, 'accounts/login.html', context=context)
#forms.py 

class LoginForm(AuthenticationForm):
    username = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': 'Login'}))
    password = forms.CharField(label='', widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
#login.html 

{% extends 'main_layout.html' %}

{% block head %}

<title> Test 123 </title>

{% endblock %}

{% block main %}

    <form method='POST'>
        {% csrf_token %}
        {{form.as_p}}
        <input type='submit' value='Login'>
    </form>


{% endblock %}
#main_layout.html

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        {% block head %}
        
        {% endblock %}

    </head>
    <body>
        <style>
            body {
                margin:0;

            }

            ul {
                list-style-type: none;
                margin: 0;
                padding: 0;
                overflow: hidden;
                background-color: #333333;
                }
            li {
                float: left;
            }

            li a {
              display: block;
              color:white;
              text-align: center;
              padding: 16px;
              text-decoration: none;
            }

        </style>
        <ul>
            <li> 
                <a href="{% url 'accounts:create' %}"> Sign Up </a>
            </li>
            <li>
                <a href="{% url 'accounts:login' %}"> Login </a>
            </li>
            {% if request.user.is_authenticated %} 
            <li>
                <a href="{% url 'accounts:logout' %}"> Logout </a> 
            </li>
            {% endif %}
            <li>
                <a href="{% url 'wallets:wallets' %}"> Wallets </a>
            </li>
            <li> 
                <a href="{% url 'wallets:create' %}"> New Wallet </a>
            </li>
        </ul>
        {% block main %}



        {% endblock %}

    </body>
</html>
->AppWallet(Project Folder)
---> Wallets (App)

---> Accounts (App)
-----> Other Folders
----->Templates
------->Accounts
--------->login.html

---> AppWallet (Project)

---> Templates
----->main_layout.html

More details of error:

self = <Engine: dirs=[PosixPath('/home/montypython/programming/projects/app_wallet/app_wallet'), 'templates'] app_dirs=True c...ltins=['django.template.defaulttags', 'django.template.defaultfilters', 'django.template.loader_tags'] autoescape=True>
name = 'main_layout.html', dirs = None
skip = [<Origin name='/home/montypython/programming/projects/app_wallet/app_wallet/accounts/templates/accounts/login.html'>]

    def find_template(self, name, dirs=None, skip=None):
        tried = []
        for loader in self.template_loaders:
            try:
                template = loader.get_template(name, skip=skip)
                return template, template.origin
            except TemplateDoesNotExist as e:
                tried.extend(e.tried)
>       raise TemplateDoesNotExist(name, tried=tried)
E       django.template.exceptions.TemplateDoesNotExist: main_layout.html

../../../.local/share/virtualenvs/app_wallet-QbJixBYD/lib/python3.10/site-packages/django/template/engine.py:161: TemplateDoesNotExist

The above exception was the direct cause of the following exception:

client = <django.test.client.Client object at 0x7f9b7fa1c5b0>

    def test_login_failed(client):
        client_url = reverse('accounts:login')
        user = User.objects.create_user(username='test123', password='Password123', email='test@domain.pl')
        data = {
            'username': 'test123',
            'password': 'Password12'
        }
>       response = client.post(path=client_url, data=data)

Some additional info:

platform linux -- Python 3.10.12, pytest-7.4.0, pluggy-1.3.0
django: settings: app_wallet.settings (from ini)
rootdir: /home/montypython/programming/projects/app_wallet
configfile: pytest.ini
plugins: django-4.5.2
collected 3 items   
#pytest.ini

[pytest]
DJANGO_SETTINGS_MODULE = app_wallet.settings

pythonpath = /home/montypython/programming/projects/app_wallet /home/montypython/programming/projects/app_wallet/app_wallet

Problem occurs only if i pass invalid data in test_case to login_view, but if i test it manually nothing is wrong.

The most interesting part is that if password or login is incorrect so even before checking them, Pytest spit with the error that cannot find template.

But!

If i change login/password from incorrect to correct one, test executes and everything is alright.

UPDATE: Suddenly, don't know why it works now. Just created another folder and copied to it and everything is alright.


Solution

  • Just created another project folder and copied to it and everything is alright.