Testing en Python#

Logo Python

Testing en diferentes casos con Python

Testing en Django#

TestTipe en Apps django#

Se abre una app django y se edita el archivo test.py:

 1# Se importa TestCase por defecto:
 2from django.test import TestCase
 3# importamos los modelos serie y episodios:
 4from .models import Serie, Episodio
 5
 6# Se crea una clase para cada test:
 7class TestSerie(TestCase):
 8    # podemos crear información temporal en la base de datos:
 9    def _generate_serie(self):
10        serie = Serie.objects.create(title='Los amigos', description='Descripcion de los amigos')
11
12        for i in range(1, 6):
13            Episodio.objects.create(serie_id=serie.pk, name='episodio amigos', number=i+1)
14
15        return serie
16
17    # vamos a probar un endpoint:
18    def test_list_serie(self):
19        # recuperamos el endpoint con get post put o delete:
20        response = self.client.get('/api/series/')
21
22        # Comprueba si el código es igual a 200:
23        self.assertEqual(response.status_code, 200)
24
25    # prueba usando
26    def test_retreive_serie(self):
27        # Se recupera la serie que se ha creado temporal:
28        serie = self._generate_serie()
29
30        # Ahora vamos a probar a recuperar el detalle de la serie:
31        response = self.client.get('/api/series/{}/'.format(serie.pk))
32
33        self.assertEqual(response.status_code, 200)
34
35        # vamos a conseguir el json:
36        response_json = response.json()
37
38        # Comprobamos que la respuesta es un diccionario:
39        self.assertIsInstance(response_json, dict)
40        # comprobamos cada uno de los campos si son del formato correcto:
41        self.assertIsInstance(response_json.get('id'), int)
42        self.assertIsInstance(response_json.get('title'), str)
43        self.assertIsInstance(response_json.get('description'), str)
44        self.assertIsInstance(response_json.get('episodes'), list)

TestTipe autenticación#

En algunos casos es necesario logearse para poder realizar algunas operaciones en la aplicación:

 1from django.test import TestCase
 2from .models import Serie, Episodio
 3# Se importa el modelo de usuarios:
 4from django.contrib.auth.models import User
 5
 6class TestSerie(TestCase):
 7
 8    # se genera un usuario de prueba:
 9    def _generate_user(self) -> User:
10        user = User.objects.create(username='fake', password='insegura', email='fakemail@fake.com')
11
12        return user
13
14    # se crea un test que necesite de login como crear una serie:
15    def test_create_serie(self):
16        user = self._generate_user()
17        # se fuerza el login sin necesidad de que tenga contraseña o permisos:
18        self.client.force_login(user)
19        # preparamos la información:
20        serie_dict = {'title': 'serie de prueba', 'description': 'descripcion de prueba'}
21        # se hace la consulta:
22        response = self.client.post('/api/series/', serie_dict)
23
24        # se hacen todas las comprobaciones:
25        self.assertEqual(response.status_code, 201)
26
27        response_json = response.json()
28
29        self.assertIsInstance(response_json, dict)
30        self.assertIsInstance(response_json.get('id'), int)
31        self.assertIsInstance(response_json.get('title'), str)
32        self.assertIsInstance(response_json.get('description'), str)

Fixtures - generar datos base#

Vamos a recuperar unos datos que pasaremos a json para poder usar en todos los test:

  1. Se crea en la raiz del proyecto la carpeta fixtures

  2. Ahora para ejecutar un fixture que genere datos de usuarios: python manage.py dumpdata --format=json auth.user > fixtures/users.json

  3. Se puede hacer lo mismo pero con un solo registro: python manage.py dumpdata --format=json --pks 1 series.serie > fixtures/serie.json

  4. Si queremos importar los episodios: python manage.py dumpdata --format=json --pks 1 series.episodio >> fixtures/serie.json

  5. Indicar donde se guardan las Fixtures en settings.py: FIXTURE_DIRS = [str(BASE_DIR.joinpath('fixtures/'))]

  6. Para reemplazar los generates por las fixtures se hace lo siguiente en los tests:

 1from django.test import TestCase
 2from .models import Serie, Episodio
 3from django.contrib.auth.models import User
 4
 5class TestSerie(TestCase):
 6    # ahora se pueden cargar fácilmente la información de las fixtures:
 7    fixtures = ['serie', 'users']
 8
 9    def test_create_serie(self):
10        # Se reemplaza la consulta por una con el ORM:
11        user = User.objects.first()
12        self.client.force_login(user)
13
14        serie_dict = {'title': 'serie de prueba', 'description': 'descripcion de prueba'}
15        response = self.client.post('/api/series/', serie_dict)
16
17        self.assertEqual(response.status_code, 201)
18
19        response_json = response.json()
20
21        self.assertIsInstance(response_json, dict)
22        self.assertIsInstance(response_json.get('id'), int)
23        self.assertIsInstance(response_json.get('title'), str)
24        self.assertIsInstance(response_json.get('description'), str)
25
26
27
28    def test_list_serie(self):
29        response = self.client.get('/api/series/')
30
31        self.assertEqual(response.status_code, 200)
32
33    def test_retreive_serie(self):
34        # Se reemplaza la consulta por una con el ORM:
35        serie = Serie.objects.first()
36
37        response = self.client.get('/api/series/{}/'.format(serie.pk))
38
39        self.assertEqual(response.status_code, 200)
40
41        response_json = response.json()
42
43        self.assertIsInstance(response_json, dict)
44        self.assertIsInstance(response_json.get('id'), int)
45        self.assertIsInstance(response_json.get('title'), str)
46        self.assertIsInstance(response_json.get('description'), str)
47        self.assertIsInstance(response_json.get('episodes'), list)

Atención

En el paso 4 debemos arreglar la información manualmente ya que se añade un segundo listado de forma incorrecta

Herramienta Coverage#

La herramienta coverage mide la covertura de los test que preparamos:

  1. Instalar la herramienta: pip install coverage

  2. Para ejecutar tests: coverage run manage.py test (osea el comando de testing que usamos)

  3. Generar reporte: coverage report