Django - test z post request

0

Cześć,
zrobilem view.py dotyczące użytkownika i przy okazji chciałem nauczyć się trochę testowania.
Nie ukrywam, że te testy to taki zlepek rzeczy znalezionych w internecie i pewnie można dodać kilka rzeczy. Także jeżeli ktoś ma jeszcze jakieś sugestie to można pisać śmiało.
Natomiast mam problem z jednym testem gdzie używamy posta.

chodzi o test_register_POST_adds_new_register. Zwraca mi AsserationError: 200 != 302.
Czytałem, że może się tak dziać gdy źle wypełnię zmienną response. Próbowałem zapisać nawias {} w różnych konfiguracjach ale nadal jest to samo albo pojawiają się jeszcze dziwniejsze błędy. Może mi ktoś podpowie co jest nie tak.

Przy okazji mam jeszcze pytanie czy jest jakaś opcja, żeby testować czy po przesłaniu post wyświetla się poprawny komunikat np. messages.succes()

test_views.py

from django.contrib.auth.models import User
from django.test import TestCase, Client
from django.urls import reverse
from users.models import Profile


class TestViews(TestCase):

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user('john', '[email protected]',
                                             'johnpassword')
        self.profile = Profile.objects.create(user_id=1)
        self.list_url = reverse('dashboard')
        self.register_url = reverse('register')
        self.edit_url = reverse('edit')

    def test_dashboard_GET(self):
        self.client.login(username='john', password='johnpassword')

        response = self.client.get(self.list_url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'account/dashboard.html')

    def test_register_GET(self):

        response = self.client.get(self.register_url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'account/register.html')

    def test_edit_GET(self):
        self.client.login(username='john', password='johnpassword')

        response = self.client.get(self.edit_url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'account/edit.html')

    def test_register_POST_adds_new_register(self):

        response = self.client.post(self.register_url, {'username': 'john123',
                                                        'email':
                                                            '[email protected]',
                                                        'first_name':
                                                            'johny',
                                                        'password':
                                                            'johnpass'})


        self.assertEqual(response.status_code, 302)
        self.assertTemplateUsed(response, 'account/register_done.html')

    def test_edit_POST(self):
        response = self.client.post(self.edit_url, {'first_name': 'john'})

        self.assertEqual(response.status_code, 302)

views.py

from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib import messages

from .models import Profile
from .forms import UserRegistrationForm, UserEditForm, ProfileEditForm


# Create your views here.


@login_required
def dashboard(request):
    return render(request, 'account/dashboard.html', {'section': dashboard})


def register(request):
    if request.method == 'POST':
        user_form = UserRegistrationForm(request.POST)
        if user_form.is_valid():
            new_user = user_form.save(commit=False)
            new_user.set_password(user_form.cleaned_data['password'])
            new_user.save()
            Profile.objects.create(user=new_user)
            return render(request, 'account/register_done.html', {'new_user':
                                                                      new_user})
    else:
        user_form = UserRegistrationForm()
    return render(request, 'account/register.html',
                  {'user_form': user_form})


@login_required
def edit(request):
    if request.method == 'POST':
        user_form = UserEditForm(instance=request.user, data=request.POST)
        profile_form = ProfileEditForm(instance=request.user.profile,
                                       data=request.POST, files=request.FILES)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, 'Profil został zaktualizowany!')
        else:
            messages.error(request, 'Wystąpił błąd podczas aktualizacji '
                                    'profilu.')
    else:
        user_form = UserEditForm(instance=request.user)
        profile_form = ProfileEditForm(instance=request.user.profile)

    return render(request, 'account/edit.html', {'user_form': user_form,
                                                 'profile_form': profile_form})

forms.py

from django import forms
from django.contrib.auth.models import User

from .models import Profile


class LoginForm(forms.Form):
    username = forms.CharField(label='Nazwa użytkownika lub e-mail',
                               max_length=20)
    password = forms.CharField(widget=forms.PasswordInput)


class UserRegistrationForm(forms.ModelForm):
    password = forms.CharField(label='Hasło', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Powtórz hasło',
                                widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('username', 'first_name', 'email')

    def clean_password2(self):
        cd = self.cleaned_data
        if cd['password'] != cd['password2']:
            raise forms.ValidationError('Hasła nie są identyczne.')
        return cd['password2']

class UserEditForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

class ProfileEditForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ('date_of_birth', 'photo')
1

Hmm 302 to redirect nie mas tam redirecta w tym widoku tylko render czyli 200, możesz dać print(response.content) i zobaczyć co tam je.... https://www.obeythetestinggoat.com/book/chapter_01.html

Tu jak ten msg sprawdzić

        html = response.content.decode('utf8')  
        self.assertTrue(html.startswith('<html>'))  
        self.assertIn(''Profil został zaktualizowany!", html)  
        self.assertTrue(html.endswith('</html>'))  

1

Jeżeli chcesz uzyskać 302, to zamiast render użyj redirect i przekieruj na odpowiednią stronę. Chyba, że nie koniecznie chcesz uzyskać 302, wtedy zmień w teście 302 na 200.

W celu przetestowania działania POST spróbuj użyć self.client.post:
https://docs.djangoproject.com/en/3.2/topics/testing/tools/

1 użytkowników online, w tym zalogowanych: 0, gości: 1