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)
I managed to attach the Django Framework to my Telegram Bot and set a webhook

I managed to attach the Django Framework to my Telegram Bot and set a webhook. I've been developing it from 10th of November 2021 and I want to have a basic working prototype.

Valentyn Vovchak 2 Sep 08, 2022
This is a simple Todo web application built Django (back-end) and React JS (front-end)

Django REST Todo app This is a simple Todo web application built with Django (back-end) and React JS (front-end). The project enables you to systemati

Maxim Mukhin 5 May 06, 2022
Getdp-project - A Django-built web app that generates a personalized banner of events to come

getdp-project https://get-my-dp.herokuapp.com/ A Django-built web app that gener

CODE 4 Aug 01, 2022
Django Girls Tutorial Workshop

Django Girls Tutorial Workshop A log of activities during the workshop. this is an H2 git remote add origin https://github.com/ahuimanu/django_girls_t

Jeffry Babb 1 Oct 27, 2021
Django Rest Framework + React application.

Django Rest Framework + React application.

2 Dec 19, 2022
Quick example of a todo list application using Django and HTMX

django-htmx-todo-list Quick example of a todo list application using Django and HTMX Background Modified & expanded from https://github.com/jaredlockh

Jack Linke 54 Dec 10, 2022
Dashboad Full Stack utilizando o Django.

Dashboard FullStack completa Projeto finalizado | Informações Cadastro de cliente Menu interatico mostrando quantidade de pessoas bloqueadas, liberada

Lucas Silva 1 Dec 15, 2021
Full-featured django project start tool.

django-start-tool Introduction django-start-tool is a full-featured replacement for django-admin startproject which provides cli for creating the same

Georgy Gnezdilov 0 Aug 30, 2022
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
A Minimalistic Modern Django Boilerplate

A Minimalistic Modern Django Boilerplate This boilerplate is mainly for educational purposes. It is meant to be cloned as a starter code for future tu

Jonathan Adly 21 Nov 02, 2022
Source code for Django for Beginners 3.2

The official source code for https://djangoforbeginners.com/. Available as an ebook or in Paperback. If you have the 3.1 version, please refer to this

William Vincent 10 Jan 03, 2023
Utilities for implementing a modified pre-order traversal tree in django.

django-mptt Utilities for implementing Modified Preorder Tree Traversal with your Django Models and working with trees of Model instances. Project hom

2.7k Jan 01, 2023
django-compat-lint

django_compat_lint -- check Django compatibility of your code Django's API stability policy is nice, but there are still things that change from one v

James Bennett 40 Sep 30, 2021
Application made in Django to generate random passwords as based on certain criteria .

PASSWORD GENERATOR Welcome to Password Generator About The App Password Generator is an Open Source project brought to you by Iot Lab,KIIT and it brin

IoT Lab KIIT 3 Oct 21, 2021
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
Django + AWS Elastic Transcoder

Django Elastic Transcoder django-elastic-transcoder is an Django app, let you integrate AWS Elastic Transcoder in Django easily. What is provided in t

StreetVoice 66 Dec 14, 2022
A starter template for building a backend with Django and django-rest-framework using docker with PostgreSQL as the primary DB.

Django-Rest-Template! This is a basic starter template for a backend project with Django as the server and PostgreSQL as the database. About the templ

Akshat Sharma 11 Dec 06, 2022
Django Serverless Cron - Run cron jobs easily in a serverless environment

Django Serverless Cron - Run cron jobs easily in a serverless environment

Paul Onteri 41 Dec 16, 2022
Django React - Purity Dashboard (Open-Source) | AppSeed

Django React Purity Dashboard Start your Development with an Innovative Admin Template for Chakra UI and React. Purity UI Dashboard is built with over

App Generator 19 Sep 19, 2022
Use heroicons in your Django and Jinja templates.

heroicons Use heroicons in your Django and Jinja templates. Requirements Python 3.6 to 3.9 supported. Django 2.2 to 3.2 supported. Are your tests slow

Adam Johnson 52 Dec 14, 2022