Django3.2の新機能テスト


Django 3.2 -, . , . , Django backport



.





1.  setUpTestData() 

:





«, TestCase.setUpTestData()



».





setUpTestData()



— , .





TestCase.setUp()



- , :





from django.test import TestCase

from example.core.models import Book

class ExampleTests(TestCase):
    def setUp(self):
        self.book = Book.objects.create(title="Meditations")
      
      



- setUp()



. , . , setUp()



, .





setUpTestData()



TestCase



. setUp()



, :





from django.test import TestCase

from example.core.models import Book

class ExampleTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.book = Book.objects.create(title="Meditations")
      
      



Django (rollback) , . , Django 3.2 rollback , . , .





, , :





from django.test import TestCase
from example.core.models import Book

class SetUpTestDataTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.book = Book.objects.create(title="Meditations")

    def test_that_changes_title(self):
        self.book.title = "Antifragile"

    def test_that_reads_title_from_db(self):
        db_title = Book.objects.get().title
        assert db_title == "Meditations"

    def test_that_reads_in_memory_title(self):
        assert self.book.title == "Meditations"
      
      



Django 3.1, :





$ ./manage.py test example.core.tests.test_setuptestdata
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.F.
======================================================================
FAIL: test_that_reads_in_memory_title (example.core.tests.test_setuptestdata.SetUpTestDataTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/.../example/core/tests/test_setuptestdata.py", line 19, in test_that_reads_in_memory_title
    assert self.book.title == "Meditations"
AssertionError

----------------------------------------------------------------------
Ran 3 tests in 0.002s

FAILED (failures=1)
Destroying test database for alias 'default'...
      
      



, in-memory test_that_changes_title()



. Django 3.2 , in-memory. :





$ ./manage.py test example.core.tests.test_setuptestdata
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK
Destroying test database for alias 'default'...
      
      



Simon Charette django-testdata, Django. Django django - ,    @wrap_testdata



setUpTestData()



. , , .





( Django , , ).





2. faulthandler

:





DiscoverRunner faulthandler .





, . Python faulthandler «» , Python.  runner Django faulthandler. pytest, .





, faulthandler, C, , . , OS SIGSEGV , , . Python, :





import os
import signal

from django.test import SimpleTestCase


class FaulthandlerTests(SimpleTestCase):
    def test_segv(self):
        # Directly trigger the segmentation fault
        # signal, which normally occurs due to
        # unsafe memory access in C
        os.kill(os.getpid(), signal.SIGSEGV)
      
      



Django 3.1, :





$ ./manage.py test example.core.tests.test_faulthandler
System check identified no issues (0 silenced).
[1]    31127 segmentation fault  ./manage.py test
      
      



, , .





Django 3.2:





$ ./manage.py test example.core.tests.test_faulthandler
System check identified no issues (0 silenced).
Fatal Python error: Segmentation fault

Current thread 0x000000010ed1bdc0 (most recent call first):
  File "/.../example/core/tests/test_faulthandler.py", line 12 in test_segv
  File "/.../python3.9/unittest/case.py", line 550 in _callTestMethod
  ...
  File "/.../django/test/runner.py", line 668 in run_suite
  ...
  File "/..././manage.py", line 17 in main
  File "/..././manage.py", line 21 in <module>
[1]    31509 segmentation fault  ./manage.py test
      
      



 ( )





Faulthandler , Python, .





3. Timing ()

:





DiscoverRunner , .





manage.py test



--timing



, - :





$ ./manage.py test --timing
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK
Destroying test database for alias 'default'...
Total database setup took 0.019s
  Creating 'default' took 0.019s
Total database teardown took 0.000s
Total run took 0.028s
      
      



. Google Summer of Code 2020.





pytest, --durations N







- pytest «» (setup time) , , .





4. (callbacks)  transaction.on_commit() 

:





TestCase.captureOnCommitCallbacks()



(callbacks functions), transaction.on_commit()



. callbacks, TransactionTestCase



.





, .





, ,  ATOMIC_REQUESTS  Django, ( , !). transaction.on_commit() , , . , :





from django.db import transaction
from django.views.decorators.http import require_http_methods

from example.core.models import ContactAttempt


@require_http_methods(("POST",))
def contact(request):
    message = request.POST.get('message', '')
    attempt = ContactAttempt.objects.create(message=message)

    @transaction.on_commit
    def send_email():
        send_contact_form_email(attempt)

    return redirect('/contact/success/')
      
      



, , ContactAttempt.





, callback ( ), on_commit()



. Django callback , TestCase



, (rollback) , .





TransactionTestCase



, . , TestCase



, .





( TransactionTestCase



TestCase



.)





Django 3.2 captureOnCommitCallbacks()



, . callbacks . , :





from django.core import mail
from django.test import TestCase

from example.core.models import ContactAttempt


class ContactTests(TestCase):
    def test_post(self):
        with self.captureOnCommitCallbacks(execute=True) as callbacks:
            response = self.client.post(
                "/contact/",
                {"message": "I like your site"},
            )

        assert response.status_code == 302
        assert response["location"] == "/contact/success/"
        assert ContactAttempt.objects.get().message == "I like your site"
        assert len(callbacks) == 1
        assert len(mail.outbox) == 1
        assert mail.outbox[0].subject == "Contact Form"
        assert mail.outbox[0].body == "I like your site"
      
      



, captureOnCommitCallbacks()



, execute , , « ()» callbacks. HTTP- , , (callback). , !





captureOnCommitCallbacks()



Django, django-capture-on-commit-callbacks.





5. assertQuerysetEqual() 

:





TransactionTestCase.assertQuerysetEqual()



Django





assertQuerysetEqual() , !





Django 3.2, assertQuerysetEqual()



QuerySet . repr()



. , , , repr() strings



:





from django.test import TestCase

from example.core.models import Book


class AssertQuerySetEqualTests(TestCase):
    def test_comparison(self):
        Book.objects.create(title="Meditations")
        Book.objects.create(title="Antifragile")

        self.assertQuerysetEqual(
            Book.objects.order_by("title"),
            ["<Book: Antifragile>", "<Book: Meditations>"],
        )

      
      



, . repr()



.





Django 3.2 QuerySet



, :





from django.test import TestCase

from example.core.models import Book


class AssertQuerySetEqualTests(TestCase):
    def test_comparison(self):
        book1 = Book.objects.create(title="Meditations")
        book2 = Book.objects.create(title="Antifragile")

        self.assertQuerysetEqual(
            Book.objects.order_by("title"),
            [book2, book1],
        )
      
      



, . Django.





, Django 3.2 backport.






«Web- Python».





« django». django; : django-debug-toolbar, django-cms, django-cleanup ..








All Articles