Skip to content

Commit 508c941

Browse files
beyondgeeksblueyed
beyondgeeks
andcommitted
Make Django's assertion helpers available in pytest_django.asserts (#709)
Fixes pytest-dev/pytest-django#97. Co-authored-by: Daniel Hahler <[email protected]>
1 parent 8ba7299 commit 508c941

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

docs/helpers.rst

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
Django helpers
44
==============
55

6+
Assertions
7+
----------
8+
9+
All of Django's :py:class:`~django:django.test.TestCase`
10+
:ref:`django:assertions` are available in ``pytest_django.asserts``, e.g.
11+
12+
::
13+
14+
from pytest_django.asserts import assertTemplateUsed
15+
616
Markers
717
-------
818

pytest_django/asserts.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""
2+
Dynamically load all Django assertion cases and expose them for importing.
3+
"""
4+
from functools import wraps
5+
from django.test import (
6+
TestCase, SimpleTestCase,
7+
LiveServerTestCase, TransactionTestCase
8+
)
9+
10+
test_case = TestCase('run')
11+
12+
13+
def _wrapper(name):
14+
func = getattr(test_case, name)
15+
16+
@wraps(func)
17+
def assertion_func(*args, **kwargs):
18+
return func(*args, **kwargs)
19+
20+
return assertion_func
21+
22+
23+
__all__ = []
24+
assertions_names = set()
25+
assertions_names.update(
26+
set(attr for attr in vars(TestCase) if attr.startswith('assert')),
27+
set(attr for attr in vars(SimpleTestCase) if attr.startswith('assert')),
28+
set(attr for attr in vars(LiveServerTestCase) if attr.startswith('assert')),
29+
set(attr for attr in vars(TransactionTestCase) if attr.startswith('assert')),
30+
)
31+
32+
for assert_func in assertions_names:
33+
globals()[assert_func] = _wrapper(assert_func)
34+
__all__.append(assert_func)

tests/test_asserts.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
Tests the dynamic loading of all Django assertion cases.
3+
"""
4+
import inspect
5+
6+
import pytest
7+
import pytest_django
8+
9+
from pytest_django.asserts import __all__ as asserts_all
10+
11+
12+
def _get_actual_assertions_names():
13+
"""
14+
Returns list with names of all assertion helpers in Django.
15+
"""
16+
from django.test import TestCase as DjangoTestCase
17+
from unittest import TestCase as DefaultTestCase
18+
19+
obj = DjangoTestCase('run')
20+
21+
def is_assert(func):
22+
return func.startswith('assert') and '_' not in func
23+
24+
base_methods = [name for name, member in
25+
inspect.getmembers(DefaultTestCase)
26+
if is_assert(name)]
27+
28+
return [name for name, member in inspect.getmembers(obj)
29+
if is_assert(name) and name not in base_methods]
30+
31+
32+
def test_django_asserts_available():
33+
django_assertions = _get_actual_assertions_names()
34+
expected_assertions = asserts_all
35+
assert set(django_assertions) == set(expected_assertions)
36+
37+
for name in expected_assertions:
38+
assert hasattr(pytest_django.asserts, name)
39+
40+
41+
@pytest.mark.django_db
42+
def test_sanity():
43+
from django.http import HttpResponse
44+
from pytest_django.asserts import assertContains, assertNumQueries
45+
46+
response = HttpResponse('My response')
47+
48+
assertContains(response, 'My response')
49+
with pytest.raises(AssertionError):
50+
assertContains(response, 'Not my response')
51+
52+
assertNumQueries(0, lambda: 1 + 1)
53+
with assertNumQueries(0):
54+
pass
55+
56+
assert assertContains.__doc__

0 commit comments

Comments
 (0)