# Django 5.2.8 documentation

# Testverktyg

Django tillhandahåller en liten uppsättning verktyg som är användbara när du skriver tester.

## Testklienten

Testklienten är en Python-klass som fungerar som en dummy-webbläsare, så att du kan testa dina vyer och interagera med din Django-drivna applikation programmatiskt.

Några av de saker du kan göra med testklienten är följande:

- Simulera GET- och POST-begäranden på en URL och observera svaret - allt från HTTP på låg nivå (resultathuvuden och statuskoder) till sidinnehåll.

- Se kedjan av omdirigeringar (om det finns några) och kontrollera webbadressen och statuskoden i varje steg.

- Testa att en given begäran återges av en given Django-mall, med en mallkontext som innehåller vissa värden.

Observera att testklienten inte är avsedd att ersätta Selenium eller andra ramverk ”i webbläsaren”. Djangos testklient har ett annat fokus. Kort och gott:

- Använd Djangos testklient för att fastställa att rätt mall återges och att mallen får rätt kontextdata.

- Använd `RequestFactory` för att testa vyfunktioner direkt, förbi routing- och middleware-lagren.

- Använd ramverk i webbläsaren som Selenium för att testa renderad HTML och beteendet på webbsidor, nämligen JavaScript-funktionalitet. Django ger också särskilt stöd för dessa ramverk; se avsnittet om `LiveServerTestCase` för mer information.

En omfattande testsvit bör använda en kombination av alla dessa testtyper.

### Översikt och ett snabbt exempel

För att använda testklienten, instansiera `django.test.Client` och hämta webbsidor:

    >>> from django.test import Client
    >>> c = Client()
    >>> response = c.post("/login/", {"username": "john", "password": "smith"})
    >>> response.status_code
    200
    >>> response = c.get("/customer/details/")
    >>> response.content
    b'<!DOCTYPE html...'

Som exemplet visar kan du instansiera `Client` från en session i den interaktiva Python-tolken.

Notera några viktiga saker om hur testklienten fungerar:

- Testklienten kräver inte att webbservern är igång. Faktum är att det går alldeles utmärkt utan att någon webbserver körs alls! Det beror på att den undviker HTTP:s overhead och hanterar Django-ramverket direkt. Detta hjälper till att få enhetstesterna att köras snabbt.

- När du hämtar sidor ska du komma ihåg att ange sökvägen i URL:en, inte hela domänen. Detta är till exempel korrekt:

      >>> c.get("/login/")

  Detta är felaktigt:

      >>> c.get("https://www.example.com/login/")

  Testklienten kan inte hämta webbsidor som inte drivs av ditt Django-projekt. Om du behöver hämta andra webbsidor kan du använda en modul från Pythons standardbibliotek, t.ex. `urllib`.

- För att lösa URL:er använder testklienten den URLconf som pekas ut av din inställning `ROOT_URLCONF`.

- Även om ovanstående exempel skulle fungera i Pythons interaktiva tolk, är en del av testklientens funktionalitet, särskilt den mallrelaterade funktionaliteten, endast tillgänglig när tester körs.

  Anledningen till detta är att Djangos testlöpare utför lite svart magi för att avgöra vilken mall som laddades av en viss vy. Denna svarta magi (i huvudsak en patchning av Djangos mallsystem i minnet) sker endast under testkörning.

- Som standard kommer testklienten att inaktivera alla CSRF-kontroller som utförs av din webbplats.

  Om du av någon anledning vill att testklienten ska utföra CSRF-kontroller kan du skapa en instans av testklienten som tvingar fram CSRF-kontroller. För att göra detta, skicka in argumentet `enforce_csrf_checks` när du konstruerar din klient:

      >>> from django.test import Client
      >>> csrf_client = Client(enforce_csrf_checks=True)

### Att göra förfrågningar

Använd klassen `django.test.Client` för att göra förfrågningar.

class Client(enforce_csrf_checks=False, raise_request_exception=True, json_encoder=DjangoJSONEncoder, *, headers=None, query_params=None, **defaults)

  En testande HTTP-klient. Tar emot flera argument som kan anpassa beteendet.

  med `headers` kan du ange standardrubriker som ska skickas med varje begäran. Till exempel, för att ställa in en `User-Agent` header:

      client = Client(headers={"user-agent": "curl/7.79.1"})

  med `query_params` kan du ange standardfrågesträngen som kommer att ställas in vid varje förfrågan.

  Godtyckliga nyckelordsargument i `**defaults` ställer in WSGI environ-variabler. Till exempel, för att ställa in skriptnamnet:

      client = Client(SCRIPT_NAME="/app/")

  Observera

  Nyckelordsargument som börjar med prefixet `HTTP_` anges som rubriker, men parametern `headers` bör föredras för läsbarhetens skull.

  The values from the `headers`, `query_params`, and `extra` keyword arguments passed to `get()`, `post()`, etc. have precedence over the defaults passed to the class constructor.

  Argumentet `enforce_csrf_checks` kan användas för att testa CSRF-skydd (se ovan).

  Argumentet `raise_request_exception` gör det möjligt att kontrollera om undantag som uppstår under begäran också ska uppstå i testet. Standardvärdet är `True`.

  Argumentet `json_encoder` gör det möjligt att ange en anpassad JSON-kodare för JSON-serialiseringen som beskrivs i `post()`.

  När du har en `Client`-instans kan du anropa någon av följande metoder:

  get(path, data=None, follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en GET-begäran på den angivna `path` och returnerar ett `Response`-objekt, som dokumenteras nedan.

    Nyckel-värdeparen i ordlistan `query_params` används för att ställa in frågesträngar. Ett exempel:

        >>> c = Client()
        >>> c.get("/customers/details/", query_params={"name": "fred", "age": 7})

    …kommer att resultera i en utvärdering av en GET-begäran som motsvarar:

        /customers/details/?name=fred&age=7

    Det är också möjligt att skicka dessa parametrar till parametern `data`. `query_params` är dock att föredra eftersom den fungerar för alla HTTP-metoder.

    Parametern `headers` kan användas för att ange vilka rubriker som ska skickas i begäran. Till exempel:

        >>> c = Client()
        >>> c.get(
        ...     "/customers/details/",
        ...     query_params={"name": "fred", "age": 7},
        ...     headers={"accept": "application/json"},
        ... )

    …will send the HTTP header `HTTP_ACCEPT` to the details view, which is a good way to test code paths that use the `django.http.HttpRequest.accepts()` method.

    Godtyckliga nyckelordsargument ställer in WSGI environ-variabler. Till exempel headers för att ange skriptnamnet:

        >>> c = Client()
        >>> c.get("/", SCRIPT_NAME="/app/")

    Om du redan har GET-argumenten i URL-kodad form kan du använda den kodningen i stället för att använda data-argumentet. Till exempel kan den föregående GET-begäran också ställas som:

        >>> c = Client()
        >>> c.get("/customers/details/?name=fred&age=7")

    Om du anger en URL med både kodade GET-data och antingen ett query_params- eller data-argument kommer dessa argument att ha företräde.

    Om du anger `follow` till `True` kommer klienten att följa alla omdirigeringar och ett `redirect_chain`-attribut kommer att anges i svarsobjektet som innehåller tuples av de mellanliggande webbadresserna och statuskoderna.

    Om du hade en URL `/redirect_me/` som omdirigerades till `/next/`, som omdirigerades till `/final/`, är det här vad du skulle se:

        >>> response = c.get("/redirect_me/", follow=True)
        >>> response.redirect_chain
        [('http://testserver/next/', 302), ('http://testserver/final/', 302)]

    Om du anger `secure` till `True` kommer klienten att emulera en HTTPS-begäran.

  post(path, data=None, content_type=MULTIPART_CONTENT, follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en POST-begäran på den angivna `path` och returnerar ett `Response`-objekt, som dokumenteras nedan.

    Nyckel-värdeparen i ordlistan `data` används för att skicka POST-data. Till exempel:

        >>> c = Client()
        >>> c.post("/login/", {"name": "fred", "passwd": "secret"})

    …kommer att resultera i en utvärdering av en POST-begäran till denna URL:

        /login/

    …med denna POST-data:

        name=fred&passwd=secret

    Om du anger `content_type` som application/json, serialiseras `data` med `json.dumps()` om det är en dict, lista eller tuple. Serialisering utförs med `DjangoJSONEncoder` som standard, och kan åsidosättas genom att tillhandahålla ett `json_encoder` argument till `Client`. Denna serialisering sker också för `put()`, `patch()` och `delete()` förfrågningar.

    Om du anger någon annan `content_type` (t.ex. text/xml för en XML-nyttolast) skickas innehållet i `data` som det är i POST-begäran, med `content_type` i HTTP-rubriken `Content-Type`.

    Om du inte anger något värde för `content_type` kommer värdena i `data` att överföras med en innehållstyp av multipart/form-data. I det här fallet kommer nyckel-värdeparen i `data` att kodas som ett multipartmeddelande och användas för att skapa POST-datanyttolasten.

    Om du vill skicka in flera värden för en viss nyckel - t.ex. för att ange urvalen för en `<select multiple>` - ska du ange värdena som en lista eller tupel för den nyckel som krävs. Till exempel skulle detta värde av `data` skicka tre valda värden för fältet med namnet `choices`:

        {"choices": ["a", "b", "d"]}

    Att skicka filer är ett specialfall. För att POSTa en fil behöver du bara ange filfältets namn som en nyckel och ett filhandtag till filen du vill ladda upp som ett värde. Om ditt formulär till exempel har fälten `name` och `attachment`, är det senare en `FileField`:

        >>> c = Client()
        >>> with open("wishlist.doc", "rb") as fp:
        ...     c.post("/customers/wishes/", {"name": "fred", "attachment": fp})
        ...

    Du kan också tillhandahålla vilket filliknande objekt som helst (t.ex. `StringIO` eller `BytesIO`) som ett filhandtag. Om du laddar upp till en `ImageField` behöver objektet ett `name`-attribut som skickar `validate_image_file_extension`-validatorn. Till exempel:

        >>> from io import BytesIO
        >>> img = BytesIO(
        ...     b"GIF89a\x01\x00\x01\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00"
        ...     b"\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x01\x00\x00"
        ... )
        >>> img.name = "myimage.gif"

    Observera att om du vill använda samma filhandtag för flera `post()`-anrop måste du manuellt återställa filpekaren mellan inläggen. Det enklaste sättet att göra detta är att manuellt stänga filen efter att den har levererats till `post()`, som demonstreras ovan.

    Du bör också se till att filen öppnas på ett sätt som gör det möjligt att läsa data. Om filen innehåller binära data, t.ex. en bild, innebär det att du måste öppna filen i läget `rb` (read binary).

    Parametrarna `headers`, `query_params` och `extra` fungerar på samma sätt som för `Client.get()`.

    Om URL:en som du begär med en POST innehåller kodade parametrar, kommer dessa parametrar att göras tillgängliga i request.GET-data. Om du t.ex. skulle göra begäran:

        >>> c.post(
        ...     "/login/", {"name": "fred", "passwd": "secret"}, query_params={"visitor": "true"}
        ... )

    … kan vyn som hanterar denna begäran fråga request.POST för att hämta användarnamn och lösenord, och kan fråga request.GET för att avgöra om användaren var en besökare.

    Om du anger `follow` till `True` kommer klienten att följa alla omdirigeringar och ett `redirect_chain`-attribut kommer att anges i svarsobjektet som innehåller tuples av de mellanliggande webbadresserna och statuskoderna.

    Om du anger `secure` till `True` kommer klienten att emulera en HTTPS-begäran.

  head(path, data=None, follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en HEAD-förfrågan på den angivna `path` och returnerar ett `Response`-objekt. Denna metod fungerar precis som `Client.get()`, inklusive parametrarna `follow`, `secure`, `headers`, `query_params` och `extra`, förutom att den inte returnerar en meddelandekropp.

  options(path, data='', content_type='application/octet-stream', follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en OPTIONS-begäran på den angivna `vägen` och returnerar ett `svar`-objekt. Användbart för att testa RESTful-gränssnitt.

    När `data` tillhandahålls används det som förfrågningsunderlag och ett `Content-Type`-huvud sätts till `content_type`.

    Parametrarna `follow`, `secure`, `headers`, `query_params` och `extra` fungerar på samma sätt som för `Client.get()`.

  put(path, data='', content_type='application/octet-stream', follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en PUT-förfrågan på den angivna `path` och returnerar ett `Response`-objekt. Användbart för att testa RESTful-gränssnitt.

    När `data` tillhandahålls används det som förfrågningsunderlag och ett `Content-Type`-huvud sätts till `content_type`.

    Parametrarna `follow`, `secure`, `headers`, `query_params` och `extra` fungerar på samma sätt som för `Client.get()`.

  patch(path, data='', content_type='application/octet-stream', follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en PATCH-förfrågan på den angivna `banan` och returnerar ett `svar`-objekt. Användbart för att testa RESTful-gränssnitt.

    Parametrarna `follow`, `secure`, `headers`, `query_params` och `extra` fungerar på samma sätt som för `Client.get()`.

  delete(path, data='', content_type='application/octet-stream', follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en DELETE-begäran på den angivna `vägen` och returnerar ett `svar`-objekt. Användbart för att testa RESTful-gränssnitt.

    När `data` tillhandahålls används det som förfrågningsunderlag och ett `Content-Type`-huvud sätts till `content_type`.

    Parametrarna `follow`, `secure`, `headers`, `query_params` och `extra` fungerar på samma sätt som för `Client.get()`.

  trace(path, follow=False, secure=False, *, headers=None, query_params=None, **extra)

    Gör en TRACE-begäran på den angivna `vägen` och returnerar ett `svar`-objekt. Användbar för att simulera diagnostiska prober.

    Till skillnad från de andra förfrågningsmetoderna tillhandahålls inte `data` som en nyckelordsparameter för att följa RFC 9110 Section 9.3.8, som föreskriver att TRACE-förfrågningar inte får ha en kropp.

    Parametrarna `follow`, `secure`, `headers`, `query_params` och `extra` fungerar på samma sätt som för `Client.get()`.

  login(**credentials)
  alogin(**credentials)

    Asynkron version: `alogin()`

    Om din webbplats använder Djangos authentication system och du hanterar inloggning av användare, kan du använda testklientens `login()`-metod för att simulera effekten av att en användare loggar in på webbplatsen.

    När du anropar den här metoden kommer testklienten att ha alla cookies och sessionsdata som krävs för att klara inloggningsbaserade tester som kan ingå i en vy.

    Formatet på argumentet `credentials` beror på vilken authentication backend <authentication-backends>` du använder (som konfigureras av din `AUTHENTICATION_BACKENDS`-inställning). Om du använder standardautentiseringsbackend som tillhandahålls av Django (`ModelBackend`), bör `credentials` vara användarens användarnamn och lösenord, som tillhandahålls som nyckelordsargument:

        >>> c = Client()
        >>> c.login(username="fred", password="secret")

        # Now you can access a view that's only available to logged-in users.

    Om du använder en annan autentiseringsbackend kan den här metoden kräva andra referenser. Den kräver de autentiseringsuppgifter som krävs av din backends `authenticate()` metod.

    `login()` returnerar `True` om autentiseringsuppgifterna accepterades och inloggningen lyckades.

    Finally, you’ll need to remember to create user accounts before you can use this method. As we explained above, the test runner is executed using a test database, which contains no users by default. As a result, user accounts that are valid on your production site will not work under test conditions. You’ll need to create users as part of the test suite – either manually (using the Django model API) or with a test fixture. Remember that if you want your test user to have a password, you can’t set the user’s password by setting the password attribute directly – you must use the `set_password()` function to store a correctly hashed password. Alternatively, you can use the `create_user()` helper method to create a new user with a correctly hashed password.

  force_login(user, backend=None)
  aforce_login(user, backend=None)

    Asynkron version: `aforce_login()`

    Om din webbplats använder Djangos authentication system kan du använda metoden `force_login()` för att simulera effekten av att en användare loggar in på webbplatsen. Använd den här metoden istället för `login()` när ett test kräver att en användare är inloggad och detaljerna om hur en användare loggar in inte är viktiga.

    Till skillnad från `login()` hoppar den här metoden över autentiserings- och verifieringsstegen: inaktiva användare (`is_active=False`) tillåts logga in och användarens autentiseringsuppgifter behöver inte anges.

    Användaren kommer att ha sitt `backend`-attribut inställt till värdet av `backend`-argumentet (som bör vara en prickad Python-sökvägssträng), eller till `settings.AUTHENTICATION_BACKENDS[0]` om ett värde inte tillhandahålls. Funktionen `authenticate()` som anropas av `login()` annoterar normalt användaren så här.

    Den här metoden är snabbare än `login()` eftersom de dyra hashingalgoritmerna för lösenord kringgås. Du kan också snabba upp `login()` genom att använda en svagare hasher när du testar.

  logout()
  alogout()

    Asynkron version: `alogout()`

    Om din webbplats använder Djangos autentiseringssystem, kan metoden `logout()` användas för att simulera effekten av att en användare loggar ut från din webbplats.

    När du har anropat den här metoden kommer testklienten att ha alla cookies och sessionsdata rensade till standardvärden. Efterföljande förfrågningar kommer att se ut att komma från en `AnonymousUser`.

### Testning av svar

Metoderna `get()` och `post()` returnerar båda ett `Response`-objekt. Detta `Response`-objekt är inte samma som `HttpResponse`-objektet som returneras av Django-vyer; testsvarsobjektet har några ytterligare data som är användbara för testkod för att verifiera.

Specifikt har ett `Response`-objekt följande attribut:

class Response
  client

    Den testklient som användes för att göra den begäran som resulterade i svaret.

  content

    Svarets innehåll, som en bytestring. Detta är det slutliga sidinnehållet som återges av vyn, eller ett eventuellt felmeddelande.

  context

    Mallen `Context`-instans som användes för att rendera den mall som producerade svarsinnehållet.

    Om den renderade sidan använde flera mallar kommer `context` att vara en lista med `Context`-objekt, i den ordning de renderades.

    Oavsett hur många mallar som används vid rendering kan du hämta kontextvärden med operatorn `[]`. Exempelvis kan kontextvariabeln `name` hämtas med hjälp av:

        >>> response = client.get("/foo/")
        >>> response.context["name"]
        'Arthur'

    Använder du inte Django-mallar?

    Detta attribut fylls endast i när du använder `DjangoTemplates` backend. Om du använder en annan mallmotor kan `context_data` vara ett lämpligt alternativ för svar med det attributet.

  exc_info

    En tupel med tre värden som ger information om det eventuella ohanterade undantag som inträffade under vyn.

    Värdena är (type, value, traceback), samma som returneras av Pythons `sys.exc_info()`. Deras betydelser är:

    - typ: Typ av undantag.

    - värde: Instansen för undantaget.

    - traceback: Ett traceback-objekt som kapslar in anropsstacken vid den punkt där undantaget ursprungligen inträffade.

    Om inget undantag inträffade kommer `exc_info` att vara `None`.

  json(**kwargs)

    Svarets text, tolkad som JSON. Extra nyckelordsargument skickas till `json.loads()`. Till exempel: json.loads:

        >>> response = client.get("/foo/")
        >>> response.json()["name"]
        'Arthur'

    Om rubriken `Content-Type` inte är `"application/json"`, kommer ett `ValueError`` att uppstå när du försöker analysera svaret.

  request

    Förfrågningsdata som stimulerade svaret.

  wsgi_request

    Instansen `WSGIRequest` som genererades av testhanteraren som genererade svaret.

  status_code

    HTTP-status för svaret, som ett heltal. För en fullständig lista över definierade koder, se IANA status code registry.

  templates

    En lista över `Template`-instanser som används för att rendera det slutliga innehållet, i den ordning de renderades. För varje mall i listan, använd `template.name` för att få mallens filnamn, om mallen laddades från en fil. (Namnet är en sträng som till exempel `'admin/index.html'`.)

    Använder du inte Django-mallar?

    Detta attribut fylls endast i när du använder `DjangoTemplates` backend. Om du använder en annan mallmotor kan `template_name` vara ett lämpligt alternativ om du bara behöver namnet på den mall som används för rendering.

  resolver_match

    En instans av `ResolverMatch` för svaret. Du kan till exempel använda attributet `func` för att verifiera den vy som serverade svaret:

        # my_view here is a function based view.
        self.assertEqual(response.resolver_match.func, my_view)

        # Class-based views need to compare the view_class, as the
        # functions generated by as_view() won't be equal.
        self.assertIs(response.resolver_match.func.view_class, MyView)

    Om den angivna URL:en inte hittas kommer åtkomst till detta attribut att ge upphov till ett `Resolver404` undantag.

Precis som med ett vanligt svar kan du också komma åt rubrikerna via `HttpResponse.headers`. Du kan till exempel bestämma innehållstypen i ett svar med hjälp av `response.headers['Content-Type']`.

### Undantag

Om du riktar testklienten mot en vy som ger upphov till ett undantag och `Client.raise_request_exception` är `True`, kommer undantaget att vara synligt i testfallet. Du kan sedan använda ett standardblock `try ... except` eller `assertRaises()` för att testa för undantag.

De enda undantagen som inte är synliga för testklienten är `Http404`, `PermissionDenied`, `SystemExit`, och `SuspiciousOperation`. Django fångar dessa undantag internt och omvandlar dem till lämpliga HTTP-svarskoder. I dessa fall kan du kontrollera `response.status_code` i ditt test.

Om `Client.raise_request_exception` är `False` kommer testklienten att returnera ett 500-svar som skulle returneras till en webbläsare. Svaret har attributet `exc_info` för att ge information om det ohanterade undantaget.

### Beständigt tillstånd

Testklienten är tillståndsbaserad. Om ett svar returnerar en cookie, kommer denna cookie att lagras i testklienten och skickas med alla efterföljande `get()`- och `post()`-förfrågningar.

Utgångspolicyerna för dessa cookies följs inte. Om du vill att en cookie ska upphöra att gälla måste du antingen ta bort den manuellt eller skapa en ny instans av `Client` (vilket i praktiken innebär att alla cookies tas bort).

En testklient har attribut som lagrar information om beständigt tillstånd. Du kan komma åt dessa egenskaper som en del av ett testvillkor.

Client.cookies

  Ett Python `SimpleCookie`-objekt som innehåller de aktuella värdena för alla klientcookies. Se dokumentationen för modulen `http.cookies` för mer information.

Client.session

  Ett ordboksliknande objekt som innehåller sessionsinformation. Se session documentation för fullständig information.

  För att ändra sessionen och sedan spara den måste den först lagras i en variabel (eftersom en ny `SessionStore` skapas varje gång denna egenskap används):

      def test_something(self):
          session = self.client.session
          session["somekey"] = "test"
          session.save()

Client.asession()

  Detta liknar attributet `session` men det fungerar i asynkrona sammanhang.

### Ställa in språk

När du testar applikationer som stöder internationalisering och lokalisering kanske du vill ställa in språket för en testklientbegäran. Metoden för att göra detta beror på om `LocaleMiddleware` är aktiverad eller inte.

Om middleware är aktiverat kan språket ställas in genom att skapa en cookie med namnet `LANGUAGE_COOKIE_NAME` och ett värde som motsvarar språkkoden:

    from django.conf import settings

    def test_language_using_cookie(self):
        self.client.cookies.load({settings.LANGUAGE_COOKIE_NAME: "fr"})
        response = self.client.get("/")
        self.assertEqual(response.content, b"Bienvenue sur mon site.")

eller genom att inkludera HTTP-huvudet `Accept-Language` i begäran:

    def test_language_using_header(self):
        response = self.client.get("/", headers={"accept-language": "fr"})
        self.assertEqual(response.content, b"Bienvenue sur mon site.")

Observera

När du använder dessa metoder, se till att återställa det aktiva språket i slutet av varje test:

    def tearDown(self):
        translation.activate(settings.LANGUAGE_CODE)

Mer information finns i Hur Django upptäcker språkpreferenser.

Om mellanvaran inte är aktiverad kan det aktiva språket ställas in med `translation.override()`:

    from django.utils import translation

    def test_language_using_override(self):
        with translation.override("fr"):
            response = self.client.get("/")
        self.assertEqual(response.content, b"Bienvenue sur mon site.")

Mer information finns i Explicit inställning av det aktiva språket.

### Exempel

Följande är ett enhetstest med hjälp av testklienten:

    import unittest
    from django.test import Client

    class SimpleTest(unittest.TestCase):
        def setUp(self):
            # Every test needs a client.
            self.client = Client()

        def test_details(self):
            # Issue a GET request.
            response = self.client.get("/customer/details/")

            # Check that the response is 200 OK.
            self.assertEqual(response.status_code, 200)

            # Check that the rendered context contains 5 customers.
            self.assertEqual(len(response.context["customers"]), 5)

Se även

`django.test.RequestFactory`

## Tillhandahållna testfallsklasser

Vanliga Python-enhetstestklasser utökar en basklass av `unittest.TestCase`. Django tillhandahåller några tillägg till denna basklass:

Hierarki av klasser för enhetstestning av Django

Du kan konvertera en normal `unittest.TestCase` till någon av underklasserna: ändra basklassen för ditt test från `unittest.TestCase` till underklassen. Alla Pythons standardfunktioner för enhetstester kommer att finnas tillgängliga, och de kommer att kompletteras med några användbara tillägg som beskrivs i varje avsnitt nedan.

### `SimpleTestCase`

class SimpleTestCase

En subklass av `unittest.TestCase` som lägger till denna funktionalitet:

- Några användbara påståenden som:

  - Kontrollerar att en anropsbar `utlöser ett visst undantag`.

  - Kontrollerar att en anropsbar `utlöser en viss varning`.

  - Testar formulärfält `rendering och felbehandling`.

  - Testar `HTML-svar för närvaro/avsaknad av ett visst fragment`.

  - Kontrollerar att en mall `har/har inte använts för att generera ett visst svarsinnehåll`.

  - Kontrollerar att två `URL:er` är lika.

  - Verifiera att en HTTP `redirect` utförs av appen.

  - Robust testning av två `HTML-fragment` för likhet/olikhet eller `containment`.

  - Robust test av två `XML-fragment` för likhet/olikhet.

  - Robust test av två `JSON-fragment` för jämlikhet.

- Möjligheten att köra tester med modified settings.

- Använda `client` `Client`.

Om dina tester gör några databasfrågor, använd underklasserna `TransactionTestCase` eller `TestCase`.

SimpleTestCase.databases

  `SimpleTestCase` tillåter inte databasfrågor som standard. Detta hjälper till att undvika att skriva frågor som påverkar andra tester eftersom varje `SimpleTestCase`-test inte körs i en transaktion. Om du inte är orolig för det här problemet kan du inaktivera det här beteendet genom att ställa in klassattributet `databases` till `'__all__'` på din testklass.

Varning

`SimpleTestCase` och dess underklasser (t.ex. `TestCase`, …) förlitar sig på `setUpClass()` och `tearDownClass()` för att utföra vissa klassomfattande initialiseringar (t.ex. åsidosätta inställningar). Om du behöver åsidosätta dessa metoder, glöm inte att anropa `super` implementationen:

    class MyTestCase(TestCase):
        @classmethod
        def setUpClass(cls):
            super().setUpClass()
            ...

        @classmethod
        def tearDownClass(cls):
            ...
            super().tearDownClass()

Var noga med att ta hänsyn till Pythons beteende om ett undantag uppstår under `setUpClass()`. Om det händer kommer varken testerna i klassen eller `tearDownClass()` att köras. I fallet med `django.test.TestCase` kommer detta att läcka transaktionen som skapats i `super()` vilket resulterar i olika symptom inklusive ett segmenteringsfel på vissa plattformar (rapporterat på macOS). Om du avsiktligt vill skapa ett undantag som `unittest.SkipTest` i `setUpClass()`, se till att göra det innan du anropar `super()` för att undvika detta.

### `TransactionTestCase`

class TransactionTestCase

`TransactionTestCase` ärver från `SimpleTestCase` för att lägga till några databasspecifika funktioner:

- Återställning av databasen till ett känt tillstånd i slutet av varje test för att underlätta testning och användning av ORM.

- Databas `fixtures`.

- Test hoppa över baserat på databasens backend-funktioner.

- De återstående specialiserade `assert*` -metoderna.

Django’s `TestCase` class is a more commonly used subclass of `TransactionTestCase` that makes use of database transaction facilities to speed up the process of resetting the database to a known state at the end of each test. A consequence of this, however, is that some database behaviors cannot be tested within a Django `TestCase` class. For instance, you cannot test that a block of code is executing within a transaction, as is required when using `select_for_update()`. In those cases, you should use `TransactionTestCase`.

`TransactionTestCase` och `TestCase` är identiska med undantag för det sätt på vilket databasen återställs till ett känt tillstånd och möjligheten för testkoden att testa effekterna av commit och rollback:

- Ett `TransactionTestCase` återställer databasen efter testkörningen genom att trunkera alla tabeller. Ett `TransactionTestCase` kan anropa commit och rollback och observera effekterna av dessa anrop på databasen.

- Ett `TestCase` trunkerar däremot inte tabeller efter ett test. Istället innesluts testkoden i en databastransaktion som rullas tillbaka i slutet av testet. Detta garanterar att rollback i slutet av testet återställer databasen till dess ursprungliga tillstånd.

Varning

`TestCase` som körs på en databas som inte stöder rollback (t.ex. MySQL med lagringsmotorn MyISAM), och alla instanser av `TransactionTestCase`, kommer att rulla tillbaka i slutet av testet genom att ta bort alla data från testdatabasen.

Appar kommer inte att se sina data laddas om; om du behöver den här funktionen (till exempel bör tredjepartsappar aktivera detta) kan du ställa in `serialized_rollback = True` i `TestCase`-kroppen.

### `TestCase`

class TestCase

Detta är den vanligaste klassen att använda för att skriva tester i Django. Den ärver från `TransactionTestCase` (och i förlängningen `SimpleTestCase`). Om din Django-applikation inte använder en databas, använd `SimpleTestCase`.

Klassen:

- Omsluter testerna i två nästlade `atomic()`-block: ett för hela klassen och ett för varje test. Därför, om du vill testa något specifikt databas transaktionsbeteende, använd `TransactionTestCase`.

- Kontrollerar uppskjutbara databasbegränsningar i slutet av varje test.

Det ger också en ytterligare metod:

classmethod TestCase.setUpTestData()

  Det `atomiska` block på klassnivå som beskrivs ovan gör det möjligt att skapa initialdata på klassnivå, en gång för hela `TestCase`. Denna teknik möjliggör snabbare tester jämfört med att använda `setUp()`.

  Till exempel:

      from django.test import TestCase

      class MyTests(TestCase):
          @classmethod
          def setUpTestData(cls):
              # Set up data for the whole TestCase
              cls.foo = Foo.objects.create(bar="Test")
              ...

          def test1(self):
              # Some test using self.foo
              ...

          def test2(self):
              # Some other test using self.foo
              ...

  Observera att om testerna körs på en databas utan transaktionsstöd (t.ex. MySQL med MyISAM-motorn) kommer `setUpTestData()` att anropas före varje test, vilket upphäver hastighetsfördelarna.

  Objects assigned to class attributes in `setUpTestData()` must support creating deep copies with `copy.deepcopy()` in order to isolate them from alterations performed by each test methods.

classmethod TestCase.captureOnCommitCallbacks(using=DEFAULT_DB_ALIAS, execute=False)

  Returnerar en kontexthanterare som fångar upp `transaction.on_commit()` callbacks för den angivna databasanslutningen. Den returnerar en lista som innehåller, vid avslutning av kontexten, de fångade återuppringningsfunktionerna. Från den här listan kan du göra påståenden om återuppringningarna eller anropa dem för att åberopa deras sidoeffekter, vilket emulerar en commit.

  `using` är aliaset för den databasanslutning för vilken återuppringningar ska registreras.

  Om `execute` är `True` kommer alla callbacks att anropas när kontexthanteraren avslutas, om inget undantag inträffade. Detta emulerar en commit efter det omslutna kodblocket.

  Till exempel:

      from django.core import mail
      from django.test import TestCase

      class ContactTests(TestCase):
          def test_post(self):
              with self.captureOnCommitCallbacks(execute=True) as callbacks:
                  response = self.client.post(
                      "/contact/",
                      {"message": "I like your site"},
                  )

              self.assertEqual(response.status_code, 200)
              self.assertEqual(len(callbacks), 1)
              self.assertEqual(len(mail.outbox), 1)
              self.assertEqual(mail.outbox[0].subject, "Contact Form")
              self.assertEqual(mail.outbox[0].body, "I like your site")

### `LiveServerTestCase`

class LiveServerTestCase

`LiveServerTestCase` gör i princip samma sak som `TransactionTestCase` med en extra funktion: den startar en live Django-server i bakgrunden vid installationen och stänger av den vid nedmonteringen. Detta gör det möjligt att använda andra automatiserade testklienter än Django dummy client som till exempel Selenium-klienten, för att utföra en serie funktionella tester i en webbläsare och simulera en riktig användares handlingar.

Live-servern lyssnar på `localhost` och binder till port 0 som använder en fri port som tilldelas av operativsystemet. Serverns URL kan nås med `self.live_server_url` under testerna.

För att visa hur man använder `LiveServerTestCase`, låt oss skriva ett Selenium-test. Först och främst måste du installera paketet selenium:

/ 

    $ python -m pip install "selenium >= 4.23.0"

    ...\> py -m pip install "selenium >= 4.23.0"

Lägg sedan till ett `LiveServerTestCase`-baserat test i din apps testmodul (till exempel: `myapp/tests.py`). I det här exemplet antar vi att du använder `staticfiles`-appen och vill ha statiska filer serverade under körningen av dina tester liknande det vi får vid utvecklingstid med `DEBUG=True`, dvs. utan att behöva samla in dem med `collectstatic`. Vi kommer att använda `StaticLiveServerTestCase` subklassen som tillhandahåller den funktionaliteten. Ersätt den med `django.test.LiveServerTestCase` om du inte behöver det.

Koden för detta test kan se ut på följande sätt:

    from django.contrib.staticfiles.testing import StaticLiveServerTestCase
    from selenium.webdriver.common.by import By
    from selenium.webdriver.firefox.webdriver import WebDriver

    class MySeleniumTests(StaticLiveServerTestCase):
        fixtures = ["user-data.json"]

        @classmethod
        def setUpClass(cls):
            super().setUpClass()
            cls.selenium = WebDriver()
            cls.selenium.implicitly_wait(10)

        @classmethod
        def tearDownClass(cls):
            cls.selenium.quit()
            super().tearDownClass()

        def test_login(self):
            self.selenium.get(f"{self.live_server_url}/login/")
            username_input = self.selenium.find_element(By.NAME, "username")
            username_input.send_keys("myuser")
            password_input = self.selenium.find_element(By.NAME, "password")
            password_input.send_keys("secret")
            self.selenium.find_element(By.XPATH, '//input[@value="Log in"]').click()

Slutligen kan du köra testet på följande sätt:

/ 

    $ ./manage.py test myapp.tests.MySeleniumTests.test_login

    ...\> manage.py test myapp.tests.MySeleniumTests.test_login

Detta exempel kommer automatiskt att öppna Firefox och sedan gå till inloggningssidan, ange inloggningsuppgifterna och trycka på knappen ”Logga in”. Selenium erbjuder andra drivrutiner om du inte har Firefox installerat eller vill använda en annan webbläsare. Exemplet ovan är bara en liten bråkdel av vad Selenium-klienten kan göra; kolla in full reference för mer information.

Observera

När man använder en SQLite-databas i minnet för att köra testerna kommer samma databasanslutning att delas av två parallella trådar: den tråd i vilken live-servern körs och den tråd i vilken testfallet körs. Det är viktigt att förhindra samtidiga databasfrågor via denna delade anslutning av de två trådarna, eftersom det ibland slumpmässigt kan leda till att testerna misslyckas. Du måste alltså se till att de två trådarna inte kommer åt databasen samtidigt. I synnerhet innebär detta att du i vissa fall (t.ex. strax efter att du har klickat på en länk eller skickat in ett formulär) kan behöva kontrollera att Selenium får ett svar och att nästa sida laddas innan du fortsätter med ytterligare testkörning. Det gör du t.ex. genom att låta Selenium vänta tills HTML-taggen `<body>` hittas i svaret (kräver Selenium > 2.13):

    def test_login(self):
        from selenium.webdriver.support.wait import WebDriverWait

        timeout = 2
        ...
        self.selenium.find_element(By.XPATH, '//input[@value="Log in"]').click()
        # Wait until the response is received
        WebDriverWait(self.selenium, timeout).until(
            lambda driver: driver.find_element(By.TAG_NAME, "body")
        )

Det knepiga här är att det egentligen inte finns något sådant som en ”sidladdning”, särskilt i moderna webbappar som genererar HTML dynamiskt efter att servern har genererat det ursprungliga dokumentet. Så att kontrollera om `<body>` finns i svaret är inte nödvändigtvis lämpligt för alla användningsfall. Mer information finns i Selenium FAQ och Selenium documentation.

## Testfall funktioner

### Standard testklient

SimpleTestCase.client

Varje testfall i en instans av `django.test.*TestCase` har tillgång till en instans av en Django-testklient. Denna klient kan nås som `self.client`. Den här klienten återskapas för varje test, så du behöver inte oroa dig för att tillstånd (t.ex. cookies) överförs från ett test till ett annat.

Detta innebär att istället för att instansiera en `Client` i varje test:

    import unittest
    from django.test import Client

    class SimpleTest(unittest.TestCase):
        def test_details(self):
            client = Client()
            response = client.get("/customer/details/")
            self.assertEqual(response.status_code, 200)

        def test_index(self):
            client = Client()
            response = client.get("/customer/index/")
            self.assertEqual(response.status_code, 200)

…kan du hänvisa till `self.client`, så här:

    from django.test import TestCase

    class SimpleTest(TestCase):
        def test_details(self):
            response = self.client.get("/customer/details/")
            self.assertEqual(response.status_code, 200)

        def test_index(self):
            response = self.client.get("/customer/index/")
            self.assertEqual(response.status_code, 200)

### Anpassning av testklienten

SimpleTestCase.client_class

Om du vill använda en annan `Client`-klass (t.ex. en underklass med anpassat beteende) använder du klassattributet `client_class`:

    from django.test import Client, TestCase

    class MyTestClient(Client):
        # Specialized methods for your environment
        ...

    class MyTest(TestCase):
        client_class = MyTestClient

        def test_my_stuff(self):
            # Here self.client is an instance of MyTestClient...
            call_some_test_code()

### Lastning av fixtur

TransactionTestCase.fixtures

En testfallsklass för en databasbaserad webbplats är inte till någon större nytta om det inte finns några data i databasen. Tester är mer läsbara och det är mer underhållbart att skapa objekt med hjälp av ORM, till exempel i `TestCase.setUpTestData()`, men du kan också använda fixtures.

En fixtur är en samling data som Django vet hur man importerar till en databas. Om din webbplats till exempel har användarkonton kan du skapa en fixtur med falska användarkonton för att fylla på din databas under tester.

Det enklaste sättet att skapa en fixtur är att använda kommandot `manage.py dumpdata`. Detta förutsätter att du redan har en del data i din databas. Se `dumpdata documentation` för mer information.

När du har skapat en fixtur och placerat den i en `fixtures` katalog i en av dina `INSTALLED_APPS`, kan du använda den i dina enhetstester genom att ange ett `fixtures` klassattribut på din `django.test.TestCase` subclass:

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

    class AnimalTestCase(TestCase):
        fixtures = ["mammals.json", "birds"]

        def setUp(self):
            # Test definitions as before.
            call_setup_methods()

        def test_fluffy_animals(self):
            # A test that uses the fixtures.
            call_some_test_code()

Det här är vad som kommer att hända i detalj:

- Under `setUpClass()` installeras alla namngivna fixturer. I det här exemplet kommer Django att installera alla JSON-fixturer med namnet `mammals`, följt av alla fixturer med namnet `birds`. Se ämnet Fixturer för mer information om hur man definierar och installerar fixturer.

För de flesta enhetstester som använder `TestCase` behöver Django inte göra något annat, eftersom transaktioner används för att rensa databasen efter varje test av prestandaskäl. Men för `TransactionTestCase` kommer följande åtgärder att äga rum:

- I slutet av varje test kommer Django att spola databasen, vilket återställer databasen till det tillstånd den befann sig i direkt efter att `migrate` anropades.

- För varje efterföljande test kommer fixturerna att laddas om innan `setUp()` körs.

I vilket fall som helst kan du vara säker på att resultatet av ett test inte kommer att påverkas av ett annat test eller av ordningen på testgenomförandet.

Som standard laddas fixturer endast in i databasen `default`. Om du använder flera databaser och anger `TransactionTestCase.databases` kommer fixturer att laddas i alla angivna databaser.

Changed in Django 5.2:

För `TransactionTestCase` gjordes fixturer tillgängliga under `setUpClass()`.

### URLconf-konfiguration

Om din applikation innehåller vyer kanske du vill inkludera tester som använder testklienten för att aktivera dessa vyer. Det står dock en slutanvändare fritt att distribuera vyerna i din applikation till vilken URL som helst. Detta innebär att dina tester inte kan förlita sig på att dina vyer kommer att finnas tillgängliga på en viss URL. Dekorera din testklass eller testmetod med `@override_settings(ROOT_URLCONF=...)` för URLconf-konfiguration.

### Stöd för flera databaser

TransactionTestCase.databases

Django skapar en testdatabas som motsvarar varje databas som definieras i `DATABASER`-definitionen i dina inställningar och som minst ett test hänvisar till via `databaser`.

En stor del av den tid det tar att köra ett Django `TestCase` förbrukas dock av anropet till `flush` som säkerställer att du har en ren databas i slutet av varje testkörning. Om du har flera databaser krävs flera spolningar (en för varje databas), vilket kan vara en tidskrävande aktivitet - särskilt om dina tester inte behöver testa aktivitet i flera databaser.

Som en optimering spolar Django bara databasen `default` i slutet av varje testkörning. Om din installation innehåller flera databaser och du har ett test som kräver att alla databaser är rena, kan du använda attributet `databaser` på testsviten för att begära att extra databaser spolas.

Till exempel:

    class TestMyViews(TransactionTestCase):
        databases = {"default", "other"}

        def test_index_page_view(self):
            call_some_test_code()

Denna testfallsklass kommer att rensa testdatabaserna `default` och `other` efter att ha kört `test_index_page_view`. Du kan också använda `'__all__'` för att ange att alla testdatabaser måste rensas.

Flaggan `databases` styr också vilka databaser som `TransactionTestCase.fixtures` laddas in i. Som standard laddas fixturerna endast in i databasen `default`.

Frågor mot databaser som inte finns i `databaser` kommer att ge assertionfel för att förhindra att tillstånd läcker mellan tester.

TestCase.databases

Som standard kommer endast `standard`-databasen att omslutas av en transaktion under exekveringen av ett `TestCase` och försök att fråga andra databaser kommer att resultera i assertionfel för att förhindra att tillstånd läcker mellan tester.

Använd klassattributet `databases` på testklassen för att begära transaktionsomslag mot databaser som inte är `standard`.

Till exempel:

    class OtherDBTests(TestCase):
        databases = {"other"}

        def test_other_db_query(self): ...

Detta test tillåter endast frågor mot databasen `other`. Precis som för `SimpleTestCase.databases` och `TransactionTestCase.databases` kan konstanten `'__all__'` användas för att ange att testet ska tillåta frågor till alla databaser.

### Åsidosätta inställningar

Varning

Använd funktionerna nedan för att tillfälligt ändra värdet på inställningar i tester. Manipulera inte `django.conf.settings` direkt eftersom Django inte kommer att återställa de ursprungliga värdena efter sådana manipulationer.

SimpleTestCase.settings()

För teständamål är det ofta användbart att ändra en inställning tillfälligt och återgå till det ursprungliga värdet efter att testkoden har körts. För detta användningsfall tillhandahåller Django en standard Python-kontexthanterare (se PEP 343) som heter `settings()`, som kan användas så här:

    from django.test import TestCase

    class LoginTestCase(TestCase):
        def test_login(self):
            # First check for the default behavior
            response = self.client.get("/sekrit/")
            self.assertRedirects(response, "/accounts/login/?next=/sekrit/")

            # Then override the LOGIN_URL setting
            with self.settings(LOGIN_URL="/other/login/"):
                response = self.client.get("/sekrit/")
                self.assertRedirects(response, "/other/login/?next=/sekrit/")

Detta exempel åsidosätter inställningen `LOGIN_URL` för koden i `with`-blocket och återställer dess värde till det tidigare tillståndet efteråt.

SimpleTestCase.modify_settings()

Det kan vara krångligt att omdefiniera inställningar som innehåller en lista med värden. I praktiken är det ofta tillräckligt att lägga till eller ta bort värden. Django tillhandahåller kontexthanteraren `modify_settings()` för enklare ändringar av inställningar:

    from django.test import TestCase

    class MiddlewareTestCase(TestCase):
        def test_cache_middleware(self):
            with self.modify_settings(
                MIDDLEWARE={
                    "append": "django.middleware.cache.FetchFromCacheMiddleware",
                    "prepend": "django.middleware.cache.UpdateCacheMiddleware",
                    "remove": [
                        "django.contrib.sessions.middleware.SessionMiddleware",
                        "django.contrib.auth.middleware.AuthenticationMiddleware",
                        "django.contrib.messages.middleware.MessageMiddleware",
                    ],
                }
            ):
                response = self.client.get("/")
                # ...

För varje åtgärd kan du ange antingen en lista med värden eller en sträng. När värdet redan finns i listan har `append` och `prepend` ingen effekt; det har inte heller `remove` när värdet inte finns.

override_settings(**kwargs)

Om du vill åsidosätta en inställning för en testmetod tillhandahåller Django dekoratorn `override_settings()` (se PEP 318). Den används så här:

    from django.test import TestCase, override_settings

    class LoginTestCase(TestCase):
        @override_settings(LOGIN_URL="/other/login/")
        def test_login(self):
            response = self.client.get("/sekrit/")
            self.assertRedirects(response, "/other/login/?next=/sekrit/")

Dekoratorn kan också tillämpas på `TestCase`-klasser:

    from django.test import TestCase, override_settings

    @override_settings(LOGIN_URL="/other/login/")
    class LoginTestCase(TestCase):
        def test_login(self):
            response = self.client.get("/sekrit/")
            self.assertRedirects(response, "/other/login/?next=/sekrit/")

modify_settings(*args, **kwargs)

På samma sätt tillhandahåller Django dekoratorn `modify_settings()`:

    from django.test import TestCase, modify_settings

    class MiddlewareTestCase(TestCase):
        @modify_settings(
            MIDDLEWARE={
                "append": "django.middleware.cache.FetchFromCacheMiddleware",
                "prepend": "django.middleware.cache.UpdateCacheMiddleware",
            }
        )
        def test_cache_middleware(self):
            response = self.client.get("/")
            # ...

Dekoratorn kan också tillämpas på testfallsklasser:

    from django.test import TestCase, modify_settings

    @modify_settings(
        MIDDLEWARE={
            "append": "django.middleware.cache.FetchFromCacheMiddleware",
            "prepend": "django.middleware.cache.UpdateCacheMiddleware",
        }
    )
    class MiddlewareTestCase(TestCase):
        def test_cache_middleware(self):
            response = self.client.get("/")
            # ...

Observera

När de får en klass modifierar dessa dekoratorer klassen direkt och returnerar den; de skapar inte och returnerar en modifierad kopia av den. Så om du försöker justera ovanstående exempel för att tilldela returvärdet ett annat namn än `LoginTestCase` eller `MiddlewareTestCase`, kan du bli förvånad över att upptäcka att de ursprungliga testfallsklasserna fortfarande påverkas lika mycket av dekoratorn. För en given klass tillämpas `modify_settings()` alltid efter `override_settings()`.

Varning

Inställningsfilen innehåller vissa inställningar som endast konsulteras under initialisering av Django internals. Om du ändrar dem med `override_settings` ändras inställningen om du kommer åt den via modulen `django.conf.settings`, men Djangos internals kommer åt den på ett annat sätt. Att använda `override_settings()` eller `modify_settings()` med dessa inställningar kommer förmodligen inte att göra vad du förväntar dig att det ska göra.

Vi rekommenderar inte att du ändrar inställningen `DATABASER`. Det är möjligt att ändra inställningen `CACHES`, men det är lite knepigt om du använder interna funktioner som använder cachelagring, som `django.contrib.sessions`. Du måste till exempel initiera sessionsbackend på nytt i ett test som använder cachade sessioner och åsidosätter `CACHES`.

Slutligen bör du undvika att använda dina inställningar som konstanter på modulnivå eftersom `override_settings()` inte fungerar på sådana värden eftersom de bara utvärderas första gången modulen importeras.

Du kan också simulera att en inställning inte finns genom att radera den efter att inställningarna har åsidosatts, så här:

    @override_settings()
    def test_something(self):
        del settings.LOGIN_URL
        ...

När du åsidosätter inställningar måste du se till att hantera de fall där din appkod använder en cache eller liknande funktion som behåller tillståndet även om inställningen ändras. Django tillhandahåller `django.test.signals.setting_changed`-signalen som låter dig registrera återuppringningar för att städa upp och på annat sätt återställa tillståndet när inställningarna ändras.

Django själv använder denna signal för att återställa olika data:

Åsidosatta inställningar | Återställning av data
--- | ---
ANVÄNDNING_TZ, TIDSZON | Tidszon för databaser
TEMPLAT | Mall för motorer
FORM_RENDERER | Standardrenderare
SERIALISERING_MODULER | Serialisatorer cache
LOKALA_ SÖKVÄGAR, SPRÅKKOD | Standardöversättning och inlästa översättningar
STATIC_ROOT, STATIC_URL, LAGRING | Konfiguration av lagringsutrymmen

### Isolera appar

utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None)

  Registrerar de modeller som definieras i en omsluten kontext i sitt eget isolerade `apps`-register. Denna funktion är användbar när du skapar modellklasser för tester, eftersom klasserna kommer att raderas rent efteråt och det inte finns någon risk för namnkollisioner.

  De appetiketter som det isolerade registret ska innehålla måste skickas som enskilda argument. Du kan använda `isolate_apps()` som en dekorator eller en kontexthanterare. Till exempel:

      from django.db import models
      from django.test import SimpleTestCase
      from django.test.utils import isolate_apps

      class MyModelTests(SimpleTestCase):
          @isolate_apps("app_label")
          def test_model_definition(self):
              class TestModel(models.Model):
                  pass

              ...

  … eller:

      with isolate_apps("app_label"):

          class TestModel(models.Model):
              pass

          ...

  Dekoratorformen kan också tillämpas på klasser.

  Två valfria nyckelordsargument kan anges:

  - `attr_name`: attribut som tilldelas det isolerade registret om det används som en klassdekorator.

  - `kwarg_name`: nyckelordsargument som skickar det isolerade registret om det används som en funktionsdekorator.

  Den tillfälliga instansen `Apps` som används för att isolera modellregistreringen kan hämtas som ett attribut när den används som en klassdekorator genom att använda parametern `attr_name`:

      @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)

  … eller alternativt som ett argument på testmetoden när den används som en metoddekorator genom att använda parametern `kwarg_name`:

      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)

### Tömning av testboxen

Om du använder någon av Djangos anpassade `TestCase`-klasser kommer testlöparen att rensa innehållet i test-e-postens utkorg i början av varje testfall.

För mer information om e-posttjänster under tester, se E-posttjänster nedan.

### Påståenden

Precis som Pythons normala klass `unittest.TestCase` implementerar assertion-metoder som `assertTrue()` och `assertEqual()`, tillhandahåller Djangos anpassade klass `TestCase` ett antal anpassade assertion-metoder som är användbara för att testa webbapplikationer:

De felmeddelanden som ges av de flesta av dessa assertion-metoder kan anpassas med argumentet `msg_prefix`. Denna sträng kommer att prefixeras till alla felmeddelanden som genereras av påståendet. Detta gör att du kan ge ytterligare information som kan hjälpa dig att identifiera platsen för och orsaken till ett fel i din testsvit.

SimpleTestCase.assertRaisesMessage(expected_exception, expected_message, callable, *args, **kwargs)
SimpleTestCase.assertRaisesMessage(expected_exception, expected_message)

  Säger att exekvering av `callable` ger upphov till `expected_exception` och att `expected_message` finns i undantagets meddelande. Alla andra resultat rapporteras som ett misslyckande. Det är en enklare version av `unittest.TestCase.assertRaisesRegex()` med skillnaden att `expected_message` inte behandlas som ett reguljärt uttryck.

  Om endast parametrarna `expected_exception` och `expected_message` anges, returneras en kontexthanterare så att den kod som testas kan skrivas inline i stället för som en funktion:

      with self.assertRaisesMessage(ValueError, "invalid literal for int()"):
          int("a")

SimpleTestCase.assertWarnsMessage(expected_warning, expected_message, callable, *args, **kwargs)
SimpleTestCase.assertWarnsMessage(expected_warning, expected_message)

  Analogt med `SimpleTestCase.assertRaisesMessage()` men för `assertWarnsRegex()` istället för `assertRaisesRegex()`.

SimpleTestCase.assertFieldOutput(fieldclass, valid, invalid, field_args=None, field_kwargs=None, empty_value='')

  Försäkrar att ett formulärfält beter sig korrekt med olika inmatningar.

  Parametrar:

    - fieldclass – klassen för det fält som ska testas.

    - valid – en ordlista som mappar giltiga indata till deras förväntade rensade värden.

    - invalid – en ordlista som kopplar ogiltiga indata till ett eller flera felmeddelanden.

    - field_args – de args som skickas för att instansiera fältet.

    - field_kwargs – de kwargs som skickas för att instansiera fältet.

    - empty_value – den förväntade rena utdata för indata i `empty_values`.

  Följande kod testar till exempel att en `EmailField` accepterar `a@a.com` som en giltig e-postadress, men avvisar `aaa` med ett rimligt felmeddelande:

      self.assertFieldOutput(
          EmailField, {"a@a.com": "a@a.com"}, {"aaa": ["Enter a valid email address."]}
      )

SimpleTestCase.assertFormError(form, field, errors, msg_prefix='')

  Säger att ett fält i ett formulär ger upphov till den angivna listan med fel.

  `form` är en `Form` instans. Formuläret måste vara bundet men inte nödvändigtvis validerat (`assertFormError()` kommer automatiskt att anropa `full_clean()` på formuläret).

  `field` är namnet på det fält i formuläret som ska kontrolleras. För att kontrollera formulärets `icke-fältfel`, använd `field=None`.

  `errors` är en lista med alla felsträngar som fältet förväntas ha. Du kan också skicka en enda felsträng om du bara förväntar dig ett fel, vilket innebär att `errors='error message'` är detsamma som `errors=['error message']`.

SimpleTestCase.assertFormSetError(formset, form_index, field, errors, msg_prefix='')

  Säger att `formset` ger upphov till den angivna listan med fel när det renderas.

  `formset` är en instans av `FormSet`. Formsetet måste vara bundet men inte nödvändigtvis validerat (`assertFormSetError()` anropar automatiskt `full_clean()` på formsetet).

  `form_index` är numret på formuläret i `FormSet` (med början från 0). Använd `form_index=None` för att kontrollera formuläruppsättningens icke-formulärfel, dvs. de fel som du får när du anropar `formset.non_form_errors()`. I så fall måste du också använda `field=None`.

  `field` och `errors` har samma betydelse som parametrarna till `assertFormError()`.

SimpleTestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)

  Säger att en `response` producerade den givna `status_code` och att `text` finns i dess `content`. Om `count` anges måste `text` förekomma exakt `count` gånger i svaret.

  Sätt `html` till `True` för att hantera `text` som HTML. Jämförelsen med svarsinnehållet kommer att baseras på HTML-semantik i stället för likhet tecken för tecken. Whitespace ignoreras i de flesta fall, attributordning är inte signifikant. Se `assertHTMLEqual()` för mer information.

SimpleTestCase.assertNotContains(response, text, status_code=200, msg_prefix='', html=False)

  Säger att en `response` producerade den angivna `status_code` och att `text` inte förekommer i dess `content`.

  Sätt `html` till `True` för att hantera `text` som HTML. Jämförelsen med svarsinnehållet kommer att baseras på HTML-semantik i stället för likhet tecken för tecken. Whitespace ignoreras i de flesta fall, attributordning är inte signifikant. Se `assertHTMLEqual()` för mer information.

SimpleTestCase.assertTemplateUsed(response, template_name, msg_prefix='', count=None)

  Bekräftar att mallen med det angivna namnet användes vid rendering av svaret.

  `response` måste vara en svarsinstans som returneras av `test client`.

  `template_name` bör vara en sträng som till exempel `'admin/index.html'`.

  Argumentet `count` är ett heltal som anger hur många gånger mallen ska återges. Standard är `None`, vilket innebär att mallen ska återges en eller flera gånger.

  Du kan använda detta som en kontexthanterare, så här:

      with self.assertTemplateUsed("index.html"):
          render_to_string("index.html")
      with self.assertTemplateUsed(template_name="index.html"):
          render_to_string("index.html")

SimpleTestCase.assertTemplateNotUsed(response, template_name, msg_prefix='')

  Bekräftar att mallen med det angivna namnet inte användes vid rendering av svaret.

  Du kan använda detta som en kontexthanterare på samma sätt som `assertTemplateUsed()`.

SimpleTestCase.assertURLEqual(url1, url2, msg_prefix='')

  Påstår att två webbadresser är desamma och ignorerar ordningen på parametrarna i frågesträngen, utom för parametrar med samma namn. Till exempel är `/path/?x=1&y=2` lika med `/path/?y=2&x=1`, men `/path/?a=1&a=2` är inte lika med `/path/?a=2&a=1`.

SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='', fetch_redirect_response=True)

  Påstår att `response` returnerade en `status_code` omdirigeringsstatus, omdirigerades till `expected_url` (inklusive eventuella `GET` data), och att den slutliga sidan mottogs med `target_status_code`.

  Om din begäran använde argumentet `follow` kommer `expected_url` och `target_status_code` att vara webbadressen och statuskoden för den sista punkten i omdirigeringskedjan.

  Om `fetch_redirect_response` är `False` kommer den slutliga sidan inte att laddas. Eftersom testklienten inte kan hämta externa webbadresser är detta särskilt användbart om `expected_url` inte är en del av din Django-app.

  Schema hanteras korrekt när jämförelser görs mellan två webbadresser. Om det inte finns något schema angivet på den plats dit vi omdirigeras används den ursprungliga begärans schema. Om det finns, är det schemat i `expected_url` som används för att göra jämförelser.

SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)

  Påstår att strängarna `html1` och `html2` är lika. Jämförelsen är baserad på HTML-semantik. Jämförelsen tar hänsyn till följande saker:

  - Mellanslag före och efter HTML-taggar ignoreras.

  - Alla typer av blanksteg betraktas som likvärdiga.

  - Alla öppna taggar stängs implicit, t.ex. när en omgivande tagg stängs eller när HTML-dokumentet avslutas.

  - Tomma taggar är likvärdiga med deras självstängande version.

  - Ordningsföljden på attributen i ett HTML-element är inte viktig.

  - Booleska attribut (t.ex. `checked`) utan argument är lika med attribut som har samma namn och värde (se exemplen).

  - Text-, tecken- och entitetsreferenser som hänvisar till samma tecken är likvärdiga.

  Följande exempel är giltiga tester och ger inte upphov till några `AssertionError`:

      self.assertHTMLEqual(
          "<p>Hello <b>&#x27;world&#x27;!</p>",
          """<p>
              Hello   <b>&#39;world&#39;! </b>
          </p>""",
      )
      self.assertHTMLEqual(
          '<input type="checkbox" checked="checked" id="id_accept_terms" />',
          '<input id="id_accept_terms" type="checkbox" checked>',
      )

  `html1` och `html2` måste innehålla HTML. Ett `AssertionError` kommer att uppstå om en av dem inte kan tolkas.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

SimpleTestCase.assertHTMLNotEqual(html1, html2, msg=None)

  Påstår att strängarna `html1` och `html2` är inte lika. Jämförelsen baseras på HTML-semantik. Se `assertHTMLEqual()` för detaljer.

  `html1` och `html2` måste innehålla HTML. Ett `AssertionError` kommer att uppstå om en av dem inte kan tolkas.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

SimpleTestCase.assertXMLEqual(xml1, xml2, msg=None)

  Påstår att strängarna `xml1` och `xml2` är lika. Jämförelsen baseras på XML-semantik. På samma sätt som `assertHTMLEqual()`, görs jämförelsen på parsat innehåll, vilket innebär att endast semantiska skillnader beaktas, inte syntaxskillnader. När ogiltig XML skickas i någon parameter, uppstår alltid ett `AssertionError`, även om båda strängarna är identiska.

  XML-deklaration, dokumenttyp, bearbetningsinstruktioner och kommentarer ignoreras. Endast rotelementet och dess underordnade element jämförs.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

SimpleTestCase.assertXMLNotEqual(xml1, xml2, msg=None)

  Påstår att strängarna `xml1` och `xml2` är inte lika. Jämförelsen är baserad på XML-semantik. Se `assertXMLEqual()` för detaljer.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

SimpleTestCase.assertInHTML(needle, haystack, count=None, msg_prefix='')

  Påstår att HTML-fragmentet `needle` ingår i `haystack` en gång.

  Om heltalsargumentet `count` anges, kommer dessutom antalet förekomster av `nålar` att kontrolleras noggrant.

  I de flesta fall ignoreras blanksteg och attributordningen är inte signifikant. Se `assertHTMLEqual()` för mer information.

SimpleTestCase.assertNotInHTML(needle, haystack, msg_prefix='')

  Påstår att HTML-fragmentet `needle` inte ingår i `haystack`.

  I de flesta fall ignoreras blanksteg och attributordningen är inte signifikant. Se `assertHTMLEqual()` för mer information.

SimpleTestCase.assertJSONEqual(raw, expected_data, msg=None)

  Påstår att JSON-fragmenten `raw` och `expected_data` är lika. Vanliga JSON-regler för icke-signifikanta blanksteg gäller eftersom tungvikten är delegerad till `json`-biblioteket.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

SimpleTestCase.assertJSONNotEqual(raw, expected_data, msg=None)

  Säger att JSON-fragmenten `raw` och `expected_data` inte är lika. Se `assertJSONEqual()` för ytterligare detaljer.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

TransactionTestCase.assertQuerySetEqual(qs, values, transform=None, ordered=True, msg=None)

  Säger att en frågeuppsättning `qs` matchar en viss iterabel av värden `values`.

  Om `transform` anges, jämförs `values` med en lista som framställs genom att `transform` tillämpas på varje medlem i `qs`.

  Som standard är jämförelsen också beroende av ordning. Om `qs` inte tillhandahåller en implicit ordning kan du ställa in parametern `ordered` till `False`, vilket gör jämförelsen till en `collections.Counter` jämförelse. Om ordningen är odefinierad (om den givna `qs` inte är ordnad och jämförelsen är mot mer än ett ordnat värde), kommer ett `ValueError` att uppstå.

  Utdata i händelse av fel kan anpassas med argumentet `msg`.

TransactionTestCase.assertNumQueries(num, func, *args, **kwargs)

  Säger att när `func` anropas med `*args` och `**kwargs` så körs `num` databasfrågor.

  Om en `"using"`-nyckel finns i `kwargs` används den som databasalias för att kontrollera antalet frågor:

      self.assertNumQueries(7, my_function, using="non_default_db")

  Om du vill anropa en funktion med en `using` parameter kan du göra det genom att omsluta anropet med en `lambda` för att lägga till en extra parameter:

      self.assertNumQueries(7, lambda: my_function(using=7))

  Du kan också använda detta som en kontexthanterare:

      with self.assertNumQueries(2):
          Person.objects.create(name="Aaron")
          Person.objects.create(name="Daniel")

### Taggning av tester

Du kan märka dina tester så att du enkelt kan köra en viss delmängd. Du kan till exempel märka snabba eller långsamma tester:

    from django.test import tag

    class SampleTestCase(TestCase):
        @tag("fast")
        def test_fast(self): ...

        @tag("slow")
        def test_slow(self): ...

        @tag("slow", "core")
        def test_slow_but_core(self): ...

Du kan också tagga en testfallsklass:

    @tag("slow", "core")
    class SampleTestCase(TestCase): ...

Underklasser ärver taggar från överklasser och metoder ärver taggar från sin klass. Givet:

    @tag("foo")
    class SampleTestCaseChild(SampleTestCase):
        @tag("bar")
        def test(self): ...

`SampleTestCaseChild.test` kommer att märkas med `'slow'`, `'core'`, `'bar'` och `'foo'`.

Sedan kan du välja vilka tester som ska köras. Till exempel om du bara vill köra snabba tester:

/ 

    $ ./manage.py test --tag=fast

    ...\> manage.py test --tag=fast

Eller för att köra snabba tester och kärntesten (även om den är långsam):

/ 

    $ ./manage.py test --tag=fast --tag=core

    ...\> manage.py test --tag=fast --tag=core

Du kan också utesluta tester med hjälp av taggar. För att köra kärntester om de inte är långsamma:

/ 

    $ ./manage.py test --tag=core --exclude-tag=slow

    ...\> manage.py test --tag=core --exclude-tag=slow

`test --exclude-tag` har företräde framför `test --tag`, så om ett test har två taggar och du väljer en av dem och utesluter den andra, kommer testet inte att köras.

## Testning av asynkron kod

Om du bara vill testa utdata från dina asynkrona vyer kommer standardtestklienten att köra dem i sin egen asynkrona loop utan något extra arbete från din sida.

Men om du vill skriva helt asynkrona tester för ett Django-projekt måste du ta hänsyn till flera saker.

För det första måste dina tester vara `async def`-metoder på testklassen (för att ge dem ett asynkront sammanhang). Django kommer automatiskt att upptäcka alla `async def`-tester och linda in dem så att de körs i sin egen händelseslinga.

Om du testar från en asynkron funktion måste du också använda den asynkrona testklienten. Detta är tillgängligt som `django.test.AsyncClient`, eller som `self.async_client` på alla tester.

class AsyncClient(enforce_csrf_checks=False, raise_request_exception=True, *, headers=None, query_params=None, **defaults)

`AsyncClient` har samma metoder och signaturer som den synkrona (normala) testklienten, med följande undantag:

- Vid initialiseringen läggs godtyckliga nyckelordsargument i `defaults` till direkt i ASGI-scopet.

- Headers som skickas som `extra` nyckelordsargument bör inte ha prefixet `HTTP_` som krävs av den synkrona klienten (se `Client.get()`). Till exempel, så här ställer du in en HTTP `Accept` header:

      >>> c = AsyncClient()
      >>> c.get("/customers/details/", {"name": "fred", "age": 7}, ACCEPT="application/json")

Med hjälp av `AsyncClient` måste alla metoder som gör en begäran väntas:

    async def test_my_thing(self):
        response = await self.async_client.get("/some-url/")
        self.assertEqual(response.status_code, 200)

Den asynkrona klienten kan också anropa synkrona vyer; den körs genom Djangos asynkrona sökväg, som stöder båda. Varje vy som anropas via `AsyncClient` kommer att få ett `ASGIRequest`-objekt för sin `request` snarare än `WSGIRequest` som den normala klienten skapar.

Varning

Om du använder testdekoratorer måste de vara async-kompatibla för att säkerställa att de fungerar korrekt. Djangos inbyggda dekoratorer kommer att bete sig korrekt, men dekoratorer från tredje part kan verka som om de inte exekveras (de kommer att ”linda in” fel del av exekveringsflödet och inte ditt test).

Om du behöver använda dessa dekoratorer, bör du dekorera dina testmetoder med `async_to_sync()` inom dem istället:

    from asgiref.sync import async_to_sync
    from django.test import TestCase

    class MyTests(TestCase):
        @mock.patch(...)
        @async_to_sync
        async def test_my_thing(self): ...

## E-posttjänster

Om någon av dina Django-vyer skickar e-post med hjälp av Djangos e-postfunktionalitet, vill du förmodligen inte skicka e-post varje gång du kör ett test med den vyn. Av denna anledning omdirigerar Djangos testlöpare automatiskt all Django-skickad e-post till en dummy-utkorg. Detta gör att du kan testa alla aspekter av att skicka e-post - från antalet meddelanden som skickas till innehållet i varje meddelande - utan att faktiskt skicka meddelandena.

Testlöparen åstadkommer detta genom att transparent ersätta den normala e-postbackend med en testbackend. (Oroa dig inte - detta har ingen effekt på andra e-postavsändare utanför Django, till exempel din maskins e-postserver, om du kör en sådan)

django.core.mail.outbox

During test running, each outgoing email is saved in `django.core.mail.outbox`. This is a list of all `EmailMessage` instances that have been sent. The `outbox` attribute is a special attribute that is created only when the `locmem` email backend is used. It doesn’t normally exist as part of the `django.core.mail` module and you can’t import it directly. The code below shows how to access this attribute correctly.

Här är ett exempel på ett test som undersöker `django.core.mail.outbox` för längd och innehåll:

    from django.core import mail
    from django.test import TestCase

    class EmailTest(TestCase):
        def test_send_email(self):
            # Send message.
            mail.send_mail(
                "Subject here",
                "Here is the message.",
                "from@example.com",
                ["to@example.com"],
                fail_silently=False,
            )

            # Test that one message has been sent.
            self.assertEqual(len(mail.outbox), 1)

            # Verify that the subject of the first message is correct.
            self.assertEqual(mail.outbox[0].subject, "Subject here")

Som nämnts tidigare, töms testutkorgen i början av varje test i ett Django `*TestCase`. För att tömma utkorgen manuellt, tilldela den tomma listan till `mail.outbox`:

    from django.core import mail

    # Empty the test outbox
    mail.outbox = []

## Kommandon för hantering

Hanteringskommandon kan testas med funktionen `call_command()`. Utdata kan omdirigeras till en `StringIO`-instans:

    from io import StringIO
    from django.core.management import call_command
    from django.test import TestCase

    class ClosepollTest(TestCase):
        def test_command_output(self):
            out = StringIO()
            call_command("closepoll", poll_ids=[1], stdout=out)
            self.assertIn('Successfully closed poll "1"', out.getvalue())

## Skippa prov

Biblioteket unittest tillhandahåller dekoratorerna `@skipIf` och `@skipUnless` så att du kan hoppa över tester om du i förväg vet att dessa tester kommer att misslyckas under vissa förutsättningar.

Om ditt test till exempel kräver ett visst valfritt bibliotek för att lyckas, kan du dekorera testfallet med `@skipIf`. Då kommer testköraren att rapportera att testet inte kördes och varför, istället för att misslyckas med testet eller utelämna testet helt och hållet.

För att komplettera dessa testöverhoppningsbeteenden tillhandahåller Django ytterligare två skip-dekoratorer. Istället för att testa en generisk boolean, kontrollerar dessa dekoratorer databasens kapacitet och hoppar över testet om databasen inte stöder en specifik namngiven funktion.

Dekoratörerna använder en strängidentifierare för att beskriva databasfunktioner. Denna sträng motsvarar attribut i klassen för databasanslutningsfunktioner. Se django.db.backends.base.features.BaseDatabaseFeatures class för en fullständig lista över databasfunktioner som kan användas som grund för att hoppa över tester.

skipIfDBFeature(*feature_name_strings)

Hoppa över det dekorerade testet eller `TestCase` om alla de namngivna databasfunktionerna stöds.

Till exempel kommer följande test inte att utföras om databasen stöder transaktioner (t.ex. skulle det * inte * köras under PostgreSQL, men det skulle under MySQL med MyISAM-tabeller):

    class MyTests(TestCase):
        @skipIfDBFeature("supports_transactions")
        def test_transaction_behavior(self):
            # ... conditional test code
            pass

skipUnlessDBFeature(*feature_name_strings)

Hoppa över det dekorerade testet eller `TestCase` om någon av de namngivna databasfunktionerna inte stöds.

Till exempel kommer följande test endast att utföras om databasen stöder transaktioner (t.ex. skulle det köras under PostgreSQL, men * inte * under MySQL med MyISAM-tabeller):

    class MyTests(TestCase):
        @skipUnlessDBFeature("supports_transactions")
        def test_transaction_behavior(self):
            # ... conditional test code
            pass