Code Monkey home page Code Monkey logo

django-testdata's Introduction

django-testdata

License Latest Version Build Status Coverage Status Supported Python Versions Wheel Status

Django application providing isolation for model instances created during setUpTestData.

Installation

pip install django-testdata

Motivation

Django 1.8 introduced TestCase.setUpTestData to allow costly generation of model fixtures to be executed only once per test class in order to speed up testcase instances execution.

One gotcha of setUpTestData though is that test instances all share the same model instances and have to be careful not to alter them to prevent breaking test isolation. Per Django's documentation:

Be careful not to modify any objects created in setUpTestData() in your
test methods. Modifications to in-memory objects from setup work done at
the class level will persist between test methods. If you do need to modify
them, you could reload them in the setUp() method with refresh_from_db(),
for example.

Reloading objects in setUp() certainly works but it kind of defeats the purpose of avoiding database hits to speed up tests execution in the first place. It makes little sense to fetch model instances from the database given all

This package offers a different alternative to work around this quirk of setUpTestData. Instead of reloading objects from the database the model instances assigned as class attributes during setUpTestData are lazily deep copied on testcase instance accesses from their original definition. All of deep copying is done by sharing a memo which makes sure in-memory relationships between objects is preserved.

Usage

The test data can be either wrapped manually by using testdata.

from django.test import TestCase
from testdata import testdata

from .models import Author, Book

class BookTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.author = testdata(Author.objects.create(
            name='Milan Kundera',
        ))
        cls.book = testdata(cls.author.books.create(
            title='Nesnesitelná lehkost bytí',
        ))

Or automatically by using the wrap_testdata decorator.

from django.test import TestCase
from testdata import wrap_testdata

from .models import Author, Book

class BookTests(TestCase):
    @classmethod
    @wrap_testdata
    def setUpTestData(cls):
        cls.author = Author.objects.create(
            name='Milan Kundera',
        )
        cls.book = cls.author.books.create(
            title='Nesnesitelná lehkost bytí',
        )

Under the hood wrap_testdata simply wraps all attributes added to cls during the execution of setUpTestData() into testdata(attr, name=name) which has also the nice side effect of speeding subsequent accesses.

Once test data is wrapped the testcase instances methods can alter objects retrieved from self without worrying about cross-tests isolation.

from django.test import TestCase
from testdata import wrap_testdata

from .models import Author, Book

class BookTests(TestCase):
    @classmethod
    @wrap_testdata
    def setUpTestData(cls):
        cls.author = Author.objects.create(
            name='Milan Kundera',
        )
        cls.book = cls.author.books.create(
            title='Nesnesitelná lehkost bytí',
        )

    def test_book_name_english(self):
        self.assertEqual(self.book.title, 'Nesnesitelná lehkost bytí')
        self.book.title = 'The Unbearable Lightness of Being'
        self.book.save()

    def test_book_name_french(self):
        self.assertEqual(self.book.title, 'Nesnesitelná lehkost bytí')
        self.book.title = "L'Insoutenable Légèreté de l'être"
        self.book.save()

django-testdata's People

Contributors

adamchainz avatar charettes avatar mbarszcz avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.