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.

Next, clone your fork, install some requirements, and run the tests:

$ 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.

Running the tests requires a Django settings module that defines the databases to use. To help you get started, Django provides and uses a sample settings module that uses the SQLite database. See Gunakan modul pengaturan lain to learn how to use a different settings module to run the tests with a different database.

Mempunyai masalah? Lihat Menyelesaikan masalah untuk beberapa masalah umum.

Menjalankan percobaan menggunakan tox

Tox is a tool for running tests in different virtual environments. Django includes a basic tox.ini that automates some checks that our build server performs on pull requests. To run the unit tests and other checks (such as import sorting, the documentation spelling checker, and code formatting), install and run the tox command from any place in the Django source tree:

$ python -m pip install tox
$ tox
...\> py -m pip install tox
...\> tox

By default, tox runs the test suite with the bundled test settings file for SQLite, flake8, isort, and the documentation spelling checker. In addition to the system dependencies noted elsewhere in this documentation, the command python3 must be on your path and linked to the appropriate version of Python. A list of default environments can be seen as follows:

$ tox -l
py3
flake8
docs
isort
...\> tox -l
py3
flake8
docs
isort

Mencoba versi Python lain dan backend basisdata

In addition to the default environments, tox supports running unit tests for other versions of Python and other database backends. Since Django's test suite doesn't bundle a settings file for database backends other than SQLite, however, you must create and provide your own test settings. For example, to run the tests on Python 3.7 using PostgreSQL:

$ tox -e py37-postgres -- --settings=my_postgres_settings
...\> tox -e py37-postgres -- --settings=my_postgres_settings

This command sets up a Python 3.7 virtual environment, installs Django's test suite dependencies (including those for PostgreSQL), and calls runtests.py with the supplied arguments (in this case, --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

Windows users should use:

...\> 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.

Running tests using django-docker-box

django-docker-box allows you to run the Django's test suite across all supported databases and python versions. See the django-docker-box project page for installation and usage instructions.

Gunakan modul pengaturan lain

Modul pengaturan disertakan (tests/test_sqlite.py) mengizinkan anda menjalankan deretan percobaan menggunakan SQLite. Jika anda ingin menjalankan percobaan menggunakan basisdata berbeda, anda akan butuh menentukan berkas pengaturan anda. Beberapa percobaan, seperti itu untuk contrib.postgres, adalah khusus untuk backend basisdata tertentu dan akan dilewati jika berjalan dengan backend berbeda.

Untuk menjalankan percobaan dengan pengaturan berbeda, pastikan bahwa modul berada di PYTHONPATH anda dan lewati modul dengan --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. Basisdata other digunakan untuk mencoba permintaan itu dapat dialihkan ke basisdata berbeda. Basisdata ini harus menggunakan backend sama seperti default, 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 menjalankan CREATE DATABASE sehingga basisdata percobaan dapat dibuat.
  • Pilihan PASSWORD butuh disediakan sandi untuk the USER 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.

For example, if you'd like to run tests only for generic relations and internationalization, type:

$ ./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.

If you want to run only a particular class of tests, you can specify a list of paths to individual test classes. For example, to run the TranslationTests of the i18n module, type:

$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests
...\> runtests.py --settings=path.to.settings i18n.tests.TranslationTests

Going beyond that, you can specify an individual test method like this:

$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects
...\> runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects

You can run tests starting at a specified top-level module with --start-at option. For example:

$ ./runtests.py --start-at=wsgi
...\> runtests.py --start-at=wsgi

You can also run tests starting after a specified top-level module with --start-after option. For example:

$ ./runtests.py --start-after=wsgi
...\> runtests.py --start-after=wsgi

Note that the --reverse option doesn't impact on --start-at or --start-after options. Moreover these options cannot be used with test labels.

Menjalankan percobaan Selenium

Some tests require Selenium and a Web browser. To run these tests, you must install the selenium package and run the tests with the --selenium=<BROWSERS> option. For example, if you have Firefox and Google Chrome installed:

$ ./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.

Some browsers (e.g. Chrome or Firefox) support headless testing, which can be faster and more stable. Add the --headless option to enable this mode.

Menjalankan semua percobaan

Jika anda ingin menjalankan deretan lengkap dari percobaan, anda akan butuh memasang sejumlah ketergantungan:

You can find these dependencies in pip requirements files inside the tests/requirements directory of the Django source tree and install them like so:

$ 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.

To run some of the autoreload tests, you'll need to install the Watchman service.

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.

Coverage should be run in a single process to obtain accurate statistics. To run coverage on the Django test suite using the standard test settings:

$ coverage run ./runtests.py --settings=test_sqlite --parallel=1
...\> coverage run runtests.py --settings=test_sqlite --parallel=1

After running coverage, generate the html report by running:

$ 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 master branch

Ensure you have the latest point release of a supported Python version, since there are often bugs in earlier versions that may cause the test suite to fail or hang.

On macOS (High Sierra and newer versions), you might see this message logged, after which the tests hang:

objc[42074]: +[__NSPlaceholderDate initialize] may have been in progress in
another thread when fork() was called.

To avoid this set a OBJC_DISABLE_INITIALIZE_FORK_SAFETY environment variable, for example:

$ OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ./runtests.py

Or add export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES to your shell's startup file (e.g. ~/.profile).

Banyak percobaan gagal dengan UnicodeEncodeError

Jika paket locales tidak terpasang, beberapa percobaan akan gagal dengan UnicodeEncodeError.

You can resolve this on Debian-based systems, for example, by running:

$ apt-get install locales
$ dpkg-reconfigure locales

You can resolve this for macOS systems by configuring your shell's locale:

$ 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.

For example, suppose that the failing test that works on its own is ModelTest.test_eq, then using:

$ ./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.

The --pair option runs the given test alongside every other test from the suite, letting you check if another test has side-effects that cause the failure. So:

$ ./runtests.py --pair basic.tests.ModelTest.test_eq
...\> runtests.py --pair basic.tests.ModelTest.test_eq

akan memperbaiki test_eq dengan setiap label percobaan.

With both --bisect and --pair, if you already suspect which cases might be responsible for the failure, you may limit tests to be cross-analyzed by specifying further test labels after the first one:

$ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions
...\> runtests.py --pair basic.tests.ModelTest.test_eq queries transactions

You can also try running any set of tests in reverse using the --reverse option in order to verify that executing tests in a different order does not cause any trouble:

$ ./runtests.py basic --reverse
...\> runtests.py basic --reverse

Melihat permintaan SQL berjalan selama percobaan

If you wish to examine the SQL being run in failing tests, you can turn on SQL logging using the --debug-sql option. If you combine this with --verbosity=2, all SQL queries will be output:

$ ./runtests.py basic --debug-sql
...\> runtests.py basic --debug-sql

Melihat melacak kembali penuh dari kegagalan percobaan

By default tests are run in parallel with one process per core. When the tests are run in parallel, however, you'll only see a truncated traceback for any test failures. You can adjust this behavior with the --parallel option:

$ ./runtests.py basic --parallel=1
...\> runtests.py basic --parallel=1

Anda dapat juga menggunakan variabel lingkungan DJANGO_TEST_PROCESSES untuk tujuan ini.

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:

tests/app_label/tests.py
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)
Back to Top