[Django]-Django + Pytest + Selenium

2👍

switch from django.test.TestCase in favour of pytest shall mean employing pytest-django plugin and your tests should look like this:


class TestSomething(object):
    def setup_method(self, method):
        pass

    @pytest.mark.django_db
    def test_something_with_dg(self):
       assert True

that above all means no django.test.TestCase (which is a derivation from python std unittest framework) inheritance.

the @pytest.mark.django_db means your test case will run in a transaction which will be rolled back once the test case is over.

first occurrence of the django_db marker will also trigger django migrations.

beware using database calls in special pytest methods such as setup_method for it’s unsupported and otherwise problematic:

django-pytest setup_method database issue

1👍

def _django_db_fixture_helper(transactional, request, _django_cursor_wrapper):
    if is_django_unittest(request):
        return

    if transactional:
        _django_cursor_wrapper.enable()

        def flushdb():
            """Flush the database and close database connections"""
            # Django does this by default *before* each test
            # instead of after.
            from django.db import connections
            from django.core.management import call_command

            for db in connections:
                call_command('flush', verbosity=0,
                             interactive=False, database=db)
            for conn in connections.all():
                conn.close()

        request.addfinalizer(_django_cursor_wrapper.disable)
        request.addfinalizer(flushdb)
    else:
        if 'live_server' in request.funcargnames:
            return
        from django.test import TestCase

        _django_cursor_wrapper.enable()
        _django_cursor_wrapper._is_transactional = False
        case = TestCase(methodName='__init__')
        case._pre_setup()
        request.addfinalizer(_django_cursor_wrapper.disable)
        request.addfinalizer(case._post_teardown)

As i see you use pytest-django (which is fine)
From this code of it, it doesn’t flush the db if it’s non-transactional db.
So in your ‘other’ tests you’d have to use transactional_db and then it will be isolated as you wanted.

So your code will look like:

class TestCase:
    def test_some_unittest(transactional_db):
        # Create some items
        #...

    def test_with_selenium(browser):
        # The items from the above testcase does not exist in this testcase

Hovewer, an improvement to pytest-django could be that flush is performed before, not after yield of the fixture value, which makes much more sense. It’s not so important what’s in teardown, it’s important that set up is correct.
As a side suggestion, for browser fixture you can just use pytest-splinter plugin

Leave a comment