Discussion:
Unit tests
Alexander Lamas
2018-08-21 09:08:56 UTC
Permalink
Hi All,

How can I make a CRUD (GET, POST, DELETE, UPDATE) unit testing for a model
class

Here is my sample. I'm struggling with the update and delete

MODEL

from django.db import models
class Tenant(models.Model):
Name = models.CharField(max_length=200, null=False, default='', db_column='Name')

def __str__(self):
return self.Name

class Meta:
db_table = 'Tenant'
ordering = ['Name']

def save(self, *args, **kwargs):
Name = self.Name
super(Tenant, self).save(*args, **kwargs)



VIEW

from rest_framework import generics, permissions, renderers, viewsetsfrom rest_framework.decorators import api_view, detail_routefrom app.models import Tenantfrom app.serializers import TenantSerializer
class TenantViewSet(viewsets.ModelViewSet):
serializer_class = TenantSerializer
queryset = Tenant.objects.all()

@detail_route(renderer_classes=[renderers.JSONRenderer])

def perform_create(self, serializer):
serializer.save()


SERIALIZER

from rest_framework import serializersfrom app.models import Tenant
class TenantSerializer(serializers.ModelSerializer):
class Meta:
model = Tenant
fields = '__all__'


UNIT TEST

import djangodjango.setup()
from django.urls import reversefrom rest_framework import statusfrom rest_framework.test import APITestCasefrom app.models import Tenant
class TenantTests(APITestCase):

_value = 'Tenant_TEST'

def test_1_Tenant_ListAll_Return_0(self):
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Tenant.objects.all().count(), 0)

def test_2_Tenant_ListSingle_Return_0(self):
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Tenant.objects.filter(Name__contains=self._value).count(), 0)

def test_3_Tenant_Post_ReturnNothing(self):
url = reverse('tenant-list')
data = {'Name': self._value}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Tenant.objects.filter(Name__contains=self._value).count(), 1)

def test_4_Tenant_Update_ReturnRecordUpdated(self):
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK,)
result = Tenant.objects.get(Name__contains=self._value).values_list('id')
self.assertEqual(Tenant.objects.count(), 1,)

def test_5_Tenant_Delete_ReturnNothing(self):
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK,)
id = 1
Tenant.objects.get(pk = id).delete()
self.assertEqual(Tenant.objects.all().count(), 0)


Is that the correct way? Better question, is there a better way?

The intention is to test if my API is working in all aspects.

How can get the ID (PK) and make the update and delete happen?

Thank you very much!

Regards,
Alex
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Marc Chakiachvili
2018-08-21 09:21:54 UTC
Permalink
Hi,

Firstly, you may not name your class var with upper case, that's only an
opinion, and doesn't respond to your query.

In your test test_5_Tenant_Delete_ReturnNothing, you are actually testing
the Rest endpoint, but the ORM action of delete.

The DRF test client provide already methods to test delete :
http://www.django-rest-framework.org/api-guide/testing/#making-requests :

''The APIClient class supports the same request interface as Django's
standard Client class. This means the that standard .get(), .post(), .put()
, .patch(), .delete(), .head() and .options() methods are all available. ''

Your DELETE test should be like this:

- Create one new item with the post method (check 201 HTTP response)
- List all (or retrieve ID from previous call)
- Call delete() method on client with ID (check that HTTP_204_NO_CONTENT is
returned)
- Check in DB that this id has been deleted (Tenant.get(pk=ID) raise a
ObjectDoesNotExist exception (with self.assertRaises(ObjectDoesNotExist):
do the get on entity)

For update method use simply put or patch methods to test.
Have a look in here:
http://www.django-rest-framework.org/tutorial/2-requests-and-responses/
http://www.django-rest-framework.org/api-guide/status-codes/#successful-2xx

Have a good day :-)
Marc
Post by Alexander Lamas
Hi All,
How can I make a CRUD (GET, POST, DELETE, UPDATE) unit testing for a model
class
Here is my sample. I'm struggling with the update and delete
MODEL
from django.db import models
Name = models.CharField(max_length=200, null=False, default='', db_column='Name')
return self.Name
db_table = 'Tenant'
ordering = ['Name']
Name = self.Name
super(Tenant, self).save(*args, **kwargs)
VIEW
from rest_framework import generics, permissions, renderers, viewsetsfrom rest_framework.decorators import api_view, detail_routefrom app.models import Tenantfrom app.serializers import TenantSerializer
serializer_class = TenantSerializer
queryset = Tenant.objects.all()
@detail_route(renderer_classes=[renderers.JSONRenderer])
serializer.save()
SERIALIZER
from rest_framework import serializersfrom app.models import Tenant
model = Tenant
fields = '__all__'
UNIT TEST
import djangodjango.setup()
from django.urls import reversefrom rest_framework import statusfrom rest_framework.test import APITestCasefrom app.models import Tenant
_value = 'Tenant_TEST'
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Tenant.objects.all().count(), 0)
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Tenant.objects.filter(Name__contains=self._value).count(), 0)
url = reverse('tenant-list')
data = {'Name': self._value}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Tenant.objects.filter(Name__contains=self._value).count(), 1)
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK,)
result = Tenant.objects.get(Name__contains=self._value).values_list('id')
self.assertEqual(Tenant.objects.count(), 1,)
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK,)
id = 1
Tenant.objects.get(pk = id).delete()
self.assertEqual(Tenant.objects.all().count(), 0)
Is that the correct way? Better question, is there a better way?
The intention is to test if my API is working in all aspects.
How can get the ID (PK) and make the update and delete happen?
Thank you very much!
Regards,
Alex
--
You received this message because you are subscribed to the Google Groups
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alexander Lamas
2018-08-22 04:24:24 UTC
Permalink
Hi Marc,

Thank you very much for your reply and time explaining everything. Much
appreciated! :)

So, each *def test_* have it's own data creation and manipulation, you can
not reuse data across the tests, can you?

Also, how can you set the environment to create it's own test database
every time I run the unit tests?

Is there a way I can set the settings.py

#ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['testserver']

to use ALLOWED_HOST['testserver'] when I'm running the unit tests?

Should I create a dev_settings.py or a unit_test_settings.py file for this?

Thank you again!

Regards,
Alex




On Tue, Aug 21, 2018 at 6:22 PM Marc Chakiachvili <
Post by Marc Chakiachvili
Hi,
Firstly, you may not name your class var with upper case, that's only an
opinion, and doesn't respond to your query.
In your test test_5_Tenant_Delete_ReturnNothing, you are actually testing
the Rest endpoint, but the ORM action of delete.
''The APIClient class supports the same request interface as Django's
standard Client class. This means the that standard .get(), .post(),
.put(), .patch(), .delete(), .head() and .options() methods are all
available. ''
- Create one new item with the post method (check 201 HTTP response)
- List all (or retrieve ID from previous call)
- Call delete() method on client with ID (check that HTTP_204_NO_CONTENT
is returned)
- Check in DB that this id has been deleted (Tenant.get(pk=ID) raise a
do the get on entity)
For update method use simply put or patch methods to test.
http://www.django-rest-framework.org/tutorial/2-requests-and-responses/
http://www.django-rest-framework.org/api-guide/status-codes/#successful-2xx
Have a good day :-)
Marc
Post by Alexander Lamas
Hi All,
How can I make a CRUD (GET, POST, DELETE, UPDATE) unit testing for a
model class
Here is my sample. I'm struggling with the update and delete
MODEL
from django.db import models
Name = models.CharField(max_length=200, null=False, default='', db_column='Name')
return self.Name
db_table = 'Tenant'
ordering = ['Name']
Name = self.Name
super(Tenant, self).save(*args, **kwargs)
VIEW
from rest_framework import generics, permissions, renderers, viewsetsfrom rest_framework.decorators import api_view, detail_routefrom app.models import Tenantfrom app.serializers import TenantSerializer
serializer_class = TenantSerializer
queryset = Tenant.objects.all()
@detail_route(renderer_classes=[renderers.JSONRenderer])
serializer.save()
SERIALIZER
from rest_framework import serializersfrom app.models import Tenant
model = Tenant
fields = '__all__'
UNIT TEST
import djangodjango.setup()
from django.urls import reversefrom rest_framework import statusfrom rest_framework.test import APITestCasefrom app.models import Tenant
_value = 'Tenant_TEST'
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Tenant.objects.all().count(), 0)
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Tenant.objects.filter(Name__contains=self._value).count(), 0)
url = reverse('tenant-list')
data = {'Name': self._value}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Tenant.objects.filter(Name__contains=self._value).count(), 1)
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK,)
result = Tenant.objects.get(Name__contains=self._value).values_list('id')
self.assertEqual(Tenant.objects.count(), 1,)
url = reverse('tenant-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK,)
id = 1
Tenant.objects.get(pk = id).delete()
self.assertEqual(Tenant.objects.all().count(), 0)
Is that the correct way? Better question, is there a better way?
The intention is to test if my API is working in all aspects.
How can get the ID (PK) and make the update and delete happen?
Thank you very much!
Regards,
Alex
--
You received this message because you are subscribed to the Google Groups
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jason
2018-08-22 11:23:06 UTC
Permalink
Yes, data that's changed/inserted/deleted in a test doesn't affect other
tests. That's the whole point of self-contained tests

testing is independent of allowed_hosts, you don't need that

by default, the test environment creates the db on each test suite run.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alexander Lamas
2018-08-23 00:06:19 UTC
Permalink
Thank you very much for your reply Jason!

yeah, I tested all my unit tests and yes, I've noticed that you can not
keep data to be used in the other tests.
They create their own data and settings and get cleaned up when finished.

Good learning! :)

Thank you!

Regards,
Alex
Post by Jason
Yes, data that's changed/inserted/deleted in a test doesn't affect other
tests. That's the whole point of self-contained tests
testing is independent of allowed_hosts, you don't need that
by default, the test environment creates the db on each test suite run.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'ju5t' via Django REST framework
2018-08-26 11:18:01 UTC
Permalink
Although you don't need to change ALLOWED_HOSTS there is this little
function that can help in case you do need to test your settings.py.

https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.override_settings

It's really useful.
Post by Jason
Yes, data that's changed/inserted/deleted in a test doesn't affect other
tests. That's the whole point of self-contained tests
testing is independent of allowed_hosts, you don't need that
by default, the test environment creates the db on each test suite run.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Continue reading on narkive:
Loading...