diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 067e33c52..5eecc5c16 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -3,7 +3,6 @@ This plugin handles creating and destroying the test environment and test database and provides some useful text fixtures. """ - import contextlib import inspect from functools import reduce @@ -40,10 +39,96 @@ SETTINGS_MODULE_ENV = 'DJANGO_SETTINGS_MODULE' CONFIGURATION_ENV = 'DJANGO_CONFIGURATION' INVALID_TEMPLATE_VARS_ENV = 'FAIL_INVALID_TEMPLATE_VARS' - +DJANGO_ASSERTS = { + # from https://github.com/django/django/blob/stable/1.3.x/django/test/testcases.py#L244 + (1, 3): ('assertContains', 'assertFormError', 'assertNotContains', + 'assertNumQueries', 'assertQuerysetEqual', 'assertRedirects', + 'assertTemplateNotUsed', 'assertTemplateUsed'), + # from https://github.com/django/django/blob/stable/1.4.x/django/test/testcases.py#L448 + (1, 4): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertHTMLEqual', 'assertHTMLNotEqual', 'assertNotContains', + 'assertNumQueries', 'assertQuerysetEqual', 'assertRaisesMessage', + 'assertRedirects', 'assertTemplateNotUsed', 'assertTemplateUsed'), + # from https://github.com/django/django/blob/stable/1.5.x/django/test/testcases.py#L246 + # and https://github.com/django/django/blob/stable/1.5.x/django/test/testcases.py#L458 + (1, 5): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertHTMLEqual', 'assertHTMLNotEqual', 'assertInHTML', + 'assertJSONEqual', 'assertNotContains', 'assertNumQueries', + 'assertQuerysetEqual', 'assertRaisesMessage', 'assertRedirects', + 'assertTemplateNotUsed', 'assertTemplateUsed', 'assertXMLEqual', + 'assertXMLNotEqual'), + # from https://github.com/django/django/blob/stable/1.6.x/django/test/testcases.py#L156 + # and https://github.com/django/django/blob/stable/1.6.x/django/test/testcases.py#L725 + (1, 6): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertFormsetError', 'assertHTMLEqual', 'assertHTMLNotEqual', + 'assertInHTML', 'assertJSONEqual', 'assertNotContains', + 'assertNumQueries', 'assertQuerysetEqual', 'assertRaisesMessage', + 'assertRedirects', 'assertTemplateNotUsed', 'assertTemplateUsed', + 'assertXMLEqual', 'assertXMLNotEqual'), + # from https://github.com/django/django/blob/stable/1.7.x/django/test/testcases.py#L162 + # and https://github.com/django/django/blob/stable/1.7.x/django/test/testcases.py#L722 + (1, 7): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertFormsetError', 'assertHTMLEqual', 'assertHTMLNotEqual', + 'assertInHTML', 'assertJSONEqual', 'assertNotContains', + 'assertNumQueries', 'assertQuerysetEqual', 'assertRaisesMessage', + 'assertRedirects', 'assertTemplateNotUsed', 'assertTemplateUsed', + 'assertXMLEqual', 'assertXMLNotEqual'), + # from https://github.com/django/django/blob/stable/1.8.x/django/test/testcases.py#L142 + # and https://github.com/django/django/blob/stable/1.8.x/django/test/testcases.py#L751 + (1, 8): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertFormsetError', 'assertHTMLEqual', 'assertHTMLNotEqual', + 'assertInHTML', 'assertJSONEqual', 'assertJSONNotEqual', + 'assertNotContains', 'assertNumQueries', 'assertQuerysetEqual', + 'assertRaisesMessage', 'assertRedirects', 'assertTemplateNotUsed', + 'assertTemplateUsed', 'assertXMLEqual', 'assertXMLNotEqual'), + # from https://github.com/django/django/blob/stable/1.9.x/django/test/testcases.py#L158 + # and https://github.com/django/django/blob/stable/1.9.x/django/test/testcases.py#L818 + (1, 9): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertFormsetError', 'assertHTMLEqual', 'assertHTMLNotEqual', + 'assertInHTML', 'assertJSONEqual', 'assertJSONNotEqual', + 'assertNotContains', 'assertNumQueries', 'assertQuerysetEqual', + 'assertRaisesMessage', 'assertRedirects', 'assertTemplateNotUsed', + 'assertTemplateUsed', 'assertXMLEqual', 'assertXMLNotEqual'), + # from https://github.com/django/django/blob/stable/1.10.x/django/test/testcases.py#L155 + # and https://github.com/django/django/blob/stable/1.10.x/django/test/testcases.py#L797 + (1, 10): ('assertContains', 'assertFieldOutput', 'assertFormError', + 'assertFormsetError', 'assertHTMLEqual', 'assertHTMLNotEqual', + 'assertInHTML', 'assertJSONEqual', 'assertJSONNotEqual', + 'assertNotContains', 'assertNumQueries', 'assertQuerysetEqual', + 'assertRaisesMessage', 'assertRedirects', 'assertTemplateNotUsed', + 'assertTemplateUsed', 'assertXMLEqual', 'assertXMLNotEqual'), +} # ############### pytest hooks ################ +def populate_namespace(): + def _wrapper(name): + + def assertion_func(*args, **kwargs): + from django.test import TestCase as DjangoTestCase + + getattr(DjangoTestCase('run'), name)(*args, **kwargs) + + return assertion_func + + asserts = {} + for name in DJANGO_ASSERTS[get_django_version()[:2]]: + asserts[name] = _wrapper(name) + + return {'django': asserts} + + +def pytest_namespace(): + """Make unittest assert methods available. + Useful for things such as floating point checks with assertAlmostEqual. + """ + try: + django_settings_is_configured() + except AssertionError: + return populate_namespace() + return {} + + def pytest_addoption(parser): group = parser.getgroup('django') group._addoption('--reuse-db', @@ -594,8 +679,7 @@ def _save_active_wrapper(self): return self._history.append(self._dj_db_wrapper.ensure_connection) def _blocking_wrapper(*args, **kwargs): - __tracebackhide__ = True - __tracebackhide__ # Silence pyflakes + __tracebackhide__ = True # noqa pytest.fail('Database access not allowed, ' 'use the "django_db" mark, or the ' '"db" or "transactional_db" fixtures to enable it.') diff --git a/tests/test_namespaces.py b/tests/test_namespaces.py new file mode 100644 index 000000000..9847f929d --- /dev/null +++ b/tests/test_namespaces.py @@ -0,0 +1,44 @@ +# coding: utf-8 +import inspect + +import pytest +import pytest_django + +from pytest_django.lazy_django import get_django_version +from pytest_django.plugin import DJANGO_ASSERTS + + +def _get_actual_assertions_names(): + """ + Returns list with names of all assertion helpers in Django. + """ + from django.test import TestCase as DjangoTestCase + from django.utils.unittest import TestCase as DefaultTestCase + + obj = DjangoTestCase('run') + is_assert = lambda x: x.startswith('assert') and '_' not in x + base_methods = [name for name, member in + inspect.getmembers(DefaultTestCase) + if is_assert(name)] + + return [name for name, member in inspect.getmembers(obj) + if is_assert(name) and name not in base_methods] + + +def test_django_asserts_available(): + django_assertions = _get_actual_assertions_names() + expected_assertions = DJANGO_ASSERTS[get_django_version()[:2]] + assert set(django_assertions) == set(expected_assertions) + + for name in expected_assertions: + assert hasattr(pytest_django, name) + + +def test_sanity(admin_client): + from pytest_django import assertContains + + response = admin_client.get('/admin-required/') + + assertContains(response, 'You are an admin') + with pytest.raises(AssertionError): + assertContains(response, 'Access denied')