Django REST Assured

Instantly test-cover your Django REST Framework based API

Observation:

Testing sucks

Can't write them, can't live without them.

So much boilerplate

Our tests still contain tons of non-DRY code.

REST API solved

We can define an entire CRUD endpoint with just 3 trivial class declarations.

I can train a chicken

To test my trivial code.

Motivation:

Testing sucks

So much.

Django REST Assured

Enter:

Features:

Sanity coverage

It's a "Django system check framework" for your API.

Extensible boilerplate

So you can write less of it.

Built for REST

Choose the mixins you need:

retrieve/list/create/upadte/destroy

Example:

github.com/ydaniv/django-rest-assured-demo

models.py

from django.db import models


class Blog(models.Model):

    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __unicode__(self):
        return self.name


class Author(models.Model):

    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __unicode__(self):
        return self.name
class Entry(models.Model):

    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField(auto_now=True)
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __unicode__(self):
        return self.headline

serializers.py

from rest_framework import serializers
from . import models


class Entry(serializers.ModelSerializer):

    class Meta:
        model = models.Entry

views.py

from rest_framework import viewsets
from . import models, serializers


class Entries(viewsets.ModelViewSet):

    queryset = models.Entry.objects.all()
    serializer_class = serializers.Entry

urls.py

from django.conf.urls import url, include
from rest_framework import routers
from . import views


router = routers.DefaultRouter()
router.register(r'entries', views.Entries)


urlpatterns = [
    url(r'^', include(router.urls)),
]

factories.py

import datetime
import factory
from factory import fuzzy
from django.contrib import auth
from . import models


class Blog(factory.DjangoModelFactory):

    class Meta:
        model = models.Blog

    # fields...


class Author(factory.DjangoModelFactory):

    class Meta:
        model = models.Author

    # fields...
class Entry(factory.DjangoModelFactory):

    class Meta:
        model = models.Entry

    # fields...


class User(factory.DjangoModelFactory):

    class Meta:

        model = auth.get_user_model()

    # fields...

tests.py

import datetime
from rest_assured.testcases import ReadWriteRESTAPITestCaseMixin, BaseRESTAPITestCase
from . import factories


class EntryAPITestCase(ReadWriteRESTAPITestCaseMixin, BaseRESTAPITestCase):

    base_name = 'entry' # this is the base_name generated by the DefaultRouter
    factory_class = factories.Entry
    user_factory = factories.User
    update_data = {'rating': 5}

    def setUp(self):
       self.author = factories.Author.create()
       super(EntryAPITestCase, self).setUp()

    def get_object(self, factory):
        return factory.create(authors=[self.author])

    def get_create_data(self):
       return {'headline': 'Lucifer Sam',
               'body_text': 'is a song by British psychedelic rock band Pink Floyd.',
               'authors': [self.author.pk],
               'rating': 4,
               'n_pingbacks': 0,
               'n_comments': 0,
               'pub_date': datetime.date(2014, 11, 12),
               'blog': self.object.blog.pk}

In this example we tested:

GET /api/entries/

GET /api/entries/:id/

POST /api/entries/

PATCH /api/entries/:id/

DELETE /api/entries/:id/

ydaniv/django-rest-assured

27

1 active contributor (@maryokhin)

PyPI: django-rest-assured

~2K/month  downloads

Supports:

Python: 2.7 & 3.4

Django: 1.7 (probably 1.6 & 1.5)

DRF: 2.4.x

Go grab it!

Thank you.

@ydaniv

Django REST Assured Intro

By ydaniv

Django REST Assured Intro

An introduction to Django REST Assured.

  • 1,480