# Django 6.0.7 documentation

# Enhetstester

Django levereras med en egen testsvit i katalogen `tests` i kodbasen. Det är vår policy att se till att alla tester godkänns hela tiden.

Vi uppskattar alla bidrag till testsviten!

Django-testerna använder alla den testinfrastruktur som levereras med Django för att testa applikationer. Se Skriva och köra tester för en förklaring av hur man skriver nya tester.

## Kör enhetstesterna

### Snabbstart

Först, fork Django på GitHub.

För det andra, skapa och aktivera en virtuell miljö. Om du inte är bekant med hur du gör det, läs vår Bidragshandledning.

Därefter klonar du din fork, installerar några krav och kör testerna:

/ 

    $ 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

För att installera kraven krävs troligen några operativsystemspaket som inte finns installerade på din dator. Du kan vanligtvis ta reda på vilket paket som ska installeras genom att göra en webbsökning efter den sista raden eller så i felmeddelandet. Försök att lägga till ditt operativsystem i sökfrågan om det behövs.

If you have trouble installing an optional test dependency, you can skip that dependency locally. For example, if installing `pylibmc` fails, comment out its line in `requirements/py3.txt` and continue with `./runtests.py`. Tests that require `pylibmc` will be skipped automatically. See Kör alla tester for details on installing the optional test dependencies.

För att köra testerna krävs en inställningsmodul för Django som definierar vilka databaser som ska användas. För att hjälpa dig att komma igång tillhandahåller och använder Django en exempelinställningsmodul som använder SQLite-databasen. Se Använda en annan settings-modul för att lära dig hur du använder en annan inställningsmodul för att köra testerna med en annan databas.

Har du problem? Se Felsökning för några vanliga problem.

### Kör tester med hjälp av `tox`

Tox är ett verktyg för att köra tester i olika virtuella miljöer. Django innehåller en grundläggande `tox.ini` som automatiserar vissa kontroller som vår byggserver utför på pull-förfrågningar. För att köra enhetstesterna och andra kontroller (som import sorting, documentation spelling checker, och code formatting), installera och kör kommandot `tox` från vilken plats som helst i Djangos källträd:

/ 

    $ 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, `black`, `blacken-docs`, `flake8`, `isort`, `lint-docs`, `zizmor`, 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
    black
    blacken-docs
    flake8>=3.7.0
    docs
    isort>=7.0.0
    lint-docs
    zizmor>=1.19.0

    ...\> tox -l
    py3
    black
    blacken-docs
    flake8>=3.7.0
    docs
    isort>=7.0.0
    lint-docs
    zizmor>=1.19.0

#### Testning av andra Python-versioner och databasbackends

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.12 using PostgreSQL:

/ 

    $ tox -e py312-postgres -- --settings=my_postgres_settings

    ...\> tox -e py312-postgres -- --settings=my_postgres_settings

This command sets up a Python 3.12 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`).

I resten av denna dokumentation visas kommandon för att köra tester utan `tox`, men alla alternativ som skickas till `runtests.py` kan också skickas till `tox` genom att prefixera argumentlistan med `--`, enligt ovan.

`Tox` respekterar även miljövariabeln `DJANGO_SETTINGS_MODULE`, om den är inställd. Följande är till exempel likvärdigt med kommandot ovan:

    $ DJANGO_SETTINGS_MODULE=my_postgres_settings tox -e py312-postgres

Windows-användare bör använda:

    ...\> set DJANGO_SETTINGS_MODULE=my_postgres_settings
    ...\> tox -e py312-postgres

#### Körning av JavaScript-testerna

Django innehåller en uppsättning JavaScript-enhetstester för funktioner i vissa Contrib-appar. JavaScript-testerna körs inte som standard med `tox` eftersom de kräver att `Node.js` installeras och inte är nödvändiga för de flesta korrigeringar. För att köra JavaScript-testerna med hjälp av `tox`:

/ 

    $ tox -e javascript

    ...\> tox -e javascript

Detta kommando kör `npm install` för att säkerställa att testkraven är uppdaterade och kör sedan `npm test`.

### Kör tester med hjälp av `django-docker-box`

med django-docker-box kan du köra Djangos testsvit över alla databaser och pythonversioner som stöds. Se projektsidan django-docker-box för installations- och användningsinstruktioner.

### Använda en annan `settings`-modul

Den medföljande inställningsmodulen (`tests/test_sqlite.py`) gör att du kan köra testsviten med SQLite. Om du vill köra testerna med en annan databas måste du definiera din egen inställningsfil. Vissa tester, t.ex. de för `contrib.postgres`, är specifika för en viss databasbackend och kommer att hoppas över om de körs med en annan backend. Vissa tester hoppas över eller förväntade misslyckanden på en viss databas backend (se `DatabaseFeatures.django_test_skips` och `DatabaseFeatures.django_test_expected_failures` på varje backend).

Om du vill köra testerna med olika inställningar måste du se till att modulen finns på din `PYTHONPATH` och skicka modulen med `--settings`.

Inställningen `DATABASES` i en modul för testinställningar måste definiera två databaser:

- En `standard` databas. Denna databas bör använda den backend som du vill använda för primär testning.

- En databas med aliaset `other`. Databasen `other` används för att testa att frågor kan riktas till olika databaser. Den här databasen bör använda samma backend som `default` och den måste ha ett annat namn.

Om du använder en backend som inte är SQLite måste du ange andra uppgifter för varje databas:

- Alternativet `USER` måste ange ett befintligt användarkonto för databasen. Den användaren behöver behörighet att köra `CREATE DATABASE` så att testdatabasen kan skapas.

- Alternativet `PASSWORD` måste innehålla lösenordet för den `USER` som har angetts.

Testdatabaser får sina namn genom att lägga till `test_` till värdet i inställningarna `NAME` för de databaser som definieras i `DATABASES`. Dessa testdatabaser raderas när testerna är avslutade.

Du måste också se till att din databas använder UTF-8 som standardteckensats. Om din databasserver inte använder UTF-8 som standardteckensats måste du lägga till ett värde för `CHARSET` i testinställningsordlistan för den aktuella databasen.

### Kör bara några av testerna

Djangos hela testsvit tar en stund att köra, och att köra varje enskilt test kan vara överflödigt om du till exempel just har lagt till ett test i Django som du vill köra snabbt utan att köra allt annat. Du kan köra en delmängd av enhetstesterna genom att lägga till namnen på testmodulerna till `runtests.py` på kommandoraden.

Om du t.ex. bara vill köra tester för generiska relationer och internationalisering, skriv:

/ 

    $ ./runtests.py --settings=path.to.settings generic_relations i18n

    ...\> runtests.py --settings=path.to.settings generic_relations i18n

Hur får du reda på namnen på enskilda tester? Titta i `tests/` - varje katalognamn där är namnet på ett test.

Om du bara vill köra en viss klass av tester kan du ange en lista med sökvägar till enskilda testklasser. Om du t.ex. vill köra `TranslationTests` för modulen `i18n` skriver du :

/ 

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

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

Utöver detta kan du ange en enskild testmetod på följande sätt:

/ 

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

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

Du kan köra tester som startar vid en angiven modul på högsta nivån med alternativet `--start-at`. Till exempel

/ 

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

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

Du kan också köra tester som startar efter en angiven modul på högsta nivån med alternativet `--start-after`. Till exempel:

/ 

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

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

Observera att alternativet `--reverse` inte har någon inverkan på alternativen `--start-at` eller `--start-after`. Dessutom kan dessa alternativ inte användas med testetiketter.

### Kör Selenium-testerna

Vissa tester kräver Selenium och en webbläsare. För att köra dessa tester måste du installera paketet selenium och köra testerna med alternativet `--selenium=<BROWSERS>`. Till exempel om du har Firefox och Google Chrome installerade:

/ 

    $ ./runtests.py --selenium=firefox,chrome

    ...\> runtests.py --selenium=firefox,chrome

Se paketet selenium.webdriver för en lista över tillgängliga webbläsare.

Om du anger `--selenium` ställs `--tags=selenium` automatiskt in så att endast de tester som kräver selenium körs.

Vissa webbläsare (t.ex. Chrome eller Firefox) stöder headless-testning, som kan vara snabbare och stabilare. Lägg till alternativet `--headless` för att aktivera detta läge.

#### Skärmdump tester

För att testa ändringar i administratörsgränssnittet kan seleniumtesterna köras med alternativet `--screenshots` aktiverat. Skärmdumpar kommer att sparas i katalogen `tests/screenshots/`.

För att definiera när skärmdumpar ska tas under ett seleniumtest måste testklassen använda dekoratorn `@django.test.selenium.screenshot_cases` med en lista över skärmdumpstyper som stöds (`"desktop_size"`, `"mobile_size"`, `"small_screen_size"`, `"rtl"`, `"dark"` och `"high_contrast"`). Den kan sedan anropa `self.take_screenshot("unique-screenshot-name")` vid önskad punkt för att generera skärmdumparna. Till exempel:

    from django.test.selenium import SeleniumTestCase, screenshot_cases
    from django.urls import reverse

    class SeleniumTests(SeleniumTestCase):
        @screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
        def test_login_button_centered(self):
            self.selenium.get(self.live_server_url + reverse("admin:login"))
            self.take_screenshot("login")
            ...

Detta genererar flera skärmdumpar av inloggningssidan - en för en datorskärm, en för en mobilskärm, en för höger till vänster-språk på datorn, en för mörkt läge på datorn och en för högkontrastläge på datorn när du använder Chrome.

### Kör alla tester

Om du vill köra hela testsviten måste du installera ett antal beroenden:

- aiosmtpd 1.4.5+

- argon2-cffi 23.1.0+

- asgiref 3.9.1+ (required)

- bcrypt 4.1.1+

- colorama 0.4.6+

- docutils 0.22+

- geoip2 4.8.0+

- Jinja2 2.11+

- numpy 1.26.0+

- Pillow 10.1.0+

- PyYAML 6.0.2+

- pywatchman

- redis 5.1.0+

- pymemcache, plus en stödd Python-bindning

- gettext (gettext på Windows)

- selenium 4.23.0+

- sqlparse 0.5.0+ (required)

- tblib 3.0.0+

Du kan hitta dessa beroenden i pip requirements files i katalogen `tests/requirements` i Djangos källträd och installera dem på följande sätt:

/ 

    $ python -m pip install -r tests/requirements/py3.txt

    ...\> py -m pip install -r tests\requirements\py3.txt

Om du stöter på ett fel under installationen kan det hända att ditt system saknar ett beroende för ett eller flera av Python-paketen. Läs dokumentationen för det paket som inte fungerar eller sök på webben efter det felmeddelande som du stöter på.

Du kan också installera valfri(a) databasadapter(s) med hjälp av `oracle.txt`, `mysql.txt` eller `postgres.txt`.

Om du vill testa backends för memcached eller Redis cache måste du också definiera en `CACHES`-inställning som pekar på din memcached- respektive Redis-instans.

För att köra GeoDjango-testerna måste du konfigurera en spatial databas och installera Geospatial-biblioteken.

Var och en av dessa beroenden är valfria. Om du saknar något av dem kommer de tillhörande testerna att hoppas över.

För att köra några av de automatiska laddningstesterna måste du installera tjänsten Watchman.

### Kodtäckning

Bidragsgivare uppmuntras att köra täckning på testsviten för att identifiera områden som behöver ytterligare tester. Installation och användning av täckningsverktyget beskrivs i testning code coverage.

För att köra täckning på Djangos testsvit med standardtestinställningarna:

/ 

    $ coverage run ./runtests.py --settings=test_sqlite

    ...\> coverage run runtests.py --settings=test_sqlite

Efter att ha kört täckning, kombinera all täckningsstatistik genom att köra:

/ 

    $ coverage combine

    ...\> coverage combine

Efter det genererar du html-rapporten genom att köra:

/ 

    $ coverage html

    ...\> coverage html

När du kör täckning för Django-testerna definierar den medföljande inställningsfilen `.coveragerc` `coverage_html` som utdatakatalog för rapporten och utesluter även flera kataloger som inte är relevanta för resultaten (testkod eller extern kod som ingår i Django).

### Code coverage on pull requests

Django’s continuous integration (CI) system automatically runs code coverage analysis on pull requests and posts a comment with a diff coverage report. This helps reviewers see which lines in the changed code are covered by tests.

What the coverage report shows:

The coverage report posted on pull requests uses diff-cover to analyze only the lines that were changed or added in the PR. It shows:

- Lines that are covered by tests (✓)

- Lines that are not covered by tests (✗)

- Lines that cannot be covered (e.g., comments, blank lines)

Important limitations:

When reviewing coverage reports on pull requests, keep these limitations in mind:

- Database-specific code: The CI coverage job runs tests using PostgreSQL on Ubuntu. Code paths specific to other databases (SQLite, MySQL, Oracle) will appear as ”not covered” even if database-specific tests exist. This is expected and acceptable.

- Platform-specific code: Similarly, code that only runs on certain operating systems (Windows, macOS) will appear as not covered when run on Ubuntu.

- Coverage doesn’t equal quality: A line being ”covered” only means it was executed during tests. It doesn’t guarantee the line is well-tested or that all edge cases are handled. During review, assess test quality beyond just coverage numbers.

Missing coverage should be considered a warning rather than a blocker and should be evaluated in context.

## Bidragande appar

Tester för Contrib-appar finns i katalogen tests/, vanligtvis under `<app_name>_tests`. Till exempel finns tester för `contrib.auth` i tests/auth_tests.

## Felsökning

### Testsviten hänger sig eller visar fel på `main`-grenen

Se till att du har den senaste punktversionen av en stödd Python-version, eftersom det ofta finns buggar i tidigare versioner som kan leda till att testsviten misslyckas eller hänger sig.

På macOS (High Sierra och nyare versioner) kan du se detta meddelande loggat, varefter testerna hänger sig:

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

För att undvika detta kan du t.ex. ange miljövariabeln `OBJC_DISABLE_INITIALIZE_FORK_SAFETY`:

    $ OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ./runtests.py

Eller lägg till `export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES` i startfilen för ditt skal (t.ex. `~/.profile`).

### Många misslyckade tester med `UnicodeEncodeError`

Om paketet `locales` inte är installerat kommer vissa tester att misslyckas med `UnicodeEncodeError`.

Du kan lösa detta på Debian-baserade system genom att t.ex. köra:

    $ apt-get install locales
    $ dpkg-reconfigure locales

Du kan lösa detta för macOS-system genom att konfigurera ditt shells locale:

    $ export LANG="en_US.UTF-8"
    $ export LC_ALL="en_US.UTF-8"

Kör kommandot `locale` för att bekräfta ändringen. Lägg eventuellt till dessa exportkommandon i startfilen för ditt skal (t.ex. `~/.bashrc` för Bash) så att du slipper skriva in dem igen.

### Tester som bara misslyckas i kombination

Om ett test godkänns när det körs isolerat men misslyckas i hela sviten har vi några verktyg som hjälper till att analysera problemet.

Alternativet `--bisect` i `runtests.py` kör det misslyckade testet samtidigt som testuppsättningen som det körs tillsammans med halveras vid varje iteration, vilket ofta gör det möjligt att identifiera ett litet antal tester som kan vara relaterade till felet.

Anta till exempel att det misslyckade testet som fungerar på egen hand är `ModelTest.test_eq`, då använder du:

/ 

    $ ./runtests.py --bisect basic.tests.ModelTest.test_eq

    ...\> runtests.py --bisect basic.tests.ModelTest.test_eq

kommer att försöka hitta ett test som stör det givna testet. Först körs testet med den första halvan av testsviten. Om ett fel uppstår delas den första halvan av testsviten upp i två grupper och varje grupp körs sedan med det angivna testet. Om det inte uppstår något fel med den första halvan av testsviten körs den andra halvan av testsviten med det angivna testet och delas upp på lämpligt sätt enligt beskrivningen ovan. Processen upprepas tills antalet misslyckade tester har minimerats.

Alternativet `--pair` kör det givna testet tillsammans med alla andra tester från sviten, så att du kan kontrollera om ett annat test har bieffekter som orsakar felet. Så här gör du:

/ 

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

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

kommer att para ihop `test_eq` med varje testetikett.

Med både `--bisect` och `--pair`, om du redan misstänker vilka fall som kan vara ansvariga för felet, kan du begränsa tester som ska korsanalyseras genom att specificera ytterligare testetiketter efter den första:

/ 

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

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

Du kan också prova att köra en uppsättning tester i slumpmässig eller omvänd ordning med hjälp av alternativen `--shuffle` och `--reverse`. Detta kan hjälpa till att verifiera att körning av tester i en annan ordning inte orsakar några problem:

/ 

    $ ./runtests.py basic --shuffle
    $ ./runtests.py basic --reverse

    ...\> runtests.py basic --shuffle
    ...\> runtests.py basic --reverse

### Se de SQL-frågor som körs under ett test

Om du vill undersöka den SQL som körs i misslyckade tester kan du aktivera SQL logging med alternativet `--debug-sql`. Om du kombinerar detta med `--verbosity=2` kommer alla SQL-frågor att skrivas ut:

/ 

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

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

### Se den fullständiga spårningen av ett testfel

Som standard körs testerna parallellt med en process per kärna. När testerna körs parallellt kommer du dock bara att se en avkortad spårning för eventuella testfel. Du kan justera detta beteende med alternativet `--parallel`:

/ 

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

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

Du kan också använda miljövariabeln `DJANGO_TEST_PROCESSES` för detta ändamål.

## Tips för att skriva tester

### Isolering av modellregistrering

För att undvika att förorena det globala `apps`-registret och förhindra onödigt skapande av tabeller, bör modeller som definieras i en testmetod vara bundna till en tillfällig `Apps`-instans. För att göra detta, använd `isolate_apps()` dekoratorn:

    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

            ...

Inställning av `app_label`

Modeller som definieras i en testmetod utan någon explicit `app_label` tilldelas automatiskt etiketten för den app där deras testklass finns.

För att säkerställa att de modeller som definieras inom ramen för `isolate_apps()`-instanser är korrekt installerade, bör du skicka uppsättningen av riktade `app_label` som argument:

`tester/app_label/tester.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"

            ...