Avancerade testämnen¶
Förfrågningsfabriken¶
Klassen:~django.test.RequestFactory delar samma API som testklienten. Men istället för att bete sig som en webbläsare ger RequestFactory ett sätt att generera en begärandeinstans som kan användas som det första argumentet för alla vyer. Detta innebär att du kan testa en vyfunktion på samma sätt som du skulle testa vilken annan funktion som helst - som en svart låda, med exakt kända ingångar, och testa för specifika utgångar.
API:et för RequestFactory
är en något begränsad delmängd av testklientens API:
Den har endast tillgång till HTTP-metoderna
get()
,post()
,put()
,delete()
,head()
,options()
ochtrace()
.Dessa metoder accepterar alla samma argument undantaget för
follow
. Eftersom detta bara är en fabrik för att producera förfrågningar är det upp till dig att hantera svaret.Den stöder inte middleware. Sessions- och autentiseringsattribut måste tillhandahållas av testet självt om det krävs för att vyn ska fungera korrekt.
Parametern query_params
har lagts till.
Exempel¶
Följande är ett enhetstest som använder request factory:
from django.contrib.auth.models import AnonymousUser, User
from django.test import RequestFactory, TestCase
from .views import MyView, my_view
class SimpleTest(TestCase):
def setUp(self):
# Every test needs access to the request factory.
self.factory = RequestFactory()
self.user = User.objects.create_user(
username="jacob", email="jacob@…", password="top_secret"
)
def test_details(self):
# Create an instance of a GET request.
request = self.factory.get("/customer/details")
# Recall that middleware are not supported. You can simulate a
# logged-in user by setting request.user manually.
request.user = self.user
# Or you can simulate an anonymous user by setting request.user to
# an AnonymousUser instance.
request.user = AnonymousUser()
# Test my_view() as if it were deployed at /customer/details
response = my_view(request)
# Use this syntax for class-based views.
response = MyView.as_view()(request)
self.assertEqual(response.status_code, 200)
AsyncRequestFactory¶
RequestFactory
skapar WSGI-liknande förfrågningar. Om du vill skapa ASGI-liknande förfrågningar, inklusive att ha ett korrekt ASGI scope
, kan du istället använda django.test.AsyncRequestFactory
.
Den här klassen är direkt API-kompatibel med RequestFactory
, med den enda skillnaden att den returnerar ASGIRequest
-instanser i stället för WSGIRequest
-instanser. Alla dess metoder är fortfarande synkrona callables.
Godtyckliga nyckelordsargument i defaults
läggs till direkt i ASGI-omfånget.
Parametern query_params
har lagts till.
Testning av klassbaserade vyer¶
För att kunna testa klassbaserade vyer utanför request/response-cykeln måste du se till att de är korrekt konfigurerade genom att anropa setup()
efter instantiering.
Anta till exempel följande klassbaserade vy:
Vyer.py
¶from django.views.generic import TemplateView
class HomeView(TemplateView):
template_name = "myapp/home.html"
def get_context_data(self, **kwargs):
kwargs["environment"] = "Production"
return super().get_context_data(**kwargs)
Du kan testa metoden get_context_data()
direkt genom att först instansiera vyn och sedan skicka en request
till setup()
, innan du fortsätter med testkoden:
tests.py
¶from django.test import RequestFactory, TestCase
from .views import HomeView
class HomePageTest(TestCase):
def test_environment_set_in_context(self):
request = RequestFactory().get("/")
view = HomeView()
view.setup(request)
context = view.get_context_data()
self.assertIn("environment", context)
Tester och flera värdnamn¶
Inställningen ALLOWED_HOSTS
valideras när tester körs. Detta gör att testklienten kan skilja mellan interna och externa webbadresser.
Projekt som stöder multitenancy eller på annat sätt ändrar affärslogik baserat på begärans värd och använder anpassade värdnamn i tester måste inkludera dessa värdar i ALLOWED_HOSTS
.
Det första alternativet är att lägga till värdarna i din inställningsfil. Till exempel innehåller testsviten för docs.djangoproject.com följande:
from django.test import TestCase
class SearchFormTestCase(TestCase):
def test_empty_get(self):
response = self.client.get(
"/en/dev/search/",
headers={"host": "docs.djangoproject.dev:8000"},
)
self.assertEqual(response.status_code, 200)
och inställningsfilen innehåller en lista över de domäner som stöds av projektet:
ALLOWED_HOSTS = ["www.djangoproject.dev", "docs.djangoproject.dev", ...]
Ett annat alternativ är att lägga till de värdar som krävs i ALLOWED_HOSTS
med override_settings()
eller modify_settings()
. Det här alternativet kan vara att föredra i fristående appar som inte kan paketera sin egen inställningsfil eller för projekt där listan över domäner inte är statisk (t.ex. underdomäner för multitenancy). Du kan t.ex. skriva ett test för domänen http://otherserver/
enligt följande:
from django.test import TestCase, override_settings
class MultiDomainTestCase(TestCase):
@override_settings(ALLOWED_HOSTS=["otherserver"])
def test_other_domain(self):
response = self.client.get("http://otherserver/foo/bar/")
Om du avaktiverar ALLOWED_HOSTS
-kontrollen (ALLOWED_HOSTS = ['*']
) när du kör tester förhindrar du att testklienten ger ett användbart felmeddelande om du följer en omdirigering till en extern URL.
Tester och flera databaser¶
Test av primär/replikakonfigurationer¶
Om du testar en konfiguration med flera databaser med replikering av primär/replika (kallas master/slave av vissa databaser), utgör denna strategi för att skapa testdatabaser ett problem. När testdatabaserna skapas kommer det inte att finnas någon replikering, och som ett resultat kommer data som skapats på den primära inte att ses på repliken.
För att kompensera för detta tillåter Django dig att definiera att en databas är en testspegel. Tänk på följande (förenklade) exempel på databaskonfiguration:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "myproject",
"HOST": "dbprimary",
# ... plus some other settings
},
"replica": {
"ENGINE": "django.db.backends.mysql",
"NAME": "myproject",
"HOST": "dbreplica",
"TEST": {
"MIRROR": "default",
},
# ... plus some other settings
},
}
I den här installationen har vi två databasservrar: dbprimary
, som beskrivs av databasaliaset default
, och dbreplica
som beskrivs av aliaset replica
. Som du kanske förväntar dig har dbreplica
konfigurerats av databasadministratören som en läskopia av dbprimary
, så under normal aktivitet kommer alla skrivningar till default
att visas på replica
.
Om Django skapade två oberoende testdatabaser skulle detta bryta alla tester som förväntade sig att replikering skulle ske. Databasen replica
har dock konfigurerats som en testspegel (med hjälp av testinställningen MIRROR
), vilket indikerar att replica
under testning bör behandlas som en spegel av default
.
När testmiljön är konfigurerad kommer en testversion av replica
inte att skapas. Istället kommer anslutningen till replica
att omdirigeras så att den pekar på default
. Som ett resultat kommer skrivningar till default
att visas på replica
- men eftersom de faktiskt är samma databas, inte för att det finns datareplikering mellan de två databaserna. Eftersom detta är beroende av transaktioner måste testerna använda TransactionTestCase
istället för TestCase
.
Kontroll av skapandeordning för testdatabaser¶
Som standard kommer Django att anta att alla databaser är beroende av default
-databasen och därför alltid skapa default
-databasen först. Det finns dock inga garantier för i vilken ordning andra databaser i din testkonfiguration skapas.
Om din databaskonfiguration kräver en viss skapandeordning kan du ange vilka beroenden som finns med hjälp av testinställningen DEPENDENCIES
. Tänk på följande (förenklade) exempel på databaskonfiguration:
DATABASES = {
"default": {
# ... db settings
"TEST": {
"DEPENDENCIES": ["diamonds"],
},
},
"diamonds": {
# ... db settings
"TEST": {
"DEPENDENCIES": [],
},
},
"clubs": {
# ... db settings
"TEST": {
"DEPENDENCIES": ["diamonds"],
},
},
"spades": {
# ... db settings
"TEST": {
"DEPENDENCIES": ["diamonds", "hearts"],
},
},
"hearts": {
# ... db settings
"TEST": {
"DEPENDENCIES": ["diamonds", "clubs"],
},
},
}
I den här konfigurationen kommer databasen diamonds
att skapas först, eftersom det är det enda databasaliaset utan beroenden. Aliasen default
och clubs
skapas därefter (även om ordningen för skapandet av detta par inte är garanterad), sedan hearts
och slutligen spades
.
Om det finns några cirkulära beroenden i DEPENDENCIES
-definitionen, kommer ett ImproperlyConfigured
-undantag att uppstå.
Avancerade funktioner i TransactionTestCase
¶
- TransactionTestCase.available_apps¶
Varning
Detta attribut är ett privat API. Det kan komma att ändras eller tas bort i framtiden utan en avvecklingsperiod, t.ex. för att tillgodose förändringar i applikationsladdning.
Den används för att optimera Djangos egen testsvit, som innehåller hundratals modeller men inga relationer mellan modeller i olika applikationer.
Som standard är
available_apps
inställd påNone
. Efter varje test anropar Djangoflush
för att återställa databastillståndet. Detta tömmer alla tabeller och sänder utpost_migrate
-signalen, som återskapar en innehållstyp och fyra behörigheter för varje modell. Denna operation blir dyr proportionellt mot antalet modeller.Om du ställer in
available_apps
till en lista över applikationer instrueras Django att bete sig som om endast modellerna från dessa applikationer var tillgängliga. Beteendet förTransactionTestCase
ändras enligt följande:post_migrate
avfyras före varje test för att skapa innehållstyper och behörigheter för varje modell i tillgängliga appar, ifall de saknas.Efter varje test tömmer Django endast tabeller som motsvarar modeller i tillgängliga appar. På databasnivå kan trunkering dock kaskadera till relaterade modeller i otillgängliga appar. Dessutom
post_migrate
avfyras inte; det kommer att avfyras av nästaTransactionTestCase
, efter att rätt uppsättning applikationer har valts.
Eftersom databasen inte är helt tömd, om ett test skapar instanser av modeller som inte ingår i
available_apps
, kommer de att läcka och de kan orsaka att orelaterade tester misslyckas. Var försiktig med tester som använder sessioner; standardsessionsmotorn lagrar dem i databasen.Eftersom
post_migrate
inte skickas ut efter rensning av databasen, är dess tillstånd efter ettTransactionTestCase
inte detsamma som efter ettTestCase
: det saknar de rader som skapats av lyssnare tillpost_migrate
. Med tanke på ordningen i vilken tester utförs är detta inte ett problem, förutsatt att antingen allaTransactionTestCase
i en given testsvit deklareraravailable_apps
, eller ingen av dem.available_apps
är obligatoriskt i Djangos egen testsvit.
- TransactionTestCase.reset_sequences¶
Om du ställer in
reset_sequences = True
på ettTransactionTestCase
ser du till att sekvenserna alltid återställs innan testet körs:class TestsThatDependsOnPrimaryKeySequences(TransactionTestCase): reset_sequences = True def test_animal_pk(self): lion = Animal.objects.create(name="lion", sound="roar") # lion.pk is guaranteed to always be 1 self.assertEqual(lion.pk, 1)
Om du inte uttryckligen testar sekvensnummer för primärnycklar rekommenderas det att du inte hårdkodar värden för primärnycklar i tester.
Om du använder
reset_sequences = True
kommer testet att gå långsammare, eftersom återställningen av primärnyckeln är en relativt dyr databasoperation.
Genomför sekventiell körning av testklasser¶
Om du har testklasser som inte kan köras parallellt (t.ex. för att de delar en gemensam resurs) kan du använda django.test.testcases.SerializeMixin
för att köra dem sekventiellt. Denna mixin använder ett filsystem lockfile
.
Du kan t.ex. använda __file__
för att bestämma att alla testklasser i samma fil som ärver från SerializeMixin
ska köras sekventiellt:
import os
from django.test import TestCase
from django.test.testcases import SerializeMixin
class ImageTestCaseMixin(SerializeMixin):
lockfile = __file__
def setUp(self):
self.filename = os.path.join(temp_storage_dir, "my_file.png")
self.file = create_file(self.filename)
class RemoveImageTests(ImageTestCaseMixin, TestCase):
def test_remove_image(self):
os.remove(self.filename)
self.assertFalse(os.path.exists(self.filename))
class ResizeImageTests(ImageTestCaseMixin, TestCase):
def test_resize_image(self):
resize_image(self.file, (48, 48))
self.assertEqual(get_image_size(self.file), (48, 48))
Använda Django Test Runner för att testa återanvändbara applikationer¶
Om du skriver en återanvändbar applikation kanske du vill använda Django test runner för att köra din egen testsvit och därmed dra nytta av Djangos testinfrastruktur.
En vanlig metod är en tests-katalog bredvid applikationskoden, med följande struktur:
runtests.py
polls/
__init__.py
models.py
...
tests/
__init__.py
models.py
test_settings.py
tests.py
Låt oss ta en titt på några av dessa filer:
runtests.py
¶#!/usr/bin/env python
import os
import sys
import django
from django.conf import settings
from django.test.utils import get_runner
if __name__ == "__main__":
os.environ["DJANGO_SETTINGS_MODULE"] = "tests.test_settings"
django.setup()
TestRunner = get_runner(settings)
test_runner = TestRunner()
failures = test_runner.run_tests(["tests"])
sys.exit(bool(failures))
Detta är det skript som du anropar för att köra testsviten. Det ställer in Django-miljön, skapar testdatabasen och kör testerna.
För tydlighetens skull innehåller detta exempel endast det absolut nödvändiga för att använda Djangos testlöpare. Du kanske vill lägga till kommandoradsalternativ för att kontrollera ordrikedom, skicka in specifika testetiketter som ska köras etc.
tester/tester_settings.py
¶SECRET_KEY = "fake-key"
INSTALLED_APPS = [
"tests",
]
Den här filen innehåller de Django-inställningar som krävs för att köra appens tester.
Även detta är ett minimalt exempel; dina tester kan kräva ytterligare inställningar för att köras.
Eftersom paketet tests ingår i INSTALLED_APPS
när du kör dina tester, kan du definiera modeller som endast gäller tester i dess fil models.py
.
Användning av olika testramverk¶
Det är uppenbart att unittest
inte är det enda testramverket i Python. Även om Django inte ger uttryckligt stöd för alternativa ramverk, ger det ett sätt att anropa tester som är konstruerade för ett alternativt ramverk som om de vore vanliga Django-tester.
När du kör ./manage.py test
tittar Django på inställningen TEST_RUNNER
för att avgöra vad som ska göras. Som standard pekar TEST_RUNNER
på 'django.test.runner.DiscoverRunner'
. Den här klassen definierar Djangos standardtestbeteende. Detta beteende innebär:
Utföra global förtestinställning.
Letar efter tester i alla filer under den aktuella katalogen vars namn matchar mönstret
test*.py
.Skapa testdatabaserna.
Kör
migrate
för att installera modeller och initialdata i testdatabaserna.Kör systemkontroller.
Kör de tester som hittades.
Förstöring av testdatabaserna.
Utföra global nedmontering efter test.
Om du definierar din egen testlöparklass och pekar TEST_RUNNER
på den klassen, kommer Django att köra din testlöpare när du kör ./manage.py test
. På så sätt är det möjligt att använda valfritt testramverk som kan köras från Python-kod, eller att modifiera Djangos testkörningsprocess för att uppfylla de testkrav du kan ha.
Definiera en testlöpare¶
En testlöpare är en klass som definierar en metod run_tests()
. Django levereras med en DiscoverRunner
-klass som definierar standardtestbeteendet för Django. Denna klass definierar ingångspunkten run_tests()
, plus ett urval av andra metoder som används av run_tests()
för att ställa in, köra och riva ner testsviten.
- class DiscoverRunner(pattern='test*.py', top_level=None, verbosity=1, interactive=True, failfast=False, keepdb=False, reverse=False, debug_mode=False, debug_sql=False, parallel=0, tags=None, exclude_tags=None, test_name_patterns=None, pdb=False, buffer=False, enable_faulthandler=True, timing=True, shuffle=False, logger=None, durations=None, **kwargs)[source]¶
DiscoverRunner
kommer att söka efter tester i alla filer som matcharmönstret
.top_level
kan användas för att ange den katalog som innehåller dina Python-moduler på högsta nivå. Vanligtvis kan Django räkna ut detta automatiskt, så det är inte nödvändigt att ange detta alternativ. Om det anges bör det i allmänhet vara den katalog som innehåller dinmanage.py
-fil.verbosity
bestämmer hur mycket meddelande- och felsökningsinformation som ska skrivas ut till konsolen;0
är ingen utdata,1
är normal utdata och2
är verbose utdata.Om
interactive
ärTrue
har testsviten behörighet att be användaren om instruktioner när testsviten körs. Ett exempel på detta beteende är att be om tillstånd att ta bort en befintlig testdatabas. Ominteractive
ärFalse
måste testsviten kunna köras utan någon manuell inblandning.Om
failfast
ärTrue
kommer testsviten att sluta köras efter att det första testfelet har upptäckts.Om
keepdb
ärTrue
kommer testsviten att använda den befintliga databasen, eller skapa en om det behövs. OmFalse
kommer en ny databas att skapas och användaren uppmanas att ta bort den befintliga databasen, om en sådan finns.Om
reverse
ärTrue
kommer testfallen att exekveras i motsatt ordning. Detta kan vara användbart för att felsöka tester som inte är ordentligt isolerade och som har bieffekter. Gruppering efter testklass bevaras när detta alternativ används. Det här alternativet kan användas tillsammans med--shuffle
för att vända ordningen för ett visst slumpmässigt frö.debug_mode
anger vad inställningenDEBUG
ska vara inställd på innan tester körs.parallel
anger antalet processer. Omparallel
är större än1
kommer testsviten att köras iparallella
processer. Om det finns färre testfallsklasser än konfigurerade processer, kommer Django att minska antalet processer i enlighet med detta. Varje process får sin egen databas. Detta alternativ kräver tredjepartstblib
-paketet för att visa spårningar korrekt.tags
kan användas för att ange en uppsättning tags för filtrering av tester. Kan kombineras medexclude_tags
.exclude_tags
kan användas för att ange en uppsättning taggar för att utesluta tester. Kan kombineras medtags
.Om
debug_sql
ärTrue
, kommer misslyckade testfall att mata ut SQL-frågor som loggas till django.db.backends logger samt spårningen. Omverbosity
är2
, kommer frågor i alla tester att matas ut.test_name_patterns
kan användas för att ange en uppsättning mönster för att filtrera testmetoder och klasser efter deras namn.Om
pdb
ärTrue
kommer en debugger (pdb
elleripdb
) att startas vid varje fel eller misslyckande i testet.Om
buffer
ärTrue
, kommer utdata från godkända tester att kasseras.Om
enable_faulthandler
ärTrue
, kommerfaulthandler
att aktiveras.Om
timing
ärTrue
visas testtider, inklusive databasinstallation och total körtid.Om
shuffle
är ett heltal kommer testfallen att blandas i en slumpmässig ordning före exekvering, med heltalet som slumpmässigt frö. Omshuffle
ärNone
kommer fröet att genereras slumpmässigt. I båda fallen kommer fröet att loggas och sättas tillself.shuffle_seed
innan testerna körs. Detta alternativ kan användas för att hjälpa till att upptäcka tester som inte är ordentligt isolerade. :ref:Gruppering efter testklass <order-of-tests>
bevaras när detta alternativ används.logger
kan användas för att skicka ett Python Logger-objekt. Om det anges kommer loggern att användas för att logga meddelanden istället för att skriva ut dem till konsolen. Logger-objektet kommer att respektera sin loggningsnivå snarare änverbosity
.durations
kommer att visa en lista över de N långsammaste testfallen. Om du ställer in detta alternativ på0
kommer varaktigheten för alla tester att visas. Kräver Python 3.12+.Django kan, från tid till annan, utöka testlöparens möjligheter genom att lägga till nya argument. Deklarationen
**kwargs
tillåter denna expansion. Om du underklassarDiscoverRunner
eller skriver din egen testlöpare, se till att den accepterar**kwargs
.Din testlöpare kan också definiera ytterligare kommandoradsalternativ. Skapa eller åsidosätt en klassmetod
add_arguments(cls, parser)
och lägg till anpassade argument genom att anropaparser.add_argument()
inuti metoden, så att kommandottest
kan använda dessa argument.
Attribut¶
- DiscoverRunner.test_suite¶
Den klass som används för att bygga testsviten. Som standard är den inställd på
unittest.TestSuite
. Detta kan åsidosättas om du vill implementera en annan logik för att samla in tester.
- DiscoverRunner.test_runner¶
Detta är klassen för den testlöpare på låg nivå som används för att köra de enskilda testerna och formatera resultaten. Som standard är den inställd på
unittest.TextTestRunner
. Trots den olyckliga likheten i namngivningskonventioner är detta inte samma typ av klass somDiscoverRunner
, som täcker en bredare uppsättning ansvarsområden. Du kan åsidosätta detta attribut för att ändra hur tester körs och rapporteras.
- DiscoverRunner.test_loader¶
Det här är klassen som laddar tester, oavsett om det är från TestCases eller moduler eller på annat sätt, och buntar ihop dem till testsviter som köraren kan köra. Som standard är den inställd på
unittest.defaultTestLoader
. Du kan åsidosätta detta attribut om dina tester kommer att laddas på ovanliga sätt.
Metoder¶
- DiscoverRunner.run_tests(test_labels, **kwargs)[source]¶
Kör testsviten.
med
test_labels
kan du ange vilka tester som ska köras och det finns stöd för flera format (seDiscoverRunner.build_suite()
för en lista över format som stöds).Denna metod bör returnera antalet tester som misslyckades.
- classmethod DiscoverRunner.add_arguments(parser)[source]¶
Åsidosätt denna klassmetod för att lägga till anpassade argument som accepteras av hanteringskommandot
test
. Seargparse.ArgumentParser.add_argument()
för information om hur du lägger till argument till en parser.
- DiscoverRunner.setup_test_environment(**kwargs)[source]¶
Ställer in testmiljön genom att anropa
setup_test_environment()
och ställa inDEBUG
tillself.debug_mode
(standard ärFalse
).
- DiscoverRunner.build_suite(test_labels=None, **kwargs)[source]¶
Konstruerar en testsvit som matchar de testetiketter som anges.
test_labels
är en lista med strängar som beskriver de tester som ska köras. En testetikett kan ha en av fyra former:path.to.test_module.TestCase.test_method
– Kör en enda testmetod i en testfallsklass.path.to.test_module.TestCase
– Kör alla testmetoder i ett testfall.path.to.module
– Söker efter och kör alla tester i det angivna Python-paketet eller -modulen.path/to/directory
– Sök efter och kör alla tester under den angivna katalogen.
Om
test_labels
har värdetNone
kommer testlöparen att söka efter tester i alla filer under den aktuella katalogen vars namn matchar dessmönster
(se ovan).Returnerar en instans av
TestSuite
som är redo att köras.
- DiscoverRunner.setup_databases(**kwargs)[source]¶
Skapar testdatabaserna genom att anropa
setup_databases()
.
- DiscoverRunner.run_checks(databases)[source]¶
Kör systemkontroller på testets
databaser
.
- DiscoverRunner.run_suite(suite, **kwargs)[source]¶
Kör testsviten.
Returnerar resultatet av körningen av testsviten.
- DiscoverRunner.get_test_runner_kwargs()[source]¶
Returnerar nyckelordsargumenten för att instansiera
DiscoverRunner.test_runner
med.
- DiscoverRunner.teardown_databases(old_config, **kwargs)[source]¶
Förstör testdatabaserna och återställer villkoren före testet genom att anropa
teardown_databases()
.
- DiscoverRunner.suite_result(suite, result, **kwargs)[source]¶
Beräknar och returnerar en returkod baserad på en testsvit och resultatet från denna testsvit.
- DiscoverRunner.log(msg, level=None)[source]¶
Om en
logger
är inställd, loggas meddelandet på den angivna heltalsnivån för loggning (t.ex.logging.DEBUG
,logging.INFO
ellerlogging.WARNING
). Annars skrivs meddelandet ut till konsolen, med hänsyn till den aktuellaverbosity
. Exempelvis skrivs inget meddelande ut omverbosity
är 0,INFO
och högre skrivs ut omverbosity
är minst 1 ochDEBUG
skrivs ut om den är minst 2. Standardvärdet förlevel
ärlogging.INFO
.
Test av verktyg¶
django.test.utils
¶
För att hjälpa till att skapa din egen testlöpare tillhandahåller Django ett antal verktygsmetoder i modulen django.test.utils
.
- setup_test_environment(debug=None)[source]¶
Utför globala inställningar före test, t.ex. installation av instrument för mallrenderingssystemet och konfigurering av dummy-utkorgen för e-post.
Om
debug
inte ärNone
, uppdaterasDEBUG
-inställningen till dess värde.
- teardown_test_environment()[source]¶
Utför global nedmontering efter test, t.ex. avlägsnande av instrument från mallsystemet och återställning av normala e-posttjänster.
- setup_databases(verbosity, interactive, *, time_keeper=None, keepdb=False, debug_sql=False, parallel=0, aliases=None, serialized_aliases=None, **kwargs)[source]¶
Skapar testdatabaserna.
Returnerar en datastruktur som innehåller tillräckligt med detaljer för att ångra de ändringar som har gjorts. Dessa data kommer att tillhandahållas till
teardown_databases()
-funktionen när testningen är avslutad.Argumentet
aliases
bestämmer vilkaDATABASES
-alias som testdatabaserna ska konfigureras för. Om det inte anges, är standardvärdet allaDATABASES
alias.Argumentet
serialized_aliases
bestämmer vilken delmängd avaliases
testdatabaser som ska ha sitt tillstånd serialiserat för att möjliggöra användning av funktionen serialized_rollback. Om det inte anges är standardvärdetaliases
.
- teardown_databases(old_config, parallel=0, keepdb=False)[source]¶
Förstör testdatabaserna och återställer förhållandena före testet.
old_config
är en datastruktur som definierar de ändringar i databaskonfigurationen som måste återställas. Det är returvärdet för metodensetup_databases()
.
django.db.connection.creation
¶
Skapandemodulen för databasens backend innehåller också några verktyg som kan vara användbara under testning.
- create_test_db(verbosity=1, autoclobber=False, serialize=True, keepdb=False)¶
Skapar en ny testdatabas och kör
migrate
mot den.verbosity
har samma beteende som irun_tests()
.autoclobber
beskriver det beteende som kommer att uppstå om en databas med samma namn som testdatabasen upptäcks:Om
autoclobber
ärFalse
kommer användaren att bli ombedd att godkänna att den befintliga databasen förstörs.`sys.exit
anropas om användaren inte godkänner detta.Om
autoclobber
ärTrue
kommer databasen att förstöras utan att användaren tillfrågas.
serialize
avgör om Django serialiserar databasen till en JSON-sträng i minnet innan tester körs (används för att återställa databasens tillstånd mellan tester om du inte har transaktioner). Du kan ställa in detta tillFalse
för att påskynda skapandetiden om du inte har några testklasser med serialized_rollback=True.keepdb
avgör om testkörningen ska använda en befintlig databas eller skapa en ny. OmTrue
används den befintliga databasen, eller skapas om den inte finns. OmFalse
skapas en ny databas och användaren uppmanas att ta bort den befintliga databasen, om en sådan finns.Returnerar namnet på den testdatabas som skapades.
create_test_db()
har som bieffekt att värdet förNAME
iDATABASES
ändras så att det motsvarar namnet på testdatabasen.
- destroy_test_db(old_database_name, verbosity=1, keepdb=False)¶
Förstör databasen vars namn är värdet för
NAME
iDATABASES
och anger värdet förold_database_name
iNAME
.Argumentet
verbosity
har samma beteende som förDiscoverRunner
.Om argumentet
keepdb
ärTrue
kommer anslutningen till databasen att stängas, men databasen kommer inte att förstöras.
- serialize_db_to_string()¶
Serialiserar databasen till en JSON-sträng i minnet som kan användas för att återställa databastillståndet mellan tester om backend inte stöder transaktioner eller om din svit innehåller testklasser med serialized_rollback=True aktiverat.
Denna funktion bör endast anropas när alla testdatabaser har skapats eftersom serialiseringsprocessen kan resultera i frågor mot databaser som inte är testdatabaser beroende på din routingkonfiguration.
Integration med coverage.py
¶
Kodtäckning beskriver hur mycket av källkoden som har testats. Den visar vilka delar av din kod som testas och vilka som inte gör det. Det är en viktig del av testningen av applikationer, så det rekommenderas starkt att du kontrollerar täckningen av dina tester.
Django kan enkelt integreras med coverage.py, ett verktyg för att mäta kodtäckning av Python-program. Först installerar du coverage. Därefter kör du följande från din projektmapp som innehåller manage.py
:
coverage run --source='.' manage.py test myapp
Detta kör dina tester och samlar in täckningsdata för de exekverade filerna i ditt projekt. Du kan se en rapport över dessa data genom att skriva följande kommando:
coverage report
Observera att en del Django-kod exekverades när testerna kördes, men den listas inte här på grund av flaggan source
som skickades till föregående kommando.
För fler alternativ, t.ex. kommenterade HTML-listor med information om missade rader, se dokumenten för coverage.py.