Satuan percobaan¶
Django datang dengan deretan percobaan dia sendiri, di pelipat tests
dari kode dasar. Itu kebijakan kami untuk memastikan semua percobaan selalu lolos.
Kami menghargai apapun dan semua bantuan pada deretan percobaan!
Percobaan Django semua menggunakan infrastruktur percobaan yang dikirim dengan Django untuk aplikasi percobaan. Lihat Menulis dan menjalankan percobaan untuk sebuah penjelasan bagaimana menulis percobaan baru.
Menjalankan satuan percobaan¶
Mulai cepat¶
Pertama, fork Django on GitHub.
Kedua, buat dan aktifkan lingkungan maya. Jika anda tidak akrab dengan bagaimana melakukan itu, baca contributing tutorial kami.
Selanjutnya, kloning cabang anda, pasang beberapa persyaratan, dan jalankan percobaan:
$ git clone https://github.com/YourGitHubName/django.git django-repo
$ cd django-repo/tests
$ python -m pip install -e ..
$ python -m pip install -r requirements/py3.txt
$ ./runtests.py
...\> git clone https://github.com/YourGitHubName/django.git django-repo
...\> cd django-repo\tests
...\> py -m pip install -e ..
...\> py -m pip install -r requirements\py3.txt
...\> runtests.py
Memasang membutuhkan akan sepertinya membutuhkan beberapa paket sistem operasi dimana komputer anda tidak dipasang. Anda dapat biasanya mencari tahu paket mana untuk dipasang dengan melakukan pencarian Jaringan untuk baris terakhir atau selanjutnya dari pesan kesalahan. Coba menambahkan sistem operasi anda pada permintaan pencarian jika dibutuhkan.
Jika anda mempunyai masalah memasang persyaratan, anda dapat melewatkan langkah itu. Lihat Menjalankan semua percobaan untuk rincian pada memasang pilihan percobaan ketergantungan. Jika anda tidak mempunyai pilihan ketergantungan terpasang, percobaan yang membutuhkan itu akan dilewatkan.
Menjalankan percobaan membutuhkan modul pengaturan Django yang menentukan basisdata yang digunakan. Untuk membantu anda memulai, Django menyediakan dan menggunakan contoh modul pengaturan yang menggunakan basisdata SQLite. Lihat Gunakan modul pengaturan lain untuk mempelajari bagaimana menggunakan modul pengaturan berbeda untuk menjalankan percobaan dengan basisdata berbeda.
Mempunyai masalah? Lihat Menyelesaikan masalah untuk beberapa masalah umum.
Menjalankan percobaan menggunakan tox
¶
Tox adalah sebuah alat untuk menjalankan lingkungan maya berbeda. Django menyertakan tox.ini
dasar yang mengotomatisasi beberapa pemeriksaan dimanapeladen pembangun kami berkinerja pada pull request. Untuk menjalankan satuan percobaan dan pemeriksaan lain (seperti import sorting, the documentation spelling checker, and code formatting), pasang dan jalankan perintah tox
dari tempat appun dalam pohon sumber Django:
$ python -m pip install tox
$ tox
...\> py -m pip install tox
...\> tox
Secara awalan, tox
menjalankan deretan percobaan dengan gabungan berkas pengaturan untuk SQLite, flake8
, isort
, dan dokumentasi pemeriksa pengejaan. Sebagai tambahan pada ketergantungan sistem dicatat ditempat lain dalam dokumentasi ini, perintah python3
harus di jalur anda dan terkait ke versi sesuai dari Python. Daftar dari lingkungan awalan dapat dilihat sebagai berikut:
$ tox -l
py3
flake8
docs
isort>=5.1.0
...\> tox -l
py3
flake8
docs
isort>=5.1.0
Mencoba versi Python lain dan backend basisdata¶
Sebagai tambahan pada lingkungan awal, tox
mendukung menjalankan deretan satuan percobaan untuk versi lain Python dan backend basisdata lain. Sejak deretan percobaan Django tidak menggabungkan berkas pengaturan untuk backend basisdata selain dari SQLite, bagaimanapun, anda harus create and provide your own test settings. Sebagai contoh, untuk menjalankan percobaan pada Python 3.7 menggunakan PostgreSQL:
$ tox -e py37-postgres -- --settings=my_postgres_settings
...\> tox -e py37-postgres -- --settings=my_postgres_settings
Perintah ini menyetel lingkungan maya Python 3.7, memasang ketergantungan deretan percobaan Django (termasuk untuk PostgreSQL), dan memanggil runtests.py
dengan argumen didukung (dalam kasus ini, --settings=my_postgres_settings
).
Sisa dari dokumentasi ini menunjukkan perintah untuk menjalankan percobaan tanpa tox
, bagaimanapun, pilihan apapun dilewatkan ke runtests.py
dapat juga dilewatkan ke tox
dengan menaruh di awalan daftar argumen dengan --
, seperti diatas.
Tox also respects the DJANGO_SETTINGS_MODULE
environment variable, if
set. For example, the following is equivalent to the command above:
$ DJANGO_SETTINGS_MODULE=my_postgres_settings tox -e py35-postgres
Pengguna Windows harus menggunakan:
...\> set DJANGO_SETTINGS_MODULE=my_postgres_settings
...\> tox -e py35-postgres
Menjalankan percobaan JavaScript¶
Django includes a set of JavaScript unit tests for
functions in certain contrib apps. The JavaScript tests aren't run by default
using tox
because they require Node.js
to be installed and aren't
necessary for the majority of patches. To run the JavaScript tests using
tox
:
$ tox -e javascript
...\> tox -e javascript
Perintah ini menjalankan npm install
untuk memastikan persyaratan percobaan terperbaharui dan kemudian menjalankan npm test
.
Menjalankan percobaan menggunakan django-docker-box
¶
django-docker-box mengizinkan anda menjalankan deretan percobaan terhadap semua basisdata yang didukung dan versi python. Lihat halaman proyek django-docker-box untuk pemasangan dan petunjuk penggunaan.
Gunakan modul pengaturan
lain¶
The included settings module (tests/test_sqlite.py
) allows you to run the
test suite using SQLite. If you want to run the tests using a different
database, you'll need to define your own settings file. Some tests, such as
those for contrib.postgres
, are specific to a particular database backend
and will be skipped if run with a different backend. Some tests are skipped or
expected failures on a particular database backend (see
DatabaseFeatures.django_test_skips
and
DatabaseFeatures.django_test_expected_failures
on each backend).
To run the tests with different settings, ensure that the module is on your
PYTHONPATH
and pass the module with --settings
.
Pengaturan DATABASES
dalam modul pengaturan percobaan apapun butuh menentukan dua basisdata:
- Basisdata
default
. Basisdata ini harus menggunakan backend yang anda ingin menggunakan untuk percobaan utama. - Sebuah basisdata dengan nama lain
other
. Basisdataother
digunakan untuk mencoba permintaan itu dapat dialihkan ke basisdata berbeda. Basisdata ini harus menggunakan backend sama sepertidefault
, dan itu harus mempunyai nama berbeda.
Jika anda menggunakan backend yang bukan SQLite, anda akan butuh menyediakan rincian lain untuk setiap basisdata:
- Pilihan
USER
butuh menentukan akun pengguna yang ada ntuk basisdata. Bahwa pengguna butuh perizinan untuk menjalankanCREATE DATABASE
sehingga basisdata percobaan dapat dibuat. - Pilihan
PASSWORD
butuh disediakan sandi untuk theUSER
yang telah ditentukan.
Basisdata percobaan mendapatkan nama-nama mereka dengan mengawali test_
pada nilai dari pengaturan NAME
untuk basisdata ditentukan di DATABASES
. Basisdata percobaan ini dihapus ketika percobaan selesai.
Anda akan juga butuh memastikan bahwa basisdata anda menggunakan UTF-8 sebagai kumpulan karakter awal. Jika peladen basisdata anda tidak menggunakan UTF-8 sebagai kumpulan karakter awal, anda akan butuh menyertakan sebuah nilai untuk CHARSET
di kamus pengaturan untuk basisdata yang berlaku.
Menjalankan hanya beberapa untuk percobaan¶
Deretan percobaan keseluruhan Django perlu waktu untuk berjalan, dan menjalankan setiap percobaan tunggal yang dapat berulang jika, katakan, anda cukup menambahkan percobaan pada Django yang anda ingin jalankan secara cepat tanpa menjalankan yang lainnya. Anda dapat menjalankan subkumpulan dari satuan percobaan dengan menambahkan nama-nama dari modul percobaan pada runtests.py
di baris perintah.
Sebagai contoh, jika anda ingin menjalankan percobaan hanya untuk hubugnan umum dan internasionalisasi, ketik:
$ ./runtests.py --settings=path.to.settings generic_relations i18n
...\> runtests.py --settings=path.to.settings generic_relations i18n
Bagaimana anda menemukan nama-nama dari percobaan perorangan? Lihat di tests/
— setiap nama pelipat ada nama dari percobaan.
Jika anda hanya ingin menjalankan hanya kelas tertentu dari percobaan, anda dapat menentukan daftar jalur pada masing-masing kelas percobaan. Sebgai contoh, untuk menjalankan TranslationTests
dari modul i18n
, ketik:
$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests
...\> runtests.py --settings=path.to.settings i18n.tests.TranslationTests
Melampaui itu, anda dapat menentukan metode percobaan sendiri seperti ini:
$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects
...\> runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects
Anda dapat menjalankan percobaan dimulai pada menentukan modul tingkat-atas dengan pilihan --start-at
. Sebagai contoh:
$ ./runtests.py --start-at=wsgi
...\> runtests.py --start-at=wsgi
Anda dapat juga menjalankan percobaan dimulai setelah modul tingkat-atas ditentukan dengan pilihan --start-after
. Sebagai contoh:
$ ./runtests.py --start-after=wsgi
...\> runtests.py --start-after=wsgi
Catat bahwa pilihan --reverse
tidak berpengaruh pada pilihan --start-at
atau --start-after
. Bahkan pilihan ini tidak dapat digunakan dengan label percobaan.
Menjalankan percobaan Selenium¶
Beberapa percobaan membutuhkan Selenium dan peramban Jaringan. Untuk menjalankan percobaan ini, anda harus memasang paket selenium dan menjalankan percobaan dengan pilihan --selenium=<BROWSERS>
. Sebagai contoh, jika anda memiliki Firefox dan Google Chrome terpasang:
$ ./runtests.py --selenium=firefox,chrome
...\> runtests.py --selenium=firefox,chrome
Lihat paket selenium.webdriver untuk daftar perambah tersedia.
Menentukan --selenium
otomatis menyetel --tags=selenium
untuk berjalan hanya percobaan yang membutuhkan selenium.
Beberapa peramban (yaitu Chrome atau Firefox) mendukung percobaan tanpa kepala, yang dapat lebih cepat dan lebih stabil. Tambah pilihan --headless
untuk mengaktifkan suasana ini.
Menjalankan semua percobaan¶
Jika anda ingin menjalankan deretan lengkap dari percobaan, anda akan butuh memasang sejumlah ketergantungan:
- aiosmtpd
- argon2-cffi 19.1.0+
- asgiref 3.3.2+ (dibutuhkan)
- bcrypt
- colorama
- docutils
- geoip2
- jinja2 2.7+
- numpy
- Pillow 6.2.0+
- PyYAML
- pytz (wajib)
- pywatchman
- setuptools
- memcached, ditambah supported Python binding
- gettext (gettext pada Windows)
- selenium
- sqlparse 0.2.2+ (dibutuhkan)
- tblib 1.5.0+
Anda dapat menemukan ketergantungan ini di pip requirements files didalam direktori tests/requirements
dari pohon sumber Django dan pasang mereka seperti itu:
$ python -m pip install -r tests/requirements/py3.txt
...\> py -m pip install -r tests\requirements\py3.txt
Jika anda menjumpai sebuah kesalahan selama pemasangan, sistem anda mungkin kehilangan ketergantungan dari satu atau lebih paket-paket Python. Rundingkan dokumentasi paket-paket gagal atau cari Jaringan dengan pesan kesalahan yang anda jumpai.
Anda dapat juga memasang pencocok basisdata dari pilihan anda menggunakan oracle.txt`, mysql.txt
, atau postgres.txt
.
Jika anda ingin mencoba backend penyimpanan memcache, anda akan juga butuh menentukan pengaturan CACHES
yang menunjuk pada contoh memcache anda.
Untuk menjalankan percobaan GeoDjango, anda akan butuh untuk setup a spatial database and install the Geospatial libraries.
Masing-masing ketergantungan ini adalah pilihan. Jika anda kehilangan salah satu dari mereka, percobaan terkait akan dilewati.
Untuk menjalankan beberapa percobaan dimuat otomatis, anda akan butuh memasang layanan Watchman.
Cakupan kode¶
Pembantu mendorong menjalankan cakupan pada deretan percobaan untuk mencirikan kawasan yang butuh percobaan tambahan. Pemasangan alat cakupan dan penggunaan digambarkan dalam testing code coverage.
Cakupan harus berjalan dalam proses tunggal untuk mendapatkan statistik akurat. Untuk menjalankan cakupan pada deretan percobaan Django menggunakan pengaturan percobaan standar:
$ coverage run ./runtests.py --settings=test_sqlite --parallel=1
...\> coverage run runtests.py --settings=test_sqlite --parallel=1
Setelah menjalankan cakupan, bangkitkan laporan html dengan menjalankan:
$ coverage html
...\> coverage html
Ketika menjalankan cakupan untuk percobaan Django, pengaturan .coveragerc
yang disertakan menentukan coverage_html
sebagai pelipat keluaran untuk laporan dan juga mengecualikan beberapa pelipat tidak terkait pada hasil (kode percobaan atau kode dikecualikan disertakan di Django).
Aplikasi bantuan¶
Percobaan untuk aplikasi bantuan dapat ditemukan dalam pelipat tests/
, khususnya dibawah <app_name>_tests
. Sebagai contoh, percobaan untuk contrib.auth
ditempatkan dalam tests/auth_tests
.
Menyelesaikan masalah¶
Test suite hangs or shows failures on main
branch¶
Pastikan anda memiliki titik terbitan terakhir dari supported Python version, sejak sering ada kesalahan dalam versi sebelumnya yang mungkin menyebabkan deretan percobaan gagal atau menggantung.
Pada macOS (High Sierra dan versi terbaru), anda mungkin melihat pesan ini tercatat, setelah itu percobaan menggantung:
objc[42074]: +[__NSPlaceholderDate initialize] may have been in progress in
another thread when fork() was called.
Untuk menghindari kumpulan variabel lingkungan OBJC_DISABLE_INITIALIZE_FORK_SAFETY
ini, sebagai contoh:
$ OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ./runtests.py
Atau tambah export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
ke berkas awal shell anda (contoh ~/.profile
).
Banyak percobaan gagal dengan UnicodeEncodeError
¶
Jika paket locales
tidak terpasang, beberapa percobaan akan gagal dengan UnicodeEncodeError
.
Anda dapat menyelesaikan ini pada sistem berdasarkan-Debian, sebagai contoh, dengan menjalankan:
$ apt-get install locales
$ dpkg-reconfigure locales
Anda dapat mengatasi ini untuk sistem macOS dengan mengkonfigurasi lokal shell anda:
$ export LANG="en_US.UTF-8"
$ export LC_ALL="en_US.UTF-8"
Jalankan perintah locale
untuk menegaskan perubahan. Pilihannya, tambah perintah ekpos tersebut pada berkas awalan shell anda (sebagai contoh ~/.bashrc
untuk Bash) untuk menghindari mengetik kembali mereka.
Percobaan hanya gagal di kombinasi¶
Dalam hal sebuah percobaan lulus ketika berjalan di pemisahan tetapi gagal dalam deretan keseluruhan, kami mempunyai beberapa alat untuk membantu menganalisa masalah.
Pilihan --bisect
dari runtests.py
akan menjalankan percobaan kegagalan selama separuh kumpulan percobaan yang dijalankan bersama-sama pada setiap putaran, sering membuatnya memungkinkan untuk mencirikan sejumlah kecil dari percobaan yang mungkin terkait terhadap kegagalan.
Sebagai contoh, misalkan bahwa percobaan gagal yang berkerja pada miliknya sendiri adalah ModelTest.test_eq
, kemudian menggunakan:
$ ./runtests.py --bisect basic.tests.ModelTest.test_eq
...\> runtests.py --bisect basic.tests.ModelTest.test_eq
akan mencoba menentukan percobaan yang mencampuri dengan satu yang diberikan. Pertama, percobaan berjalan dengan babak pertama dari deretan percobaan. Jika kegagalan muncul, babak pertama dari deretan percobaan dipisah dalam dua kelompok dan setiap kelompok berjalan dengan percobaan yang ditentukan. Jika tidak ada kegagalan dengan babak pertama dari deretan percobaan, babak kedua dari deretan percobaan berjalan dengan percobaan yang ditentukan dan dipisah dengan benar seperti digambarkan di awal. Pengolahan berulang sampai kumpulan percobaan kegagalan kecil.
Pilihan --pair
menjalankan percobaan diberikan bersama setiap percobaan lain dari deretan, membiarkan anda memeriksa jika percobaan lain mempunyai pengaruh-samping yang menyebabkan kegagalan. Jadi:
$ ./runtests.py --pair basic.tests.ModelTest.test_eq
...\> runtests.py --pair basic.tests.ModelTest.test_eq
akan memperbaiki test_eq
dengan setiap label percobaan.
Dengan kedua --bisect
dan --pair
, jika anda sudah menduga kasus mana yang mungkin bertanggung jawab terhadap kegagalan, anda mungkin membatasi percobaan pada analisa-silang dengan specifying further test labels setelah yang pertama:
$ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions
...\> runtests.py --pair basic.tests.ModelTest.test_eq queries transactions
Anda dapat juga mencoba menjalankan kumpulan percobaan di kebalikan menggunakan pilihan --reverse
agar mengecek bahwa penjalanan percobaan dalam urutan berbeda tidak menyebabkan masalah apapun:
$ ./runtests.py basic --reverse
...\> runtests.py basic --reverse
Melihat permintaan SQL berjalan selama percobaan¶
Jika anda berharap menguji SQL yang sedang berjalan dalam kegagalan percobaan, anda dapat menyalakan SQL logging menggunakan pilihan --debug-sql
. Jika anda menggabungkan ini dengan --verbosity=2
, semua permintaan SQL akan mengeluarkan:
$ ./runtests.py basic --debug-sql
...\> runtests.py basic --debug-sql
Melihat melacak kembali penuh dari kegagalan percobaan¶
Secara awalan percobaan berjalan paralel dengan satu proses per inti. Ketika percobaan berjalan secara paralel, anda hanya akan melihat potongan melacak belakang untuk kegagalan percobaan apapun. Anda dapat menyesuaikan perilaku ini dengan pilihan --parallel
:
$ ./runtests.py basic --parallel=1
...\> runtests.py basic --parallel=1
You can also use the DJANGO_TEST_PROCESSES
environment variable for
this purpose.
Tip untuk menulis percobaan¶
Mengasingkan pendaftaran model¶
Untuk menghindari registrar apps
global dan mencegah pembuatan tabel tidak diperlukan, model ditentukan dalam cara percobaan harus diikat ke instance Apps
sementara:
from django.apps.registry import Apps
from django.db import models
from django.test import SimpleTestCase
class TestModelDefinition(SimpleTestCase):
def test_model_definition(self):
test_apps = Apps(['app_label'])
class TestModel(models.Model):
class Meta:
apps = test_apps
...
-
django.test.utils.
isolate_apps
(*app_labels, attr_name=None, kwarg_name=None)¶
Sejak corak ini melibatkan banyak boilerplate, Django menyediakan penghias isolate_apps()
. Itu digunakan seperti ini:
from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps
class TestModelDefinition(SimpleTestCase):
@isolate_apps('app_label')
def test_model_definition(self):
class TestModel(models.Model):
pass
...
Mengatur app_label
Model ditentukan dalam cara percobaan dengan tidak eksplisit app_label
secara otomatis diberikan label dari aplikasi dimana kelas percobaan mereka ditempatkan.
Untuk memastikan model ditentukan dalam konteks instance isolate_apps()
dengan benar dipasang, anda harus lolos kumpulan app_label
ditargetkan sebagai argumen:
from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps
class TestModelDefinition(SimpleTestCase):
@isolate_apps('app_label', 'other_app_label')
def test_model_definition(self):
# This model automatically receives app_label='app_label'
class TestModel(models.Model):
pass
class OtherAppModel(models.Model):
class Meta:
app_label = 'other_app_label'
...
Penghias dapat juga diberlakukan ke kelas-kelas:
from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps
@isolate_apps('app_label')
class TestModelDefinition(SimpleTestCase):
def test_model_definition(self):
class TestModel(models.Model):
pass
...
Instance Apps
sementara digunakan untuk mengasingkan pendaftaran model dapat ditarik sebagai sebuah atribut ketika digunakan sebagai kelas penghias dengan menggunakan parameter attr_name
:
from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps
@isolate_apps('app_label', attr_name='apps')
class TestModelDefinition(SimpleTestCase):
def test_model_definition(self):
class TestModel(models.Model):
pass
self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel)
Atau sebagai sebuah argumen pada cara percobaan ketika digunakan sebagai cara penghias dengan menggunakan parameter kwarg_name
:
from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps
class TestModelDefinition(SimpleTestCase):
@isolate_apps('app_label', kwarg_name='apps')
def test_model_definition(self, apps):
class TestModel(models.Model):
pass
self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel)