A Django plugin for pytest.

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)
A feature flipper for Django

README Django Waffle is (yet another) feature flipper for Django. You can define the conditions for which a flag should be active, and use it in a num

952 Jan 06, 2023
Plugin for generating HTML reports for pytest results

pytest-html pytest-html is a plugin for pytest that generates a HTML report for test results. Resources Documentation Release Notes Issue Tracker Code

pytest-dev 548 Dec 28, 2022
Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes in a variety of languages.

Mimesis - Fake Data Generator Description Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes

Isaak Uchakaev 3.8k Dec 29, 2022
WEB PENETRATION TESTING TOOL 💥

N-WEB ADVANCE WEB PENETRATION TESTING TOOL Features 🎭 Admin Panel Finder Admin Scanner Dork Generator Advance Dork Finder Extract Links No Redirect H

56 Dec 23, 2022
This file will contain a series of Python functions that use the Selenium library to search for elements in a web page while logging everything into a file

element_search with Selenium (Now With docstrings 😎 ) Just to mention, I'm a beginner to all this, so it it's very possible to make some mistakes The

2 Aug 12, 2021
Donors data of Tamil Nadu Chief Ministers Relief Fund scrapped from https://ereceipt.tn.gov.in/cmprf/Interface/CMPRF/MonthWiseReport

Tamil Nadu Chief Minister's Relief Fund Donors Scrapped data from https://ereceipt.tn.gov.in/cmprf/Interface/CMPRF/MonthWiseReport Scrapper scrapper.p

Arunmozhi 5 May 18, 2021
FaceBot is a script to automatically create a facebook account using the selenium and chromedriver modules.

FaceBot is a script to automatically create a facebook account using the selenium and chromedriver modules. That way, we don't need to input full name, email and password and date of birth. All will

Fadjrir Herlambang 2 Jun 17, 2022
Spam the buzzer and upgrade automatically - Selenium

CookieClicker Usage: Let's check your chrome navigator version : Consequently, you have to : download the right chromedriver in the follow link : http

Iliam Amara 1 Nov 22, 2021
Repository for JIDA SNP Browser Web Application: Local Deployment

JIDA JIDA is a web application that retrieves SNP information for a genomic region of interest in Homo sapiens and calculates specific summary statist

3 Mar 03, 2022
Docker-based integration tests

Docker-based integration tests Description Simple pytest fixtures that help you write integration tests with Docker and docker-compose. Specify all ne

Avast 326 Dec 27, 2022
The async ready version of the AniManga library created by centipede000.

Async-Animanga An Async/Aiohttp compatible library. Async-Animanga is an async ready web scraping library that returns Manga information from animepla

3 Sep 22, 2022
Automated testing tool developed in python for Advanced mathematical operations.

Advanced-Maths-Operations-Validations Automated testing tool developed in python for Advanced mathematical operations. Requirements Python 3.5 or late

Nikhil Repale 1 Nov 16, 2021
✅ Python web automation and testing. 🚀 Fast, easy, reliable. 💠

Build fast, reliable, end-to-end tests. SeleniumBase is a Python framework for web automation, end-to-end testing, and more. Tests are run with "pytes

SeleniumBase 3k Jan 04, 2023
nose is nicer testing for python

On some platforms, brp-compress zips man pages without distutils knowing about it. This results in an error when building an rpm for nose. The rpm bui

1.4k Dec 12, 2022
This is a bot that can type without any assistance and have incredible speed.

BulldozerType This is a bot that can type without any assistance and have incredible speed. This bot currently only works on the site https://onlinety

1 Jan 03, 2022
Show surprise when tests are passing

pytest-pikachu pytest-pikachu prints ascii art of Surprised Pikachu when all tests pass. Installation $ pip install pytest-pikachu Usage Pass the --p

Charlie Hornsby 13 Apr 15, 2022
The Social-Engineer Toolkit (SET) repository from TrustedSec - All new versions of SET will be deployed here.

💼 The Social-Engineer Toolkit (SET) 💼 Copyright 2020 The Social-Engineer Toolkit (SET) Written by: David Kennedy (ReL1K) @HackingDave Company: Trust

trustedsec 8.4k Dec 31, 2022
Given some test cases, this program automatically queries the oracle and tests your Cshanty compiler!

The Diviner A complement to The Oracle for compilers class. Given some test cases, this program automatically queries the oracle and tests your compil

Grant Holmes 2 Jan 29, 2022
A automated browsing experience.

browser-automation This app is an automated browsing technique where one has to enter the required information, it's just like searching for Animals o

Ojas Barawal 3 Aug 04, 2021
Subprocesses for Humans 2.0.

Delegator.py — Subprocesses for Humans 2.0 Delegator.py is a simple library for dealing with subprocesses, inspired by both envoy and pexpect (in fact

Amit Tripathi 1.6k Jan 04, 2023