pytest-django allows you to test your Django project/applications with the pytest testing tool.

Overview
PyPI Version Supported Python versions Build Status Coverage

Welcome to pytest-django!

pytest-django allows you to test your Django project/applications with the pytest testing tool.

Install pytest-django

pip install pytest-django

Why would I use this instead of Django's manage.py test command?

Running your test suite with pytest-django allows you to tap into the features that are already present in pytest. Here are some advantages:

  • Manage test dependencies with pytest fixtures.
  • Less boilerplate tests: no need to import unittest, create a subclass with methods. Write tests as regular functions.
  • Database re-use: no need to re-create the test database for every test run.
  • Run tests in multiple processes for increased speed (with the pytest-xdist plugin).
  • Make use of other pytest plugins.
  • Works with both worlds: Existing unittest-style TestCase's still work without any modifications.

See the pytest documentation for more information on pytest itself.

Comments
  • Create --querycount parameter

    Create --querycount parameter

    It displays a list of top N tests with most queries.

    I was inspired by the --duration parameter of pytest and tried to make work as similar as a could.

    Note that I used the report sections to store the executed queries. Even though I'm not sure it is the best way to do that, it had a nice side effect: The executed queries are displayed when a test fails.

    TODO:

    • [ ] capture all connections; if there are multiple this should be reported separately (but for the single nodeid, similar to setup/call/teardown (see 4. below))
    • [ ] revisit tests to check if it is using the test DB always really
    • [x] counts appear to be wrong: I get the same with "teardown" as with "call" always (fixed in diff/patch)
    • [ ] combine counts per nodeid, but only list counts for setup, call, and teardown in parentheses with it.
    • [ ] currently you will get the captured queries in case of failures (and -s I assume?). There could also be a django_db_log_queries mark and fixture (context manager) that would do the same, but then could be used on a single test for debugging. This should get refactored to provide this easily.
    • [ ] rebase on master for and refactor with _assert_num_queries

    IDEAS:

    • [ ] default to 10 for --querycount, i.e. do not require an argument?
    enhancement 
    opened by renanivo 58
  • Plugin stops testing non-django projects

    Plugin stops testing non-django projects

    Hi

    When the plugin is installed testing a non-django project without having DJANGO_SETTINGS_MODULE results in an error. The reason (AFAIK) is that pytest_django.plugin, which is registered as the pytest11 entrypoint via "from .plugin import *" in pytest_django.init, does a direct "from django.conf import settings".

    I'm not immediately sure how the plugin can detect it is testing a django application in order to decide to activate itself or not. But I think it would be beneficial to not have pytest-django break normal test runs by default.

    Regards, Floris

    opened by flub 36
  • Add initial approach to put Django's asserts into pytest's namespace. Issue #97 (was: Pull Request #144)

    Add initial approach to put Django's asserts into pytest's namespace. Issue #97 (was: Pull Request #144)

    I've only addressed the straight-forward things from the code review feedback in PR #144 for now.

    Original issue: https://github.com/pytest-dev/pytest-django/issues/97

    enhancement 
    opened by bittner 33
  • Adds tests for invalid template variables

    Adds tests for invalid template variables

    Django catches all VariableDoesNotExist exceptions to replace them in templates with a modifiable string that you can define in your settings. Sadly that doesn't allow you to find them in unit tests.

    _fail_for_invalid_template_variable sets the setting TEMPLATE_STRING_IF_INVALID to a custom class that not only fails the current test but prints a pretty message including the template name.

    A new marker allows disabling this behavior, eg:

    @pytest.mark.ignore_template_errors
    def test_something():
        pass
    

    This marker sets the setting to None, if you want it to be a string, you can use the settings fixture to set it to your desired value.

    enhancement 
    opened by codingjoe 31
  • conftest.py presence changes sys.path and settings import

    conftest.py presence changes sys.path and settings import

    running py.test with DJANGO_SETTINGS_MODULE=myproject.settings py.test fails if there is no conftest.py file in root folder with ERROR: Could not import settings 'myproject.settings' (Is it on sys.path?): No module named myproject.settings

    opened by krya 26
  • pytest 5.4 skips Django's teardown (causing e.g.

    pytest 5.4 skips Django's teardown (causing e.g. "connection already closed" errors)

    pytest-django==3.5.1 django versions tested: 2.2.11 and 3.0.4

    When one test fails, all tests which use database launched after this test will fail with traceback:

    test/apiv2/put_inputevent__test.py:34: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/model_mommy/mommy.py:54: in make
        return mommy.make(_save_kwargs=_save_kwargs, **attrs)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/model_mommy/mommy.py:228: in make
        return self._make(commit=True, commit_related=True, _save_kwargs=_save_kwargs, **attrs)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/model_mommy/mommy.py:265: in _make
        instance = self.instance(self.model_attrs, _commit=commit, _save_kwargs=_save_kwargs)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/model_mommy/mommy.py:289: in instance
        instance.save(**_save_kwargs)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/base.py:741: in save
        force_update=force_update, update_fields=update_fields)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/base.py:779: in save_base
        force_update, using, update_fields,
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/base.py:851: in _save_table
        forced_update)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/base.py:900: in _do_update
        return filtered._update(values) > 0
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/query.py:760: in _update
        return query.get_compiler(self.db).execute_sql(CURSOR)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1469: in execute_sql
        cursor = super().execute_sql(result_type)
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1138: in execute_sql
        cursor = self.connection.cursor()
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/backends/base/base.py:256: in cursor
        return self._cursor()
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/backends/base/base.py:235: in _cursor
        return self._prepare_cursor(self.create_cursor(name))
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/utils.py:89: in __exit__
        raise dj_exc_value.with_traceback(traceback) from exc_value
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/backends/base/base.py:235: in _cursor
        return self._prepare_cursor(self.create_cursor(name))
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fe8150ed208>, name = None
    
        def create_cursor(self, name=None):
            if name:
                # In autocommit mode, the cursor will be used outside of a
                # transaction, hence use a holdable cursor.
                cursor = self.connection.cursor(name, scrollable=False, withhold=self.connection.autocommit)
            else:
    >           cursor = self.connection.cursor()
    E           django.db.utils.InterfaceError: connection already closed
    
    /home/u1/.virtualenvs/npserver/lib/python3.7/site-packages/django/db/backends/postgresql/base.py:223: InterfaceError
    
    

    Downgrading to pytest==5.3.5 fixes the issue.

    Not yet sure if this is pytest issue or pytest-django.

    bug 
    opened by Fak3 25
  • Fixed #136 - fix the settings fixture for certain settings.

    Fixed #136 - fix the settings fixture for certain settings.

    When changing/deleting a setting, the django.test.signals.setting_changed fixture will be sent, just like Django's override_settings decorator.

    Refs #93, #46.

    more and more apps are using this signal to clean their caches, so more and more settings can't be changed with this fixture

    opened by syphar 25
  • Tests using live_server fixture removing data from data migrations

    Tests using live_server fixture removing data from data migrations

    I've created a simple test case to reproduce this behavior https://github.com/ekiro/case_pytest/blob/master/app/tests.py which fails after second test using live_server fixture. MyModel objects are created in migration, using RunPython. It seems like after any test with live_server, every row from the database is truncated. Both, postgresql and sqlite3 was tested.

    EDIT: Tests

    """
    MyModel objects are created in migration
    Test results:
        app/tests.py::test_no_live_server PASSED
        app/tests.py::test_live_server PASSED
        app/tests.py::test_live_server2 FAILED
        app/tests.py::test_no_live_server_after_live_server FAILED
    """
    
    import pytest
    
    from .models import MyModel
    
    
    @pytest.mark.django_db()
    def test_no_live_server():
        """Passed"""
        assert MyModel.objects.count() == 10
    
    
    @pytest.mark.django_db()
    def test_live_server(live_server):
        """Passed"""
        assert MyModel.objects.count() == 10
    
    
    @pytest.mark.django_db()
    def test_live_server2(live_server):
        """Failed, because count() returns 0"""
        assert MyModel.objects.count() == 10
    
    
    @pytest.mark.django_db()
    def test_no_live_server_after_live_server():
        """Failed, because count() returns 0"""
        assert MyModel.objects.count() == 10
    
    opened by ekiro 23
  • New release?

    New release?

    Do the maintainers have plans to cut the next release? A few projects at my job depend on some of the new features such as django_assert_num_queries.

    If there are any blockers to release, I'd be glad to help out.

    opened by sloria 22
  • Should automatically call django.setup() on django 1.7

    Should automatically call django.setup() on django 1.7

    For now I have this in my conftest.py:

    try:
        from django import setup
    except ImportError:
        pass
    else:
        def pytest_configure():
            setup()
    

    Without it I have these mind-boggling errors (on django 1.7b4):

    Traceback (most recent call last):
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/core/handlers/base.py", line 111, in get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/contrib/admin/sites.py", line 225, in wrapper
        return self.admin_view(view, cacheable)(*args, **kwargs)
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/utils/decorators.py", line 105, in _wrapped_view
        response = view_func(request, *args, **kwargs)
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
        response = view_func(request, *args, **kwargs)
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/contrib/admin/sites.py", line 204, in inner
        return view(request, *args, **kwargs)
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
        response = view_func(request, *args, **kwargs)
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/contrib/admin/sites.py", line 401, in index
        'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name),
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/core/urlresolvers.py", line 542, in reverse
        return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
      File "/home/ionel/osp/django-admin-utils/.tox/3.4-1.7/lib/python3.4/site-packages/django/core/urlresolvers.py", line 459, in _reverse_with_prefix
        (lookup_view_s, args, kwargs, len(patterns), patterns))
    django.core.urlresolvers.NoReverseMatch: Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': 'auth'}' not found. 1 pattern(s) tried: ['admin/(?P<app_label>test_app)/$']
    
    bug 
    opened by ionelmc 22
  • INTERNALERROR> Failed: Database access not allowed

    INTERNALERROR> Failed: Database access not allowed

    I have been facing this issue:

    INTERNALERROR> Traceback (most recent call last):
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/main.py", line 203, in wrap_session
    INTERNALERROR>     session.exitstatus = doit(config, session) or 0
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/main.py", line 243, in _main
    INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/hooks.py", line 289, in __call__
    INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 68, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 62, in <lambda>
    INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 208, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 80, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 187, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/main.py", line 264, in pytest_runtestloop
    INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/hooks.py", line 289, in __call__
    INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 68, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 62, in <lambda>
    INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 208, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 80, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 187, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/runner.py", line 78, in pytest_runtest_protocol
    INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/runner.py", line 87, in runtestprotocol
    INTERNALERROR>     rep = call_and_report(item, "setup", log)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/runner.py", line 175, in call_and_report
    INTERNALERROR>     report = hook.pytest_runtest_makereport(item=item, call=call)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/hooks.py", line 289, in __call__
    INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 68, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 62, in <lambda>
    INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 203, in _multicall
    INTERNALERROR>     gen.send(outcome)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/skipping.py", line 127, in pytest_runtest_makereport
    INTERNALERROR>     rep = outcome.get_result()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 80, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 187, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/runner.py", line 271, in pytest_runtest_makereport
    INTERNALERROR>     excinfo, style=item.config.option.tbstyle
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/nodes.py", line 284, in _repr_failure_py
    INTERNALERROR>     truncate_locals=truncate_locals,
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_code/code.py", line 556, in getrepr
    INTERNALERROR>     return fmt.repr_excinfo(self)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_code/code.py", line 806, in repr_excinfo
    INTERNALERROR>     reprtraceback = self.repr_traceback(excinfo)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_code/code.py", line 751, in repr_traceback
    INTERNALERROR>     reprentry = self.repr_traceback_entry(entry, einfo)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_code/code.py", line 710, in repr_traceback_entry
    INTERNALERROR>     reprargs = self.repr_args(entry) if not short else None
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_code/code.py", line 628, in repr_args
    INTERNALERROR>     args.append((argname, self._saferepr(argvalue)))
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_code/code.py", line 622, in _saferepr
    INTERNALERROR>     return saferepr(obj)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_io/saferepr.py", line 72, in saferepr
    INTERNALERROR>     return srepr.repr(obj)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_io/saferepr.py", line 12, in repr
    INTERNALERROR>     return self._callhelper(reprlib.Repr.repr, self, x)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_io/saferepr.py", line 38, in _callhelper
    INTERNALERROR>     s = call(x, *args)
    INTERNALERROR>   File "/usr/local/lib/python3.6/reprlib.py", line 55, in repr
    INTERNALERROR>     return self.repr1(x, self.maxlevel)
    INTERNALERROR>   File "/usr/local/lib/python3.6/reprlib.py", line 65, in repr1
    INTERNALERROR>     return self.repr_instance(x, level)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_io/saferepr.py", line 33, in repr_instance
    INTERNALERROR>     return self._callhelper(repr, x)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/_io/saferepr.py", line 38, in _callhelper
    INTERNALERROR>     s = call(x, *args)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 244, in __repr__
    INTERNALERROR>     data = list(self[:REPR_OUTPUT_SIZE + 1])
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 268, in __iter__
    INTERNALERROR>     self._fetch_all()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 1186, in _fetch_all
    INTERNALERROR>     self._result_cache = list(self._iterable_class(self))
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 54, in __iter__
    INTERNALERROR>     results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1063, in execute_sql
    INTERNALERROR>     cursor = self.connection.cursor()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/backends/base/base.py", line 255, in cursor
    INTERNALERROR>     return self._cursor()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/django/db/backends/base/base.py", line 232, in _cursor
    INTERNALERROR>     self.ensure_connection()
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/pytest_django/plugin.py", line 749, in _blocking_wrapper
    INTERNALERROR>     "Database access not allowed, "
    INTERNALERROR>   File "/usr/local/lib/python3.6/site-packages/_pytest/outcomes.py", line 113, in fail
    INTERNALERROR>     raise Failed(msg=msg, pytrace=pytrace)
    INTERNALERROR> Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
    

    It happens when I have a FK in a model with a default value set via a function that looks like this:

    def default_value():
        return ModelA.objects.get(name='foo').pk
    

    It happened when I used the django_db mark, even if it was on an empty test and even if this was the only test:

    @pytest.mark.django_db
    def test_this():
        pass
    

    If I comment the decorator, it wouldn't happen.

    I feel the error has to do with the migrations.

    Thank you!

    PS: Edited to remove information that became irrelevant (see my comment below)

    bug 
    opened by cmermingas 21
  • Add `pattern` argument to django_assert_num_queries fixture

    Add `pattern` argument to django_assert_num_queries fixture

    This optional argument allows to filter the queries to take into account for the assertion.

    It may be useful to check for the count of only certain queries. For example, a use case of mine is to skip SAVEPOINT queries by using:

    NO_SAVEPOINT_PATTERN=r'(?!^(ROLLBACK TO |RELEASE )?SAVEPOINT [`"].+[`"]$)'
    ...
    with django_assert_num_queries(n, pattern=NO_SAVEPOINT_PATTERN):
       ...
    
    opened by qarlosh 0
  • How to test stripe webhook using pytest-django

    How to test stripe webhook using pytest-django

    I have a docker-compose based development environment with

    services:
        django:
        postgres:
        stripe:
            command: listen --forward-to http://django:8000/stripe/webhook
    

    When the user uses stripe to make a payment, an event is forwarded by stripe to a webhook http://django:800/stripe/webhook, handled by the django instance.

    When I use pytest to test the service, the following happens (as far as I understand):

    1. django is still running with access to the regular database
    2. A live_server with --ds=config.settings.test is created with access to the test database
    3. When a payment is made during testing, stripe still forwards the request to django, which accesses the regular database, NOT the test database that is hooked to live_server, and the test payment would fail.

    To fix this problem, we may

    1. Fix stripe: Somehow configure stripe to --forward-to live_server.url/stripe/webhoo. This is what is supposed to happen but requires a different stripe cli instance to be created after live_server.url is determined.
    2. Keep --forward-to to the regular django instance, but django (NOT live_server) will access the test database to complete the test. This may be easier but I am not sure how to configure django to access the test database.

    Does anyone have any suggestions on how to do this properly?

    Edit: A third option maybe running the tests on django directly without firing up a live_server, and using the normal database. The trouble is then how to direct pytest-django to NOT use the test database.

    opened by BoPeng 1
  • Idea: Add support to specify db suffix from command line

    Idea: Add support to specify db suffix from command line

    I am working on a big project which has a lot of migrations and I am bouncing from one branch to another where there will be differences between migrations (eg develop vs master). So sometimes I cannot reuse the existing test database when I checkout a different branch.

    So my thought was to add a specific db suffix that can be used to specify different test db (based on my branch). The following code did the trick:

    from pytest_django.fixtures import _set_suffix_to_test_databases
    from pytest_django.lazy_django import skip_if_no_django
    
     def pytest_addoption(parser) -> None:
        """pytest django plugin enhancements.
        Adds pytest command line argument to specify test database suffix.
        """
        group = parser.getgroup("django")
        group.addoption(
            "--db-suffix",
            action="store",
            dest="db_suffix",
            default=None,
            help="Use specific test database suffix.",
        )
    
    
    @pytest.fixture(scope="session")
    def django_db_suffix(request) -> str:
        return request.config.getvalue("db_suffix")
    
    
    @pytest.fixture(scope="session", autouse=True)
    def django_db_modify_db_settings_config_suffix(django_db_suffix) -> None:
        skip_if_no_django()
    
        if django_db_suffix:
            _set_suffix_to_test_databases(suffix=django_db_suffix)
    

    I was wondering if this can be added to that library and help others.

    opened by gmuj 0
  • Idea: Ability to capture queries but not fail the test

    Idea: Ability to capture queries but not fail the test

    Let's say we've got a following test:

    # models.py
    from django.db import models
    
    
    class Post(models.Model):
        title = models.CharField(max_length=255)
    
    
    class PostHistory(models.Model):
        post = models.ForeignKey(Post, on_delete=models.CASCADE)
    
    
    def create_post(title):
        post = Post.objects.create(title=title)
        PostHistory.objects.create(post=post)
    
    
    # test_models.py
    def test_saving_element_works(django_assert_num_queries):
        with django_assert_num_queries(2):
            create_post("foo")
    
        post = Post.objects.first()
        assert post
        assert post.title == 'foo'
        assert PostHistory.objects.filter(post=post).count() == 1
    

    This test would pass of course just fine.

    Let's say For some reason I remove the line PostHistory.objects.create(post=post).

    Now the test fails with the number of queries being incorrect (1 instead of 2). But in order to debug this using the following test, I'd have to either comment out the num_queries assertion, or have a separate test for just testing the query count, but that's a solution we don't really want, as there'll always be a test case that tests the logic, but doesn't really check if the queries match (you could have n-queries inside if-statement for example).

    As a potential solution for this I was thinking of having a way to not fail the test (only for development), but rather only display the message as a warning.

    I think ideally, we could add a CLI flag in the lines of --no-fail-on-django-query-count or something similar.

    I'm happy to work on this, just wanted to see if there's any interest in adding something like that, or if there's a better solution to this issue.

    opened by MichalPodeszwa 1
  • Move thread activation to start method

    Move thread activation to start method

    This moves activation of LiveServer.thread to a method. My primary motivation here is to delay thread activation so I can change the parameters of the thread in an overriden live_server fixture. This provides a work-around to issue #294 using the following override:

    import os
    
    import pytest
    from django.test.testcases import _StaticFilesHandler
    from pytest_django import live_server_helper
    from pytest_django.lazy_django import skip_if_no_django
    
    
    @pytest.fixture(scope="session")
    def live_server(request):
        skip_if_no_django()
    
        addr = (
            request.config.getvalue("liveserver")
            or os.getenv("DJANGO_LIVE_TEST_SERVER_ADDRESS")
            or "localhost"
        )
    
        server = live_server_helper.LiveServer(addr)
        server.thread.static_handler = _StaticFilesHandler  # Force _StaticFilesHandler
        server.start()
        request.addfinalizer(server.stop)
    
        return server
    
    opened by samamorgan 6
Releases(v4.5.2)
  • v4.5.2(Dec 7, 2021)

  • v4.5.1(Dec 2, 2021)

  • v4.5.0(Dec 1, 2021)

  • v4.3.0(May 19, 2021)

  • v4.1.0(Oct 22, 2020)

  • v4.0.0(Oct 16, 2020)

  • v3.8.0(Feb 6, 2020)

  • v3.5.0(Jun 3, 2019)

    Features ^^^^^^^^

    • Run tests in the same order as Django (#223)

    • Use verbosity=0 with disabled migrations (#729, #730)

    Bugfixes ^^^^^^^^

    • django_db_setup: warn instead of crash with teardown errors (#726)

    Misc ^^^^

    • tests: fix test_sqlite_database_renamed (#739, #741)

    • tests/conftest.py: move import of db_helpers (#737)

    • Cleanup/improve coverage, mainly with tests (#706)

    • Slightly revisit unittest handling (#740)

    Source code(tar.gz)
    Source code(zip)
  • 3.4.4(Nov 13, 2018)

    3.4.4 (2018-11-13)

    Bugfixes ^^^^^^^^

    • Refine the django.conf module check to see if the settings really are configured (#668).
    • Avoid crash after OSError during Django path detection (#664).

    Features ^^^^^^^^

    • Add parameter info to fixture assert_num_queries to display additional message on failure (#663).

    Docs ^^^^

    • Improve doc for django_assert_num_queries/django_assert_max_num_queries.
    • Add warning about sqlite specific snippet + fix typos (#666).

    Misc ^^^^

    • MANIFEST.in: include tests for downstream distros (#653).
    • Ensure that the LICENSE file is included in wheels (#665).
    • Run black on source.
    Source code(tar.gz)
    Source code(zip)
  • 3.4.2(Aug 20, 2018)

    3.4.2 (2018-08-20)

    Bugfixes ^^^^^^^^

    • Changed dependency for pathlib to pathlib2 (#636).
    • Fixed code for inserting the project to sys.path with pathlib to use an absolute path, regression in 3.4.0 (#637, #638).
    Source code(tar.gz)
    Source code(zip)
  • 3.4.0(Aug 16, 2018)

    3.4.0 (2018-08-16)

    Features ^^^^^^^^

    • Added new fixture :fixture:django_assert_max_num_queries (#547).
    • Added support for connection and returning the wrapped context manager with :fixture:django_assert_num_queries (#547).
    • Added support for resetting sequences via :fixture:django_db_reset_sequences (#619).

    Bugfixes ^^^^^^^^

    • Made sure to not call django.setup() multiple times (#629, #531).

    Compatibility ^^^^^^^^^^^^^

    • Removed py dependency, use pathlib instead (#631).
    Source code(tar.gz)
    Source code(zip)
  • 3.3.1(Jun 21, 2018)

    3.3.1 (2018-06-21)

    Bug fixes ^^^^^^^^^

    • Fixed test for classmethod with Django TestCases again (#618, introduced in #598 (3.3.0)).

    Compatibility ^^^^^^^^^^^^^

    • Support Django 2.1 (no changes necessary) (#614).
    Source code(tar.gz)
    Source code(zip)
  • 3.3.0(Jun 15, 2018)

    Features ^^^^^^^^

    • Added new fixtures django_mail_dnsname and django_mail_patch_dns, used by mailoutbox to monkeypatch the DNS_NAME used in :py:mod:django.core.mail to improve performance and reproducibility.

    Bug fixes ^^^^^^^^^

    • Fixed test for classmethod with Django TestCases (#597, #598).
    • Fixed RemovedInPytest4Warning: MarkInfo objects are deprecated (#596, #603)
    • Fixed scope of overridden settings with live_server fixture: previously they were visible to following tests (#612).
    Source code(tar.gz)
    Source code(zip)
  • 3.2.0(Apr 14, 2018)

    3.2.0

    Features ^^^^^^^^

    • Added new fixture django_assert_num_queries for testing the number of database queries (#387).
    • --fail-on-template-vars has been improved and should now return full/absolute path (#470).
    • Support for setting the live server port (#500).
    • unittest: help with setUpClass not being a classmethod (#544).

    Bug fixes ^^^^^^^^^

    • Fix --reuse-db and --create-db not working together (#411).
    • Numerous fixes in the documentation. These should not go unnoticed 🌟

    Compatibility ^^^^^^^^^^^^^

    • Support for Django 2.0 has been added.
    • Support for Django before 1.8 has been dropped.
    Source code(tar.gz)
    Source code(zip)
The pytest framework makes it easy to write small tests, yet scales to support complex functional testing

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. An example o

pytest-dev 9.6k Jan 6, 2023
Django project starter on steroids: quickly create a Django app AND generate source code for data models + REST/GraphQL APIs (the generated code is auto-linted and has 100% test coverage).

Create Django App ?? We're a Django project starter on steroids! One-line command to create a Django app with all the dependencies auto-installed AND

imagine.ai 68 Oct 19, 2022
A Django web application that allows you to be in the loop about everything happening in your neighborhood.

A Django web application that allows you to be in the loop about everything happening in your neighborhood. From contact information of different handyman to meeting announcements or even alerts.

Kennedy Ngugi Mwaura 3 Dec 11, 2022
A Django app to initialize Sentry client for your Django applications

Dj_sentry This Django application intialize Sentry SDK to your Django application. How to install You can install this packaging by using: pip install

Gandi 1 Dec 9, 2021
Django-Audiofield is a simple app that allows Audio files upload, management and conversion to different audio format (mp3, wav & ogg), which also makes it easy to play audio files into your Django application.

Django-Audiofield Description: Django Audio Management Tools Maintainer: Areski Contributors: list of contributors Django-Audiofield is a simple app t

Areski Belaid 167 Nov 10, 2022
Django URL Shortener is a Django app to to include URL Shortening feature in your Django Project

Django URL Shortener Django URL Shortener is a Django app to to include URL Shortening feature in your Django Project Install this package to your Dja

Rishav Sinha 4 Nov 18, 2021
Example project demonstrating using Django’s test runner with Coverage.py

Example project demonstrating using Django’s test runner with Coverage.py Set up with: python -m venv --prompt . venv source venv/bin/activate python

Adam Johnson 5 Nov 29, 2021
A test microblog project created using Django 4.0

django-microblog This is a test microblog project created using Django 4.0. But don't worry this is a fully working project. There is no super-amazing

Ali Kasimoglu 8 Jan 14, 2022
An app that allows you to add recipes from the dashboard made using DJango, JQuery, JScript and HTMl.

An app that allows you to add recipes from the dashboard. Then visitors filter based on different categories also each ingredient has a unique page with their related recipes.

Pablo Sagredo 1 Jan 31, 2022
A Django app that allows visitors to interact with your site as a guest user without requiring registration.

django-guest-user A Django app that allows visitors to interact with your site as a guest user without requiring registration. Largely inspired by dja

Julian Wachholz 21 Dec 17, 2022
A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a unique id.

Django-URL-Shortener A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a uni

Rohini Rao 3 Aug 8, 2021
django-idom allows Django to integrate with IDOM

django-idom allows Django to integrate with IDOM, a package inspired by ReactJS for creating responsive web interfaces in pure Python.

null 113 Jan 4, 2023
DCM is a set of tools that helps you to keep your data in your Django Models consistent.

Django Consistency Model DCM is a set of tools that helps you to keep your data in your Django Models consistent. Motivation You have a lot of legacy

Occipital 59 Dec 21, 2022
django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project. Inspired in the dashboard framework Dashing

django-dashing django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project.

talPor Solutions 703 Dec 22, 2022
Stream Framework is a Python library, which allows you to build news feed, activity streams and notification systems using Cassandra and/or Redis. The authors of Stream-Framework also provide a cloud service for feed technology:

Stream Framework Activity Streams & Newsfeeds Stream Framework is a Python library which allows you to build activity streams & newsfeeds using Cassan

Thierry Schellenbach 4.7k Jan 2, 2023
This a Django TODO app project and practiced how to deploy and publish the project to Heroku

ToDo App Demo | Project Table of Contents Overview Built With Features How to use Acknowledgements Contact Overview Built With HTML CSS JS Django How

Cetin OGUT 1 Nov 19, 2021
A reusable Django app that configures your project for deployment

django-simple-deploy This app gives you a management command that configures your project for an initial deployment. It targets Heroku at the moment,

Eric Matthes 205 Dec 26, 2022
wagtail_tenants is a Django/Wagtail app to provide multitenancy to your wagtail project.

wagtail-tenants wagtail_tenants is a Django/Wagtail app to provide multitenancy to your wagtail project. You are able to run a main Wagtail Site and f

<bbr> 11 Nov 20, 2022
A simple demonstration of integrating a sentiment analysis tool in a django project

sentiment-analysis A simple demonstration of integrating a sentiment analysis tool in a django project (watch the video .mp4) To run this project : pi

null 2 Oct 16, 2021