Django - test z post request

Django - test z post request
L8
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 2 lata
  • Postów:33
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

Kopiuj
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', 'john@example.com',
                                             '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':
                                                            'john@john.com',
                                                        '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

Kopiuj
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

Kopiuj
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')
RA
  • Rejestracja:prawie 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:221
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ć

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

edytowany 1x, ostatnio: Rado
Haskell
  • Rejestracja:prawie 10 lat
  • Ostatnio:12 miesięcy
  • Postów:4700
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/


Zaglądali do kufrów, zaglądali do waliz, nie zajrzeli do d**y - tam miałem socjalizm. Czesław Miłosz

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.