Bagaimana saya harus menulis tes untuk Formulir di Django?

110

Saya ingin mensimulasikan permintaan ke pandangan saya di Django ketika saya menulis percobaan. Ini terutama untuk menguji formulir. Berikut cuplikan permintaan pengujian sederhana:

from django.tests import TestCase

class MyTests(TestCase):
    def test_forms(self):
        response = self.client.post("/my/form/", {'something':'something'})
        self.assertEqual(response.status_code, 200) # we get our page back with an error

Halaman selalu mengembalikan respon 200 apakah ada kesalahan formulir atau tidak. Bagaimana cara memeriksa bahwa Formulir saya gagal dan bidang tertentu ( soemthing) mengalami kesalahan?

Mridang Agarwalla
sumber

Jawaban:

250

Saya pikir jika Anda hanya ingin menguji formulir, maka Anda harus menguji formulir dan bukan tampilan di mana formulir tersebut dirender. Contoh untuk mendapatkan ide:

from django.test import TestCase
from myapp.forms import MyForm

class MyTests(TestCase):
    def test_forms(self):
        form_data = {'something': 'something'}
        form = MyForm(data=form_data)
        self.assertTrue(form.is_valid())
        ... # other tests relating forms, for example checking the form data
Torsten Engelbrecht
sumber
62
+1. Ide pengujian unit adalah untuk menguji setiap unit secara terpisah.
Daniel Roseman
13
@Daniel Tapi tes integrasi jauh lebih berguna dan lebih mungkin untuk menangkap bug.
wobbily_col
19
@wobbily_col Juga membutuhkan lebih banyak waktu untuk menemukan bug yang sebenarnya dalam pengujian integrasi. Dalam pengujian unit itu lebih jelas. Saya pikir untuk cakupan tes yang baik, Anda tetap membutuhkan keduanya.
Torsten Engelbrecht
11
Ini adalah cara Anda memeriksa kesalahan formulir tertentu:self.assertEquals(form.errors['recipient'], [u"That recipient isn't valid"])
Emil Stenström
18
self.assertEqual(form.is_valid(), True)dapat disederhanakan:self.assertTrue(form.is_valid())
Adam Taylor
76

https://docs.djangoproject.com/en/stable/topics/testing/tools/#django.test.SimpleTestCase.assertFormError

from django.tests import TestCase

class MyTests(TestCase):
    def test_forms(self):
        response = self.client.post("/my/form/", {'something':'something'})
        self.assertFormError(response, 'form', 'something', 'This field is required.')

Di mana "formulir" adalah nama variabel konteks untuk formulir Anda, "sesuatu" adalah nama bidang, dan "Bidang ini wajib diisi". adalah teks persis dari kesalahan validasi yang diharapkan.

Shane
sumber
Ini menimbulkan AttibuteError untuk saya: AttributeError: objek 'SafeUnicode' tidak memiliki atribut 'error'
sbaechler
untuk pengguna pemula: buat pengguna sebelumnya dan gunakan self.client.force_login(self.user)sebagai baris pertama dalam metode pengujian.
sgauri
Saya mengalami masalah dengan posting ini (), kemudian saya menemukan bahwa saya harus mengirimkannya sebagai multipart sebagai berikut response = self.client.post ("/ form-url /", data = {'name': 'test123' , 'category': 1, 'note': 'note123'}, content_type = django.test.client.MULTIPART_CONTENT) Jika ada yang terjebak dengan mendapatkan instance kosong saat menyimpan formulir, periksa permintaan yang dikirim dari browser
Ghaleb Khaled
17

Jawaban asli tahun 2011 adalah

self.assertContains(response, "Invalid message here", 1, 200)

Tapi saya lihat sekarang (2018) ada banyak sekali pernyataan yang berlaku tersedia :

  • assertRaisesMessage
  • assertFieldOutput
  • assertFormError
  • assertFormsetError

Ambil pilihanmu.

John Mee
sumber
+1 Ini berfungsi untuk saya ketika itu adalah kesalahan Formulir umum yang tidak dilampirkan ke bidang.
Aaron Lelevier