# Django 6.0.5 documentation

# Skriva och köra tester

Se även

testhandledning, referens för testverktyg och avancerade testämnen.

Detta dokument är uppdelat i två huvudavsnitt. Först förklarar vi hur man skriver tester med Django. Sedan förklarar vi hur man kör dem.

## Skriva tester

Djangos enhetstester använder en modul från Pythons standardbibliotek: `unittest`. Denna modul definierar tester med hjälp av ett klassbaserat tillvägagångssätt.

Här är ett exempel som underklassar från `django.test.TestCase`, som är en underklass av `unittest.TestCase` som kör varje test inuti en transaktion för att ge isolering:

    from django.test import TestCase
    from myapp.models import Animal

    class AnimalTestCase(TestCase):
        def setUp(self):
            Animal.objects.create(name="lion", sound="roar")
            Animal.objects.create(name="cat", sound="meow")

        def test_animals_can_speak(self):
            """Animals that can speak are correctly identified"""
            lion = Animal.objects.get(name="lion")
            cat = Animal.objects.get(name="cat")
            self.assertEqual(lion.speak(), 'The lion says "roar"')
            self.assertEqual(cat.speak(), 'The cat says "meow"')

När du kör dina tester, är standardbeteendet för testverktyget att hitta alla testfallsklasser (det vill säga underklasser till `unittest.TestCase`) i alla filer vars namn börjar med `test`, automatiskt bygga en testsvit av dessa testfallsklasser och köra sviten.

För mer information om `unittest`, se Python-dokumentationen.

Var ska testerna genomföras?

Standardmallen `startapp` skapar en fil med namnet `tests.py` i den nya applikationen. Detta kan vara bra om du bara har ett fåtal tester, men när din testsvit växer kommer du sannolikt att vilja omstrukturera den till ett testpaket så att du kan dela upp dina tester i olika undermoduler som `test_models.py`, `test_views.py`, `test_forms.py`, etc. Känn dig fri att välja vilket organisationsschema du vill.

Se även testning av återanvändbara applikationer.

Varning

Om dina tester förlitar sig på databasåtkomst, till exempel för att skapa eller fråga modeller, se till att skapa dina testklasser som underklasser till `django.test.TestCase` snarare än `unittest.TestCase`.

Genom att använda `unittest.TestCase` slipper du kostnaden för att köra varje test i en transaktion och rensa databasen, men om dina tester interagerar med databasen kommer deras beteende att variera beroende på i vilken ordning testlöparen kör dem. Detta kan leda till enhetstester som godkänns när de körs isolerat men som misslyckas när de körs i en svit.

## Genomföra tester

När du har skrivit tester kan du köra dem med kommandot `test` i verktyget `manage.py` i ditt projekt:

    $ ./manage.py test

Test discovery is based on the unittest module’s built-in test discovery. By default, this will discover tests in any file named `test*.py` under the current working directory.

Du kan ange särskilda tester som ska köras genom att ange ett valfritt antal ”testetiketter” till `./manage.py test`. Varje testetikett kan vara en fullständig Python-punktad sökväg till ett paket, en modul, en `TestCase`-underklass eller en testmetod. Till exempel:

    # Run all the tests in the animals.tests module
    $ ./manage.py test animals.tests

    # Run all the tests found within the 'animals' package
    $ ./manage.py test animals

    # Run just one test case class
    $ ./manage.py test animals.tests.AnimalTestCase

    # Run just one test method
    $ ./manage.py test animals.tests.AnimalTestCase.test_animals_can_speak

Du kan också ange en sökväg till en katalog för att hitta tester under den katalogen:

    $ ./manage.py test animals/

Du kan ange ett anpassat filnamnsmönster med hjälp av alternativet `-p` (eller `--pattern`) om dina testfiler har andra namn än `test*.py`:

    $ ./manage.py test --pattern="tests_*.py"

Om du trycker på `Ctrl-C` medan testerna körs, väntar testköraren på att det aktuella testet ska slutföras och avslutas sedan på ett elegant sätt. Under en elegant avslutning kommer testköraren att ge ut information om eventuella testfel, rapportera hur många tester som kördes och hur många fel och misslyckanden som uppstod, samt förstöra alla testdatabaser som vanligt. Att trycka på `Ctrl-C` kan alltså vara mycket användbart om du glömmer att ange alternativet `--failfast`, märker att vissa tester oväntat misslyckas och vill få information om misslyckandena utan att vänta på att hela testkörningen ska slutföras.

Om du inte vill vänta på att det aktuella testet ska avslutas kan du trycka på `Ctrl-C` en gång till så avbryts testkörningen omedelbart, men inte på ett elegant sätt. Inga detaljer om de tester som kördes före avbrottet kommer att rapporteras, och inga testdatabaser som skapats av körningen kommer att förstöras.

Test med varningar aktiverade

Det är en bra idé att köra dina tester med Python-varningar aktiverade: `python -Wa manage.py test`. Flaggan `-Wa` säger till Python att visa varningar för utfasning. Django, liksom många andra Python-bibliotek, använder dessa varningar för att flagga när funktioner försvinner. Det kan också flagga områden i din kod som inte är helt fel men som kan dra nytta av en bättre implementering.

### Testdatabasen

Tester som kräver en databas (dvs. modelltester) använder inte din ”riktiga” (produktions-) databas. Separata, tomma databaser skapas för testerna.

Oavsett om testerna godkänns eller inte, förstörs testdatabaserna när alla tester har utförts.

Du kan förhindra att testdatabaserna förstörs genom att använda alternativet `test --keepdb`. Detta kommer att bevara testdatabasen mellan körningarna. Om databasen inte finns kommer den först att skapas. Eventuella migreringar kommer också att tillämpas för att hålla den uppdaterad.

Som beskrivs i föregående avsnitt får testdatabasen inte förstöras om en testkörning avbryts med våld. Vid nästa körning kommer du att få frågan om du vill återanvända eller förstöra databasen. Använd alternativet `test --noinput` för att undertrycka den frågan och automatiskt förstöra databasen. Detta kan vara användbart när du kör tester på en server för kontinuerlig integration där testerna kan avbrytas av en timeout, till exempel.

Standardnamnen på testdatabaserna skapas genom att lägga till `test_` till värdet för varje `NAME` i `DATABASES`. När SQLite används kommer testerna att använda en databas i minnet som standard (dvs. databasen skapas i minnet och kringgår filsystemet helt!) Ordlistan `TEST` i `DATABASER` erbjuder ett antal inställningar för att konfigurera din testdatabas. Om du till exempel vill använda ett annat databasnamn anger du `NAME` i ordlistan `TEST` för en viss databas i `DATABASES`.

På PostgreSQL behöver `USER` också läsbehörighet till den inbyggda databasen `postgres`.

Förutom att använda en separat databas kommer testköraren att använda samma inställningar för databasen som du har i din inställningsfil: `ENGINE`, `USER`, `HOST`, etc. Testdatabasen skapas av den användare som anges av `USER`, så du måste se till att det angivna användarkontot har tillräckliga privilegier för att skapa en ny databas i systemet.

För finkornig kontroll över teckenkodningen i din testdatabas använder du alternativet `CHARSET` TEST. Om du använder MySQL kan du också använda alternativet `COLLATION` för att styra den specifika kollationering som används av testdatabasen. Se settings-dokumentationen för mer information om dessa och andra avancerade inställningar.

Om du använder en SQLite-databas i minnet med SQLite är shared cache aktiverat, så att du kan skriva tester med möjlighet att dela databasen mellan trådar.

Hittar du data från din produktionsdatabas när du kör tester?

Om din kod försöker komma åt databasen när modulerna kompileras kommer detta att ske innan testdatabasen har skapats, vilket kan ge oväntade resultat. Om du till exempel har en databasfråga i kod på modulnivå och det finns en riktig databas, kan produktionsdata förorena dina tester. Det är ändå en dålig idé att ha sådana databasfrågor för importtid i din kod - skriv om din kod så att den inte gör detta.

This also applies to customized implementations of `ready()`.

Se även

The avancerade ämnen för testning av flera databaser.

### Ordning i vilken testerna utförs

För att garantera att all `TestCase`-kod startar med en ren databas, ordnar Django test runner om testerna på följande sätt:

- Alla `TestCase` underklasser körs först.

- Därefter körs alla andra Django-baserade tester (testfallsklasser baserade på `SimpleTestCase`, inklusive `TransactionTestCase`) utan att någon särskild ordning garanteras eller upprätthålls mellan dem.

- Sedan körs alla andra `unittest.TestCase`-tester (inklusive doctests) som kan ändra databasen utan att återställa den till dess ursprungliga tillstånd.

Observera

Den nya ordningsföljden för tester kan avslöja oväntade beroenden av testfallets ordningsföljd. Detta är fallet med doctests som förlitade sig på tillstånd som lämnats i databasen av ett visst `TransactionTestCase`-test, de måste uppdateras för att kunna köras oberoende.

Observera

Fel som upptäcks vid laddning av tester ordnas före alla ovanstående för snabbare återkoppling. Detta inkluderar saker som testmoduler som inte kunde hittas eller som inte kunde laddas på grund av syntaxfel.

Du kan randomisera och/eller vända exekveringsordningen inom grupper med hjälp av alternativen `test --shuffle` och `--reverse`. Detta kan hjälpa till att säkerställa att dina tester är oberoende av varandra.

### Rollback-emulering

Alla initiala data som laddas i migreringar kommer endast att vara tillgängliga i `TestCase`-tester och inte i `TransactionTestCase`-tester, och dessutom endast på backends där transaktioner stöds (det viktigaste undantaget är MyISAM). Detta gäller även för tester som förlitar sig på `TransactionTestCase` som `LiveServerTestCase` och `StaticLiveServerTestCase`.

Django kan ladda om dessa data åt dig per testfall genom att ställa in alternativet `serialized_rollback` till `True` i kroppen av `TestCase` eller `TransactionTestCase`, men observera att detta kommer att sakta ner testsviten med ungefär 3x.

Tredjepartsappar eller de som utvecklas mot MyISAM måste ställa in detta; i allmänhet bör du dock utveckla dina egna projekt mot en transaktionsdatabas och använda `TestCase` för de flesta tester, och därmed inte behöva denna inställning.

Den första serialiseringen går vanligtvis mycket snabbt, men om du vill utesluta vissa appar från denna process (och snabba upp testkörningarna något) kan du lägga till dessa appar i `TEST_NON_SERIALIZED_APPS`.

För att förhindra att serialiserade data laddas två gånger, inaktiverar inställningen `serialized_rollback=True` `post_migrate`-signalen när testdatabasen rensas.

Changed in Django 5.2:

För `TransactionTestCase` görs serialiserade migreringsdata tillgängliga under `setUpClass()`.

### Andra testförhållanden

Oavsett värdet på inställningen `DEBUG` i din konfigurationsfil körs alla Django-tester med :setting:`DEBUG`=False. Detta är för att säkerställa att den observerade utmatningen av din kod matchar vad som kommer att ses i en produktionsinställning.

Cacher rensas inte efter varje test, och om du kör `manage.py test fooapp` kan data från testerna infogas i cacheminnet i ett live-system om du kör dina tester i produktion eftersom, till skillnad från databaser, en separat ”testcache” inte används. Detta beteende kan komma att ändras i framtiden.

### Förstå testutdata

När du kör dina tester kommer du att se ett antal meddelanden när testköraren förbereder sig. Du kan styra detaljnivån i dessa meddelanden med alternativet `verbosity` på kommandoraden:

    Creating test database...
    Creating table myapp_animal
    Creating table myapp_mineral

Detta visar att testköraren skapar en testdatabas, enligt beskrivningen i föregående avsnitt.

När testdatabasen har skapats kommer Django att köra dina tester. Om allt går bra kommer du att se något liknande detta:

    ----------------------------------------------------------------------
    Ran 22 tests in 0.221s

    OK

Om testerna misslyckas kommer du dock att se fullständig information om vilka tester som misslyckades:

    ======================================================================
    FAIL: test_was_published_recently_with_future_poll (polls.tests.PollMethodTests)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/dev/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_poll
        self.assertIs(future_poll.was_published_recently(), False)
    AssertionError: True is not False

    ----------------------------------------------------------------------
    Ran 1 test in 0.003s

    FAILED (failures=1)

En fullständig förklaring av denna felutmatning ligger utanför ramen för detta dokument, men den är ganska intuitiv. Du kan läsa dokumentationen för Pythons `unittest`-bibliotek för mer information.

Observera att returkoden för testrunner-skriptet är 1 för varje antal misslyckade tester (oavsett om misslyckandet orsakades av ett fel, ett misslyckat påstående eller en oväntad framgång). Om alla tester godkänns är returkoden 0. Den här funktionen är användbar om du använder testrunner-skriptet i ett shell-skript och behöver testa om det lyckas eller misslyckas på den nivån.

### Snabbare tester

#### Kör tester parallellt

Så länge dina tester är ordentligt isolerade kan du köra dem parallellt för att få högre hastighet på flerkärnig maskinvara. Se `test --parallel`.

#### Hashing av lösenord

Standardalgoritmen för lösenordshashning är ganska långsam av designskäl. Om du autentiserar många användare i dina tester kanske du vill använda en anpassad inställningsfil och ställa in `PASSWORD_HASHERS` till en snabbare hash-algoritm:

    PASSWORD_HASHERS = [
        "django.contrib.auth.hashers.MD5PasswordHasher",
    ]

Glöm inte att i `PASSWORD_HASHERS` även ange den hash-algoritm som används i fixturerna, om någon.

#### Bevara testdatabasen

Alternativet `test --keepdb` bevarar testdatabasen mellan testkörningar. Det hoppar över åtgärderna för att skapa och förstöra, vilket kan minska tiden för att köra tester avsevärt.

#### Undvika diskåtkomst för mediefiler

Klassen:~django.core.files.storage.InMemoryStorage är ett bekvämt sätt att förhindra diskåtkomst för mediefiler. All data sparas i minnet och kasseras sedan efter testkörningen.