18.7. Tests Views

18.7.1. Fixtures

$ python manage.py dumpdata shop.customer --indent=2 --output=shop/fixtures/customer.json
[...........................................................................]
from django.test import TestCase

class CustomerTest(TestCase):
    fixtures = ['customer.json']

18.7.2. Example

Empty files:

  • myproject/shop/templates/shop/customer_index.html

  • myproject/shop/templates/shop/customer_list.html

  • myproject/shop/templates/shop/customer_detail.html

Code 18.5. File myproject/shop/fixtures/customer.json
[
  {
    "model": "shop.customer",
    "pk": 1,
    "fields": {
      "firstname": "Mark",
      "lastname": "Watney",
      "birthdate": "2000-01-02"
    }
  },
  {
    "model": "shop.customer",
    "pk": 2,
    "fields": {
      "firstname": "Melissa",
      "lastname": "Lewis",
      "birthdate": "2000-01-02"
    }
  },
  {
    "model": "shop.customer",
    "pk": 3,
    "fields": {
      "firstname": "Rick",
      "lastname": "Martinez",
      "birthdate": "2000-01-02"
    }
  }
]
Code 18.6. File myproject/shop/views.py
from django.shortcuts import render
from django.views.generic import DetailView, ListView
from shop.models import Customer


def customer_index(request):
    return render(request, 'shop/customer_index.html')


class CustomerList(ListView):
    model = Customer
    template_name = 'shop/customer_list.html'


class CustomerDetail(DetailView):
    model = Customer
    template_name = 'shop/customer_detail.html'
Code 18.7. File myproject/shop/urls.py
from django.urls import path
from shop.views import customer_index, CustomerList, CustomerDetail

app_name = 'shop'

urlpatterns = [
    path('index', customer_index, name='customer_index'),
    path('list', CustomerList.as_view(), name='customer_list'),
    path('detail/<int:pk>', CustomerDetail.as_view(), name='customer_detail'),
]
Code 18.8. File myproject/urls.py
from django.contrib import admin
from django.urls import path, include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('customer/', include('shop.urls')),
]
Code 18.9. File myproject/shop/tests/test_views_customer.py
from django.test import TestCase, SimpleTestCase
from django.urls import reverse, resolve
from shop.views import customer_index, CustomerList, CustomerDetail


class CustomerIndexTest(SimpleTestCase):
    def setUp(self):
        self.url = reverse('shop:customer_index')

    def test_url(self):
        self.assertEqual(self.url, '/customer/index')

    def test_view(self):
        view = resolve(self.url).func  # function-based view
        self.assertEqual(view, customer_index)

    def test_template(self):
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'shop/customer_index.html')


class CustomerListTest(TestCase):
    fixtures = ['customer.json']

    def setUp(self):
        self.url = reverse('shop:customer_list')

    def test_url(self):
        self.assertEqual(self.url, '/customer/list')

    def test_view(self):
        view = resolve(self.url).func.view_class  # class-based view
        self.assertEqual(view, CustomerList)

    def test_template(self):
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'shop/customer_list.html')


class CustomerDetailTest(TestCase):
    fixtures = ['customer.json']

    def setUp(self):
        self.url = reverse('shop:customer_detail', kwargs={'pk': 1})

    def test_url(self):
        self.assertEqual(self.url, '/customer/detail/1')

    def test_view(self):
        view = resolve(self.url).func.view_class  # class-based view
        self.assertEqual(view, CustomerDetail)

    def test_template(self):
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'shop/customer_detail.html')

18.7.3. Use Case - 1

Code 18.10. File myproject/shop/tests/test_views_customer.py
from django.test import TestCase, Client
from django.urls import reverse
from shop.models import Product


class TestViews(TestCase):
    def setUp(self):
        self.client = Client()

    def test_product_list(self):
        url = reverse('shop:product_list')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'shop/product-list.html')

    def test_product_detail(self):
        Product.objects.create(
            name='Alpha', price=100, barcode='1234567890123'
            )
        url = reverse('shop:product_detail', kwargs={'pk': 1})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'shop/product-detail.html')

    def test_product_create_valid(self):
        url = reverse('shop:product_create')
        self.client.post(
            url, {
                'name': 'Alpha',
                'price': 100.00,
                'barcode': '1234567890123'
            }
            )
        self.assertEqual(response.status_code, 201)
        self.assertEqual(Product.objects.count(), 1)
        self.assertEqual(Product.objects.first().name, 'Alpha')
        self.assertEqual(Product.objects.first().price, 100.00)
        self.assertEqual(Product.objects.first().barcode, '1234567890123')

    def test_product_create_invalid_name(self):
        url = reverse('shop:product_create')
        self.client.post(
            url, {
                'price': 100.00,
                'barcode': '1234567890123'
            }
            )
        self.assertEqual(response.status_code, 400)
        self.assertEqual(Product.objects.count(), 0)

    def test_product_create_invalid_price(self):
        url = reverse('shop:product_create')
        self.client.post(
            url, {
                'name': 'Alpha',
                'price': 'hundred',
                'barcode': '1234567890123'
            }
            )
        self.assertEqual(response.status_code, 400)
        self.assertEqual(Product.objects.count(), 0)

    def test_product_delete(self):
        url = reverse('shop:product_delete', kwargs={'pk': 1})
        self.client.delete(url)
        self.assertEqual(response.status_code, 204)
        self.assertEqual(Product.objects.count(), 0)