00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Testing

Il testing e una pratica fondamentale per garantire la qualita e l’affidabilita di un’applicazione Django. Il framework include un sistema di testing completo basato su unittest di Python, con strumenti specifici per testare modelli, viste, form e API.

Classi di Test Disponibili

Django mette a disposizione diverse classi di test, ognuna con caratteristiche specifiche:

  • SimpleTestCase: Per test che non necessitano di accesso al database.
  • TestCase: La piu utilizzata, con transazioni e database di test.
  • TransactionTestCase: Per test che richiedono il controllo delle transazioni.
  • LiveServerTestCase: Avvia un server di test reale, utile per test con Selenium.

Primo Test con TestCase

# myapp/tests.py
from django.test import TestCase
from .models import Articolo

class ArticoloTestCase(TestCase):
    def setUp(self):
        """Eseguito prima di ogni metodo di test."""
        self.articolo = Articolo.objects.create(
            titolo="Test Articolo",
            contenuto="Contenuto di prova",
            pubblicato=True,
        )

    def tearDown(self):
        """Eseguito dopo ogni metodo di test."""
        # La pulizia del database avviene automaticamente con TestCase
        pass

    def test_creazione_articolo(self):
        """Verifica che l'articolo sia stato creato correttamente."""
        self.assertEqual(self.articolo.titolo, "Test Articolo")
        self.assertTrue(self.articolo.pubblicato)

    def test_conteggio_articoli(self):
        """Verifica il numero di articoli nel database."""
        conteggio = Articolo.objects.count()
        self.assertEqual(conteggio, 1)

    def test_stringa_rappresentazione(self):
        """Verifica il metodo __str__ del modello."""
        self.assertEqual(str(self.articolo), "Test Articolo")

Esegui i test:

python manage.py test
python manage.py test myapp                    # Test di una singola app
python manage.py test myapp.tests.ArticoloTestCase  # Test di una singola classe
python manage.py test myapp.tests.ArticoloTestCase.test_creazione_articolo  # Singolo test

Test delle Viste con Client

Il Client di Django simula un browser web per testare le viste:

from django.test import TestCase, Client
from django.urls import reverse

class VisteTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        Articolo.objects.create(
            titolo="Articolo Test",
            contenuto="Contenuto",
            pubblicato=True,
        )

    def test_lista_articoli(self):
        """Verifica che la pagina della lista articoli funzioni."""
        response = self.client.get(reverse("lista-articoli"))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "articoli/lista.html")
        self.assertContains(response, "Articolo Test")

    def test_dettaglio_articolo(self):
        """Verifica la pagina di dettaglio."""
        response = self.client.get(reverse("dettaglio-articolo", args=[1]))
        self.assertEqual(response.status_code, 200)

    def test_pagina_non_trovata(self):
        """Verifica il comportamento per una pagina inesistente."""
        response = self.client.get(reverse("dettaglio-articolo", args=[999]))
        self.assertEqual(response.status_code, 404)

    def test_creazione_articolo_post(self):
        """Verifica la creazione di un articolo tramite POST."""
        response = self.client.post(reverse("crea-articolo"), {
            "titolo": "Nuovo Articolo",
            "contenuto": "Nuovo contenuto",
        })
        self.assertEqual(response.status_code, 302)  # Redirect dopo creazione
        self.assertTrue(Articolo.objects.filter(titolo="Nuovo Articolo").exists())

Test con Autenticazione

from django.contrib.auth.models import User

class VisteAutenticateTestCase(TestCase):
    def setUp(self):
        self.utente = User.objects.create_user(
            username="testuser",
            password="testpass123",
        )

    def test_accesso_area_privata(self):
        """Verifica che l'area privata richieda autenticazione."""
        response = self.client.get(reverse("dashboard"))
        self.assertEqual(response.status_code, 302)  # Redirect al login

        self.client.login(username="testuser", password="testpass123")
        response = self.client.get(reverse("dashboard"))
        self.assertEqual(response.status_code, 200)

RequestFactory

RequestFactory crea oggetti request senza passare attraverso il middleware, utile per testare le viste in isolamento:

from django.test import TestCase, RequestFactory
from .views import lista_articoli

class RequestFactoryTestCase(TestCase):
    def setUp(self):
        self.factory = RequestFactory()

    def test_lista_articoli_view(self):
        request = self.factory.get("/articoli/")
        request.user = User.objects.create_user(username="test", password="test123")

        response = lista_articoli(request)
        self.assertEqual(response.status_code, 200)

SimpleTestCase per Test Senza Database

from django.test import SimpleTestCase
from django.urls import reverse, resolve
from .views import homepage

class URLTestCase(SimpleTestCase):
    def test_homepage_url(self):
        url = reverse("homepage")
        self.assertEqual(resolve(url).func, homepage)

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

Fixture e Dati di Test

Puoi caricare dati predefiniti usando le fixture:

class ArticoloConFixtureTestCase(TestCase):
    fixtures = ["articoli_test.json"]

    def test_articoli_caricati(self):
        self.assertEqual(Articolo.objects.count(), 5)

Metodi di Asserzione Utili

Django estende le asserzioni standard con metodi specifici:

# Asserzioni sulle risposte HTTP
self.assertContains(response, "testo atteso")
self.assertNotContains(response, "testo non atteso")
self.assertTemplateUsed(response, "template.html")
self.assertRedirects(response, "/destinazione/")

# Asserzioni sui form
self.assertFormError(response, "form", "campo", "Errore atteso")

# Asserzioni sulle query
self.assertQuerySetEqual(qs, ["valore1", "valore2"])
self.assertNumQueries(3, lambda: lista_articoli())

Conclusione

Il framework di testing di Django offre tutti gli strumenti necessari per scrivere test completi e affidabili. Usa TestCase per i test standard, Client per simulare le richieste HTTP, RequestFactory per testare le viste in isolamento e SimpleTestCase quando non serve il database. Testare regolarmente il codice previene regressioni e migliora la qualita complessiva dell’applicazione.