Padziļināta informācija par Django testēšanas sistēmu, salīdzinot un kontrastējot TestCase un TransactionTestCase, lai palīdzētu jums rakstīt efektīvākus un uzticamākus testus.
Python Django testēšana: TestCase vs. TransactionTestCase
Testēšana ir būtiska programmatūras izstrādes sastāvdaļa, kas nodrošina, ka jūsu lietojumprogramma darbojas, kā paredzēts, un laika gaitā paliek stabila. Django, populārs Python tīmekļa ietvars, nodrošina jaudīgu testēšanas ietvaru, lai palīdzētu jums rakstīt efektīvus testus. Šis emuāra ieraksts iedziļinās divās pamatklasēs Django testēšanas ietvarā: TestCase
un TransactionTestCase
. Mēs izpētīsim to atšķirības, lietošanas gadījumus un sniegsim praktiskus piemērus, lai palīdzētu jums izvēlēties pareizo klasi jūsu testēšanas vajadzībām.
Kāpēc testēšana ir svarīga programmā Django
Pirms iedziļināties TestCase
un TransactionTestCase
specifikā, īsi apspriedīsim, kāpēc testēšana ir tik svarīga programmā Django izstrādē:
- Nodrošina koda kvalitāti: Testi palīdz agrīni izķert kļūdas izstrādes procesā, neļaujot tām nonākt ražošanā.
- Atvieglo refaktorēšanu: Ar visaptverošu testu komplektu jūs varat pārliecinoši refaktorēt savu kodu, zinot, ka testi jūs brīdinās, ja ieviesīsiet kādas regresijas.
- Uzlabo sadarbību: Labi uzrakstīti testi kalpo kā jūsu koda dokumentācija, atvieglojot citiem izstrādātājiem to saprast un veicināt.
- Atbalsta testēšanas vadītu izstrādi (TDD): TDD ir izstrādes pieeja, kurā jūs rakstāt testus pirms faktiskā koda rakstīšanas. Tas liek jums iepriekš domāt par vēlamo jūsu lietojumprogrammas darbību, kā rezultātā iegūst tīrāku un vieglāk uzturamu kodu.
Django testēšanas ietvars: īss pārskats
Django testēšanas ietvars ir veidots, pamatojoties uz Python iebūvēto unittest
moduli. Tas nodrošina vairākas funkcijas, kas atvieglo Django lietojumprogrammu testēšanu, tostarp:
- Testu atklāšana: Django automātiski atklāj un palaiž testus jūsu projektā.
- Testu rīks: Django nodrošina testu rīku, kas izpilda jūsu testus un ziņo rezultātus.
- Apgalvojumu metodes: Django nodrošina apgalvojumu metožu kopu, ko varat izmantot, lai pārbaudītu paredzamo jūsu koda darbību.
- Klients: Django testu klients ļauj jums simulēt lietotāju mijiedarbību ar jūsu lietojumprogrammu, piemēram, iesniedzot veidlapas vai veicot API pieprasījumus.
- TestCase un TransactionTestCase: Tās ir divas pamatklases testu rakstīšanai programmā Django, kuras mēs izpētīsim detalizēti.
TestCase: ātra un efektīva vienību testēšana
TestCase
ir primārā klase vienību testu rakstīšanai programmā Django. Tā nodrošina tīru datu bāzes vidi katram testa gadījumam, nodrošinot, ka testi ir izolēti un neiejaucas viens otrā.
Kā darbojas TestCase
Kad izmantojat TestCase
, Django veic šādas darbības katrai testa metodei:
- Izveido testa datu bāzi: Django izveido atsevišķu testa datu bāzi katrai testa palaišanai.
- Iztīra datu bāzi: Pirms katras testa metodes Django iztīra testa datu bāzi, noņemot visus esošos datus.
- Palaiž testa metodi: Django izpilda definēto testa metodi.
- Atceļ transakciju: Pēc katras testa metodes Django atceļ transakciju, efektīvi atceļot visas izmaiņas, kas veiktas datu bāzē testa laikā.
Šī pieeja nodrošina, ka katra testa metode sākas ar tīru lapu un ka visas izmaiņas, kas veiktas datu bāzē, tiek automātiski atceltas. Tas padara TestCase
ideālu vienību testēšanai, kur vēlaties testēt atsevišķus savas lietojumprogrammas komponentus izolēti.
Piemērs: vienkārša modeļa testēšana
Apskatīsim vienkāršu piemēru, kā testēt Django modeli, izmantojot TestCase
:
from django.test import TestCase
from .models import Product
class ProductModelTest(TestCase):
def test_product_creation(self):
product = Product.objects.create(name="Test Product", price=10.00)
self.assertEqual(product.name, "Test Product")
self.assertEqual(product.price, 10.00)
self.assertTrue(isinstance(product, Product))
Šajā piemērā mēs testējam Product
modeļa instances izveidi. Metode test_product_creation
izveido jaunu produktu un pēc tam izmanto apgalvojumu metodes, lai pārbaudītu, vai produkta atribūti ir iestatīti pareizi.
Kad izmantot TestCase
TestCase
parasti ir vēlamā izvēle lielākajai daļai Django testēšanas scenāriju. Tas ir ātrs, efektīvs un nodrošina tīru datu bāzes vidi katram testam. Izmantojiet TestCase
, ja:
- Jūs testējat atsevišķus modeļus, skatus vai citus savas lietojumprogrammas komponentus.
- Vēlaties nodrošināt, ka jūsu testi ir izolēti un neiejaucas viens otrā.
- Jums nav nepieciešams testēt sarežģītas datu bāzes mijiedarbības, kas aptver vairākas transakcijas.
TransactionTestCase: sarežģītu datu bāzes mijiedarbību testēšana
TransactionTestCase
ir vēl viena klase testu rakstīšanai programmā Django, taču tā atšķiras no TestCase
ar to, kā tā apstrādā datu bāzes transakcijas. Tā vietā, lai atceltu transakciju pēc katras testa metodes, TransactionTestCase
apstiprina transakciju. Tas padara to piemērotu sarežģītu datu bāzes mijiedarbību testēšanai, kas aptver vairākas transakcijas, piemēram, tās, kas saistītas ar signāliem vai atomiskām transakcijām.
Kā darbojas TransactionTestCase
Kad izmantojat TransactionTestCase
, Django veic šādas darbības katram testa gadījumam:
- Izveido testa datu bāzi: Django izveido atsevišķu testa datu bāzi katrai testa palaišanai.
- NEiztīra datu bāzi: TransactionTestCase *automātiski ne*iztīra datu bāzi pirms katra testa. Tā sagaida, ka datu bāze pirms katra testa palaišanas būs konsekventā stāvoklī.
- Palaiž testa metodi: Django izpilda definēto testa metodi.
- Apstiprina transakciju: Pēc katras testa metodes Django apstiprina transakciju, padarot izmaiņas pastāvīgas testa datu bāzē.
- Saīsina tabulas: Visu testu
TransactionTestCase
*beigās* tabulas tiek saīsinātas, lai notīrītu datus.
Tā kā TransactionTestCase
apstiprina transakciju pēc katras testa metodes, ir būtiski nodrošināt, ka jūsu testi neatstāj datu bāzi nekonsekventā stāvoklī. Iespējams, būs manuāli jānotīra visi dati, kas izveidoti testa laikā, lai izvairītos no iejaukšanās turpmākajos testos.
Piemērs: signālu testēšana
Apskatīsim piemēru, kā testēt Django signālus, izmantojot TransactionTestCase
:
from django.test import TransactionTestCase
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Product, ProductLog
@receiver(post_save, sender=Product)
def create_product_log(sender, instance, created, **kwargs):
if created:
ProductLog.objects.create(product=instance, action="Created")
class ProductSignalTest(TransactionTestCase):
def test_product_creation_signal(self):
product = Product.objects.create(name="Test Product", price=10.00)
self.assertEqual(ProductLog.objects.count(), 1)
self.assertEqual(ProductLog.objects.first().product, product)
self.assertEqual(ProductLog.objects.first().action, "Created")
Šajā piemērā mēs testējam signālu, kas izveido ProductLog
instanci ikreiz, kad tiek izveidota jauna Product
instance. Metode test_product_creation_signal
izveido jaunu produktu un pēc tam pārbauda, vai ir izveidots atbilstošs produktu žurnāla ieraksts.
Kad izmantot TransactionTestCase
TransactionTestCase
parasti izmanto noteiktos scenārijos, kad jums ir jātestē sarežģītas datu bāzes mijiedarbības, kas aptver vairākas transakcijas. Apsveriet iespēju izmantot TransactionTestCase
, ja:
- Jūs testējat signālus, kurus aktivizē datu bāzes operācijas.
- Jūs testējat atomiskās transakcijas, kas ietver vairākas datu bāzes operācijas.
- Jums ir jāpārbauda datu bāzes stāvoklis pēc virknes saistītu operāciju.
- Jūs izmantojat kodu, kas paļaujas uz automātiski palielināmo ID, lai saglabātos starp testiem (lai gan tas parasti tiek uzskatīts par sliktu praksi).
Svarīgi apsvērumi, lietojot TransactionTestCase
Tā kā TransactionTestCase
apstiprina transakcijas, ir svarīgi apzināties šādus apsvērumus:
- Datu bāzes tīrīšana: Iespējams, būs manuāli jānotīra visi dati, kas izveidoti testa laikā, lai izvairītos no iejaukšanās turpmākajos testos. Apsveriet iespēju izmantot metodes
setUp
untearDown
, lai pārvaldītu testa datus. - Testa izolācija:
TransactionTestCase
nenodrošina tādu pašu testu izolācijas līmeni kāTestCase
. Ņemiet vērā potenciālo mijiedarbību starp testiem un pārliecinieties, ka jūsu testi nepaļaujas uz datu bāzes stāvokli no iepriekšējiem testiem. - Veiktspēja:
TransactionTestCase
var būt lēnāks nekāTestCase
, jo tas ietver transakciju apstiprināšanu. Izmantojiet to saprātīgi un tikai tad, kad nepieciešams.
Labākā prakse Django testēšanai
Šeit ir dažas labākās prakses, kas jāatceras, rakstot testus programmā Django:
- Rakstiet skaidrus un kodolīgus testus: Testiem jābūt viegli saprotamiem un uzturamiem. Izmantojiet aprakstošus nosaukumus testa metodēm un apgalvojumiem.
- Testējiet vienu lietu vienlaikus: Katrai testa metodei jākoncentrējas uz viena aspekta testēšanu jūsu kodā. Tas atvieglo atteices avota identificēšanu, kad tests neizdodas.
- Izmantojiet jēgpilnus apgalvojumus: Izmantojiet apgalvojumu metodes, kas skaidri pauž paredzamo jūsu koda darbību. Django nodrošina bagātīgu apgalvojumu metožu kopu dažādiem scenārijiem.
- Ievērojiet sakārtošanas-rīcības-apgalvojuma modeli: Strukturējiet testus atbilstoši sakārtošanas-rīcības-apgalvojuma modelim: Sakārtojiet testa datus, rīkojieties ar testēto kodu un apstipriniet paredzamo rezultātu.
- Saglabājiet testus ātrus: Lēni testi var atturēt izstrādātājus no to biežas palaišanas. Optimizējiet testus, lai samazinātu izpildes laiku.
- Izmantojiet fiksētājus testa datiem: Fiksētāji ir ērts veids, kā ielādēt sākotnējos datus testa datu bāzē. Izmantojiet fiksētājus, lai izveidotu konsekventus un atkārtoti lietojamus testa datus. Apsveriet iespēju izmantot dabiskos atslēgas fiksētājos, lai izvairītos no ID kodēšanas.
- Apsveriet testēšanas bibliotēkas, piemēram, pytest, izmantošanu: Lai gan Django iebūvētais testēšanas ietvars ir jaudīgs, tādas bibliotēkas kā pytest var piedāvāt papildu funkcijas un elastību.
- Centieties sasniegt augstu testu pārklājumu: Centieties sasniegt augstu testu pārklājumu, lai nodrošinātu, ka jūsu kods ir pilnībā pārbaudīts. Izmantojiet pārklājuma rīkus, lai izmērītu testu pārklājumu un identificētu jomas, kurām nepieciešama lielāka testēšana.
- Integrējiet testus savā CI/CD cauruļvadā: Palaidiet testus automātiski kā daļu no jūsu nepārtrauktas integrācijas un nepārtrauktas izvietošanas (CI/CD) cauruļvada. Tas nodrošina, ka visas regresijas tiek uztvertas jau izstrādes procesa sākumā.
- Rakstiet testus, kas atspoguļo reālās pasaules scenārijus: Testējiet savu lietojumprogrammu veidos, kas atdarina to, kā lietotāji faktiski mijiedarbosies ar to. Tas palīdzēs jums atklāt kļūdas, kas var nebūt redzamas vienkāršos vienību testos. Piemēram, testējot veidlapas, apsveriet starptautisko adrešu un tālruņu numuru variācijas.
Internationalizācija (i18n) un testēšana
Izstrādājot Django lietojumprogrammas globālai auditorijai, ir ļoti svarīgi ņemt vērā internationalizāciju (i18n) un lokalizāciju (l10n). Nodrošiniet, lai jūsu testi aptvertu dažādas valodas, datumu formātus un valūtas simbolus. Šeit ir daži padomi:
- Testējiet ar dažādiem valodas iestatījumiem: Izmantojiet Django dekoratoru
override_settings
, lai testētu savu lietojumprogrammu ar dažādiem valodas iestatījumiem. - Izmantojiet lokalizētus datus savos testos: Izmantojiet lokalizētus datus savos testa fiksētājos un testa metodēs, lai nodrošinātu, ka jūsu lietojumprogramma pareizi apstrādā dažādus datumu formātus, valūtas simbolus un citus lokalizētus datus.
- Testējiet savas tulkošanas virknes: Pārbaudiet, vai jūsu tulkošanas virknes ir pareizi tulkotas un vai tās pareizi atveidojas dažādās valodās.
- Izmantojiet
localize
veidnes tagu: Savās veidnēs izmantojietlocalize
veidnes tagu, lai formatētu datumus, skaitļus un citus lokalizētus datus atbilstoši lietotāja pašreizējai lokalizācijai.
Piemērs: testēšana ar dažādiem valodas iestatījumiem
from django.test import TestCase
from django.utils import translation
from django.conf import settings
class InternationalizationTest(TestCase):
def test_localized_date_format(self):
original_language = translation.get_language()
try:
translation.activate('de') # Aktivizēt vācu valodu
with self.settings(LANGUAGE_CODE='de'): # Iestatīt valodu iestatījumos
from django.utils import formats
from datetime import date
d = date(2024, 1, 20)
formatted_date = formats.date_format(d, 'SHORT_DATE_FORMAT')
self.assertEqual(formatted_date, '20.01.2024')
finally:
translation.activate(original_language) # Atjaunot sākotnējo valodu
Šis piemērs parāda, kā testēt datumu formatēšanu ar dažādiem valodas iestatījumiem, izmantojot Django moduļus translation
un formats
.
Secinājums
Izpratne par atšķirībām starp TestCase
un TransactionTestCase
ir būtiska, lai rakstītu efektīvus un uzticamus testus programmā Django. TestCase
parasti ir vēlamā izvēle lielākajai daļai testēšanas scenāriju, nodrošinot ātru un efektīvu veidu, kā testēt atsevišķus jūsu lietojumprogrammas komponentus izolēti. TransactionTestCase
ir noderīgs sarežģītu datu bāzes mijiedarbību testēšanai, kas aptver vairākas transakcijas, piemēram, tās, kas saistītas ar signāliem vai atomiskām transakcijām. Ievērojot labāko praksi un ņemot vērā internationalizācijas aspektus, jūs varat izveidot stabilu testu komplektu, kas nodrošina jūsu Django lietojumprogrammu kvalitāti un uzturēšanu.