Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

https://img.shields.io/github/workflow/status/adamchainz/django-capture-on-commit-callbacks/CI/main?style=for-the-badge https://img.shields.io/badge/Coverage-100%25-success?style=for-the-badge https://img.shields.io/pypi/v/django-capture-on-commit-callbacks.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

Capture and make assertions on transaction.on_commit() callbacks. This allows you to write your tests with the TestCase, rather than needing the slower TransactionTestCase to actually commit the transactions.

This package was made as a first pass for Django PR #12944, which is a solution for Ticket #30457 “on_commit should be triggered in a TestCase”. The PR has been merged to Django and has been released in version 3.2, so this package can now be considered a backport.

Read more in my blog post The Fast Way to Test Django transaction.on_commit() Callbacks.

Installation

Use pip:

python -m pip install django-capture-on-commit-callbacks

Requirements

Python 3.7 to 3.10 supported.

Django 3.2 to 4.0 supported.

Note: This package is not needed on Django 4.0+ and it will error on usage for such versions.


Are your tests slow? Check out my book Speed Up Your Django Tests which covers loads of ways to write faster, more accurate tests.


API

capture_on_commit_callbacks(*, using="default", execute=False)

Acts as a context manager that captures on_commit callbacks for the given database connection. It returns a list that contains, on exit of the context, the captured callback functions. From this list you can make assertions on the callbacks or call them to invoke their side effects, emulating a commit.

All arguments must be passed as keyword arguments.

using is the alias of the database connection to capture callbacks for.

execute specifies whether to call all the callbacks automatically as the context manager exits, if no exception has been raised.

For example, you can test a commit hook that sends an email like so:

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


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

        self.assertEqual(response.status_code, 200)

        self.assertEqual(len(callbacks), 1)
        # Execute the callback
        callbacks[0]()

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, "Contact Form")
        self.assertEqual(mail.outbox[0].body, "I like your site")

The same test can be written a bit more succinctly with execute=True:

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


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

        self.assertEqual(response.status_code, 200)

        self.assertEqual(len(callbacks), 1)

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, "Contact Form")
        self.assertEqual(mail.outbox[0].body, "I like your site")

TestCaseMixin

A mixin class to be added to your custom TestCase subclass. It adds one method, captureOnCommitCallbacks() that aliases capture_on_commit_callbacks(), to match the camelCase style of unittest assertions.

You can add to your custom TestCase classes like so:

from django import test
from django_capture_on_commit_callbacks import TestCaseMixin


class TestCase(TestCaseMixin, test.TestCase):
    pass

You could then rewrite the above tests with your custom TestCase class like so:

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


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

        self.assertEqual(response.status_code, 200)

        self.assertEqual(len(callbacks), 1)

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, "Contact Form")
        self.assertEqual(mail.outbox[0].body, "I like your site")

Release files for django-capture-on-commit-callbacks 1.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-capture-on-commit-callbacks 1.11.0
File Size Uploaded
django-capture-on-commit-callbacks-1.11.0.tar.gz 6.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-capture-on-commit-callbacks 1.11.0
File Interpreter ABI Platform
django_capture_on_commit_callbacks-1.11.0-py3-none-any.whl Python 3 none any Details

Total release size:12.0 kB

Release files / django-capture-on-commit-callbacks-1.11.0.tar.gz

Download URL django-capture-on-commit-callbacks-1.11.0.tar.gz
Size 6.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ee5a79dc74937a0318c192b54d904ce0826ced47748d160bf15324fc77e98c41
BLAKE2b-256 checksum
How to use checksums
64b4b6cd102b08e82b8020896619cbf0df2ade14b17edb7e4a0c5188f2da0a60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.10.4

Release files / django_capture_on_commit_callbacks-1.11.0-py3-none-any.whl

Download URL django_capture_on_commit_callbacks-1.11.0-py3-none-any.whl
Size 5.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a75300586390411a7e4641128c4251fdc5db25b6e76543329d82fb2c2bc71163
BLAKE2b-256 checksum
How to use checksums
f08b2f7e3971b7138e6efea1e4792eb8fd2a2391106e8dcaa2bf57561daa51eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.10.4
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page